diff --git a/src/config.ts b/src/config.ts index a6f281e99..13858cac4 100644 --- a/src/config.ts +++ b/src/config.ts @@ -4,7 +4,7 @@ const config: Config = { questions: [ typedQuestion({ type: "single-select", - name: "solidity-framework", + name: "solidityFramework", message: "What solidity framework do you want to use?", extensions: ["hardhat", "foundry", null], default: "hardhat", diff --git a/src/main.ts b/src/main.ts index 03411840a..537717143 100644 --- a/src/main.ts +++ b/src/main.ts @@ -55,8 +55,8 @@ export async function createProject(options: Options) { }, }, { - title: `📡 Initializing Git repository ${ - options.extensions.includes("foundry") ? "and submodules" : "" + title: `📡 Initializing Git repository${ + options.extensions.includes("foundry") ? " and submodules" : "" }`, task: () => createFirstGitCommit(targetDirectory, options), }, diff --git a/src/types.ts b/src/types.ts index 20ee48a0e..f8639c82d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,22 +2,30 @@ import type { Question } from "inquirer"; export type Args = string[]; -export type RawOptions = { +type BaseOptions = { project: string | null; install: boolean | null; dev: boolean; - extensions: Extension[] | null; }; -type NonNullableRawOptions = { - [Prop in keyof RawOptions]: NonNullable; +export type RawOptions = BaseOptions & { + solidityFramework: SolidityFramework | "none" | null; }; -export type Options = NonNullableRawOptions; +type MergedOptions = BaseOptions & { + extensions: Extension[]; +}; + +type NonNullableMergedOptions = { + [Prop in keyof MergedOptions]: NonNullable; +}; + +export type Options = NonNullableMergedOptions; + +export type SolidityFramework = "hardhat" | "foundry"; + +export type Extension = SolidityFramework; -export type Extension = - | "hardhat" - | "foundry" type NullExtension = null; export type ExtensionOrNull = Extension | NullExtension; // corresponds to inquirer question types: diff --git a/src/utils/parse-arguments-into-options.ts b/src/utils/parse-arguments-into-options.ts index 1879f3247..2632f8ec4 100644 --- a/src/utils/parse-arguments-into-options.ts +++ b/src/utils/parse-arguments-into-options.ts @@ -12,6 +12,9 @@ export function parseArgumentsIntoOptions(rawArgs: Args): RawOptions { "--skip": "--skip-install", "-s": "--skip-install", + "--solidity-framework": solidityFrameworkHandler, + "-f": "--solidity-framework", + "--dev": Boolean, }, { @@ -21,16 +24,39 @@ export function parseArgumentsIntoOptions(rawArgs: Args): RawOptions { const install = args["--install"] ?? null; const skipInstall = args["--skip-install"] ?? null; + + if (install && skipInstall) { + throw new Error( + 'Please select only one of the options: "--install" or "--skip-install".' + ); + } + const hasInstallRelatedFlag = install || skipInstall; const dev = args["--dev"] ?? false; // info: use false avoid asking user const project = args._[0] ?? null; + const solidityFramework = args["--solidity-framework"] ?? null; + return { project, install: hasInstallRelatedFlag ? install || !skipInstall : null, dev, - extensions: null, // TODO add extensions flags + solidityFramework, }; } + +function solidityFrameworkHandler(value: string) { + const lowercasedValue = value.toLowerCase(); + if ( + lowercasedValue === "hardhat" || + lowercasedValue === "foundry" || + lowercasedValue === "none" + ) { + return lowercasedValue; + } + + // choose from cli prompts + return null; +} diff --git a/src/utils/prompt-for-missing-options.ts b/src/utils/prompt-for-missing-options.ts index a949496e2..b6ebe7c7e 100644 --- a/src/utils/prompt-for-missing-options.ts +++ b/src/utils/prompt-for-missing-options.ts @@ -6,7 +6,7 @@ import { RawOptions, extensionWithSubextensions, isDefined, - isExtension + isExtension, } from "../types"; import inquirer, { Answers } from "inquirer"; import { extensionDict } from "./extensions-tree"; @@ -16,14 +16,14 @@ const defaultOptions: RawOptions = { project: "my-dapp-example", install: true, dev: false, - extensions: [], + solidityFramework: "none", }; const invalidQuestionNames = ["project", "install"]; const nullExtensionChoice = { - name: 'None', - value: null -} + name: "none", + value: null, +}; export async function promptForMissingOptions( options: RawOptions @@ -78,18 +78,21 @@ export async function promptForMissingOptions( .join(", ")}` ); } + const extensions = question.extensions .filter(isExtension) .map((ext) => extensionDict[ext]) .filter(isDefined); - const hasNoneOption = question.extensions.includes(null) + const hasNoneOption = question.extensions.includes(null); questions.push({ type: question.type === "multi-select" ? "checkbox" : "list", name: question.name, message: question.message, - choices: hasNoneOption ? [...extensions, nullExtensionChoice] : extensions, + choices: hasNoneOption + ? [...extensions, nullExtensionChoice] + : extensions, }); recurringAddFollowUps(extensions, question.name); @@ -108,14 +111,17 @@ export async function promptForMissingOptions( project: options.project ?? answers.project, install: options.install ?? answers.install, dev: options.dev ?? defaultOptions.dev, - extensions: [], + extensions: [options.solidityFramework ?? answers.solidityFramework].filter( + (ext) => Boolean(ext) && ext !== "none" + ), }; - config.questions.forEach((question) => { - const { name } = question; - const choice: Extension[] = [answers[name]].flat().filter(isDefined); - mergedOptions.extensions.push(...choice); - }); + // TODO: check if it needed for nested extensions + // config.questions.forEach((question) => { + // const { name } = question; + // const choice: Extension[] = [answers[name]].flat().filter(isDefined); + // mergedOptions.extensions.push(...choice); + // }); const recurringAddNestedExtensions = (baseExtensions: Extension[]) => { baseExtensions.forEach((extValue) => {