diff --git a/.changeset/slow-stingrays-eat.md b/.changeset/slow-stingrays-eat.md new file mode 100644 index 000000000..76127079c --- /dev/null +++ b/.changeset/slow-stingrays-eat.md @@ -0,0 +1,5 @@ +--- +"create-eth": patch +--- + +templates: optional YourContract.sol in extensions diff --git a/src/tasks/copy-template-files.ts b/src/tasks/copy-template-files.ts index c00f43bd1..8575ed670 100644 --- a/src/tasks/copy-template-files.ts +++ b/src/tasks/copy-template-files.ts @@ -9,7 +9,7 @@ import path from "path"; import { promisify } from "util"; import link from "../utils/link"; import { getArgumentFromExternalExtensionOption } from "../utils/external-extensions"; -import { BASE_DIR, SOLIDITY_FRAMEWORKS, SOLIDITY_FRAMEWORKS_DIR } from "../utils/consts"; +import { BASE_DIR, SOLIDITY_FRAMEWORKS, SOLIDITY_FRAMEWORKS_DIR, EXAMPLE_CONTRACTS_DIR } from "../utils/consts"; const EXTERNAL_EXTENSION_TMP_DIR = "tmp-external-extension"; @@ -129,6 +129,7 @@ const processTemplatedFiles = async ( { solidityFramework, externalExtension, dev: isDev }: Options, basePath: string, solidityFrameworkPath: string | null, + exampleContractsPath: string | null, targetDir: string, ) => { const baseTemplatedFileDescriptors: TemplateDescriptor[] = findFilesRecursiveSync(basePath, path => @@ -151,6 +152,17 @@ const processTemplatedFiles = async ( .flat() : []; + const starterContractsTemplateFileDescriptors: TemplateDescriptor[] = exampleContractsPath + ? findFilesRecursiveSync(exampleContractsPath, filePath => isTemplateRegex.test(filePath)) + .map(exampleContractTemplatePath => ({ + path: exampleContractTemplatePath, + fileUrl: pathToFileURL(exampleContractTemplatePath).href, + relativePath: exampleContractTemplatePath.split(exampleContractsPath)[1], + source: `example-contracts ${solidityFramework}`, + })) + .flat() + : []; + const externalExtensionFolder = isDev ? typeof externalExtension === "string" ? path.join(basePath, "../../externalExtensions", externalExtension, "extension") @@ -174,6 +186,7 @@ const processTemplatedFiles = async ( ...baseTemplatedFileDescriptors, ...solidityFrameworkTemplatedFileDescriptors, ...externalExtensionTemplatedFileDescriptors, + ...starterContractsTemplateFileDescriptors, ].map(async templateFileDescriptor => { const templateTargetName = templateFileDescriptor.path.match(isTemplateRegex)?.[1] as string; @@ -189,6 +202,14 @@ const processTemplatedFiles = async ( } } + if (exampleContractsPath) { + const argsFilePath = path.join(exampleContractsPath, argsPath); + const fileExists = fs.existsSync(argsFilePath); + if (fileExists) { + argsFileUrls.push(pathToFileURL(argsFilePath).href); + } + } + if (externalExtension) { const argsFilePath = isDev ? path.join(basePath, "../../externalExtensions", externalExtension as string, "extension", argsPath) @@ -302,11 +323,13 @@ export async function copyTemplateFiles(options: Options, templateDir: string, t // 2. Copy solidity framework folder const solidityFrameworkPath = options.solidityFramework && getSolidityFrameworkPath(options.solidityFramework, templateDir); - if (solidityFrameworkPath) { await copyExtensionFiles(options, solidityFrameworkPath, targetDir); } + const exampleContractsPath = + options.solidityFramework && path.resolve(templateDir, EXAMPLE_CONTRACTS_DIR, options.solidityFramework); + // 3. Set up external extension if needed if (options.externalExtension) { let externalExtensionPath = path.join(tmpDir, "extension"); @@ -321,11 +344,27 @@ export async function copyTemplateFiles(options: Options, templateDir: string, t await setUpExternalExtensionFiles(options, tmpDir); } + if (options.solidityFramework) { + const externalExtensionSolidityPath = path.join( + externalExtensionPath, + "packages", + options.solidityFramework, + "contracts", + ); + // if external extension does not have solidity framework, we copy the example contracts + if (!fs.existsSync(externalExtensionSolidityPath) && exampleContractsPath) { + await copyExtensionFiles(options, exampleContractsPath, targetDir); + } + } + await copyExtensionFiles(options, externalExtensionPath, targetDir); } + if (!options.externalExtension && options.solidityFramework && exampleContractsPath) { + await copyExtensionFiles(options, exampleContractsPath, targetDir); + } // 4. Process templated files and generate output - await processTemplatedFiles(options, basePath, solidityFrameworkPath, targetDir); + await processTemplatedFiles(options, basePath, solidityFrameworkPath, exampleContractsPath, targetDir); // 5. Delete tmp directory if (options.externalExtension && !options.dev) { diff --git a/src/utils/consts.ts b/src/utils/consts.ts index f3ee6d438..b6a942488 100644 --- a/src/utils/consts.ts +++ b/src/utils/consts.ts @@ -1,5 +1,6 @@ export const BASE_DIR = "base"; export const SOLIDITY_FRAMEWORKS_DIR = "solidity-frameworks"; +export const EXAMPLE_CONTRACTS_DIR = "example-contracts"; export const SOLIDITY_FRAMEWORKS = { HARDHAT: "hardhat", diff --git a/src/utils/prompt-for-missing-options.ts b/src/utils/prompt-for-missing-options.ts index c6d9273ef..18cee780d 100644 --- a/src/utils/prompt-for-missing-options.ts +++ b/src/utils/prompt-for-missing-options.ts @@ -36,11 +36,12 @@ export async function promptForMissingOptions( const answers = await inquirer.prompt(questions, cliAnswers); + const solidityFramework = options.solidityFramework ?? answers.solidityFramework; const mergedOptions: Options = { project: options.project ?? answers.project, install: options.install, dev: options.dev ?? defaultOptions.dev, - solidityFramework: options.solidityFramework ?? answers.solidityFramework, + solidityFramework: solidityFramework === "none" ? null : solidityFramework, externalExtension: options.externalExtension, }; diff --git a/src/utils/show-help-message.ts b/src/utils/show-help-message.ts index 2a58cc276..441fabce1 100644 --- a/src/utils/show-help-message.ts +++ b/src/utils/show-help-message.ts @@ -2,10 +2,9 @@ import chalk from "chalk"; export const showHelpMessage = () => { console.log(` ${chalk.bold.blue("Usage:")} - ${chalk.bold.green("npx create-eth<@version>")} ${chalk.gray("[-i | --install | --skip | --skip-install] [-s | --solidity-framework ] [-e | --extension ] [-h | --help]")} + ${chalk.bold.green("npx create-eth<@version>")} ${chalk.gray("[--skip | --skip-install] [-s | --solidity-framework ] [-e | --extension ] [-h | --help]")} `); console.log(` ${chalk.bold.blue("Options:")} - ${chalk.gray("-i, --install")} Install packages ${chalk.gray("--skip, --skip-install")} Skip packages installation ${chalk.gray("-s, --solidity-framework")} Choose solidity framework ${chalk.gray("-e, --extension")} Add curated or third-party extension diff --git a/templates/solidity-frameworks/foundry/packages/foundry/contracts/YourContract.sol b/templates/example-contracts/foundry/packages/foundry/contracts/YourContract.sol similarity index 100% rename from templates/solidity-frameworks/foundry/packages/foundry/contracts/YourContract.sol rename to templates/example-contracts/foundry/packages/foundry/contracts/YourContract.sol diff --git a/templates/example-contracts/foundry/packages/foundry/script/Deploy.s.sol.args.mjs b/templates/example-contracts/foundry/packages/foundry/script/Deploy.s.sol.args.mjs new file mode 100644 index 000000000..00c236b6f --- /dev/null +++ b/templates/example-contracts/foundry/packages/foundry/script/Deploy.s.sol.args.mjs @@ -0,0 +1,5 @@ +export const deploymentsScriptsImports = `import { DeployYourContract } from "./DeployYourContract.s.sol";`; +export const deploymentsLogic = ` + DeployYourContract deployYourContract = new DeployYourContract(); + deployYourContract.run(); +`; diff --git a/templates/solidity-frameworks/foundry/packages/foundry/script/DeployYourContract.s.sol b/templates/example-contracts/foundry/packages/foundry/script/DeployYourContract.s.sol similarity index 100% rename from templates/solidity-frameworks/foundry/packages/foundry/script/DeployYourContract.s.sol rename to templates/example-contracts/foundry/packages/foundry/script/DeployYourContract.s.sol diff --git a/templates/solidity-frameworks/hardhat/packages/hardhat/contracts/YourContract.sol b/templates/example-contracts/hardhat/packages/hardhat/contracts/YourContract.sol similarity index 100% rename from templates/solidity-frameworks/hardhat/packages/hardhat/contracts/YourContract.sol rename to templates/example-contracts/hardhat/packages/hardhat/contracts/YourContract.sol diff --git a/templates/solidity-frameworks/hardhat/packages/hardhat/deploy/00_deploy_your_contract.ts b/templates/example-contracts/hardhat/packages/hardhat/deploy/00_deploy_your_contract.ts similarity index 100% rename from templates/solidity-frameworks/hardhat/packages/hardhat/deploy/00_deploy_your_contract.ts rename to templates/example-contracts/hardhat/packages/hardhat/deploy/00_deploy_your_contract.ts diff --git a/templates/solidity-frameworks/foundry/packages/foundry/script/Deploy.s.sol.template.mjs b/templates/solidity-frameworks/foundry/packages/foundry/script/Deploy.s.sol.template.mjs index f9f05e2ff..ea924b105 100644 --- a/templates/solidity-frameworks/foundry/packages/foundry/script/Deploy.s.sol.template.mjs +++ b/templates/solidity-frameworks/foundry/packages/foundry/script/Deploy.s.sol.template.mjs @@ -4,14 +4,10 @@ const content = ({ deploymentsScriptsImports, deploymentsLogic }) => `//SPDX-Lic pragma solidity ^0.8.19; import "./DeployHelpers.s.sol"; -import { DeployYourContract } from "./DeployYourContract.s.sol"; ${deploymentsScriptsImports.filter(Boolean).join("\n")} contract DeployScript is ScaffoldETHDeploy { function run() external { - DeployYourContract deployYourContract = new DeployYourContract(); - deployYourContract.run(); - ${deploymentsLogic.filter(Boolean).join("\n")} // deploy more contracts here