diff --git a/.changeset/thick-lizards-yell.md b/.changeset/thick-lizards-yell.md new file mode 100644 index 0000000000..e42260073c --- /dev/null +++ b/.changeset/thick-lizards-yell.md @@ -0,0 +1,5 @@ +--- +"hardhat": patch +--- + +Added an optional `--output` param to the flatten task diff --git a/packages/hardhat-core/src/builtin-tasks/flatten.ts b/packages/hardhat-core/src/builtin-tasks/flatten.ts index 28e6a65c88..61c72924c7 100644 --- a/packages/hardhat-core/src/builtin-tasks/flatten.ts +++ b/packages/hardhat-core/src/builtin-tasks/flatten.ts @@ -1,4 +1,5 @@ import picocolors from "picocolors"; +import { writeFileSync } from "node:fs"; import { subtask, task, types } from "../internal/core/config/config-env"; import { HardhatError } from "../internal/core/errors"; import { ERRORS } from "../internal/core/errors-list"; @@ -303,46 +304,63 @@ task( undefined, types.inputFile ) - .setAction(async ({ files }: { files: string[] | undefined }, { run }) => { - const [flattenedFile, metadata]: [string, FlattenMetadata | null] = - await run(TASK_FLATTEN_GET_FLATTENED_SOURCE_AND_METADATA, { files }); - - console.log(flattenedFile); - - if (metadata === null) return; - - if (metadata.filesWithoutLicenses.length > 0) { - console.warn( - picocolors.yellow( - `\nThe following file(s) do NOT specify SPDX licenses: ${metadata.filesWithoutLicenses.join( - ", " - )}` - ) - ); - } + .addOptionalParam( + "output", + "The output file containing the flattened contracts", + undefined, + types.string + ) + .setAction( + async ( + { + files, + output, + }: { files: string[] | undefined; output: string | undefined }, + { run } + ) => { + const [flattenedFile, metadata]: [string, FlattenMetadata | null] = + await run(TASK_FLATTEN_GET_FLATTENED_SOURCE_AND_METADATA, { files }); + + if (output !== undefined) { + writeFileSync(output, flattenedFile, { encoding: "utf-8" }); + } else { + console.log(flattenedFile); + } + if (metadata === null) return; + + if (metadata.filesWithoutLicenses.length > 0) { + console.warn( + picocolors.yellow( + `\nThe following file(s) do NOT specify SPDX licenses: ${metadata.filesWithoutLicenses.join( + ", " + )}` + ) + ); + } - if ( - metadata.pragmaDirective !== "" && - metadata.filesWithoutPragmaDirectives.length > 0 - ) { - console.warn( - picocolors.yellow( - `\nPragma abicoder directives are defined in some files, but they are not defined in the following ones: ${metadata.filesWithoutPragmaDirectives.join( - ", " - )}` - ) - ); - } + if ( + metadata.pragmaDirective !== "" && + metadata.filesWithoutPragmaDirectives.length > 0 + ) { + console.warn( + picocolors.yellow( + `\nPragma abicoder directives are defined in some files, but they are not defined in the following ones: ${metadata.filesWithoutPragmaDirectives.join( + ", " + )}` + ) + ); + } - if (metadata.filesWithDifferentPragmaDirectives.length > 0) { - console.warn( - picocolors.yellow( - `\nThe flattened file is using the pragma abicoder directive '${ - metadata.pragmaDirective - }' but these files have a different pragma abicoder directive: ${metadata.filesWithDifferentPragmaDirectives.join( - ", " - )}` - ) - ); + if (metadata.filesWithDifferentPragmaDirectives.length > 0) { + console.warn( + picocolors.yellow( + `\nThe flattened file is using the pragma abicoder directive '${ + metadata.pragmaDirective + }' but these files have a different pragma abicoder directive: ${metadata.filesWithDifferentPragmaDirectives.join( + ", " + )}` + ) + ); + } } - }); + ); diff --git a/packages/hardhat-core/test/builtin-tasks/flatten.ts b/packages/hardhat-core/test/builtin-tasks/flatten.ts index 64844b5645..6249b3cf1c 100644 --- a/packages/hardhat-core/test/builtin-tasks/flatten.ts +++ b/packages/hardhat-core/test/builtin-tasks/flatten.ts @@ -1,8 +1,10 @@ import { assert } from "chai"; -import fs from "fs"; +import fs, { readFileSync } from "fs"; import sinon, { SinonSpy } from "sinon"; import picocolors from "picocolors"; +import { removeSync } from "fs-extra"; +import { tmpdir } from "os"; import { TASK_FLATTEN, TASK_FLATTEN_GET_FLATTENED_SOURCE, @@ -412,6 +414,21 @@ describe("Flatten task", () => { assert(!spyFunctionConsoleWarn.called); }); + it("should write to an output file when the parameter output is specified", async function () { + const outputFile = `${tmpdir()}/flatten.sol`; + try { + await this.env.run(TASK_FLATTEN, { + files: ["contracts/A.sol", "contracts/D.sol"], + output: outputFile, + }); + const expected = await getExpectedSol(); + const actual = readFileSync(outputFile, "utf8"); + assert.equal(actual, expected); + } finally { + removeSync(outputFile); + } + }); + describe("No contracts to flatten", () => { useFixtureProject("flatten-task/no-contracts");