From eec537a7c8a42a5e0b0c78d576daf24b18050204 Mon Sep 17 00:00:00 2001 From: Armando Belardo <11140328+armandobelardo@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:45:28 -0400 Subject: [PATCH] fix(cli): unhide generator upgrade command (#4403) --- packages/cli/cli/src/cli.ts | 56 +----- packages/cli/cli/src/cliV2.ts | 167 ++++++++++++------ .../help/__snapshots__/help.test.ts.snap | 4 +- .../upgrade-generator.test.ts.snap | 35 ++++ .../upgrade-generator.test.ts | 26 +++ pnpm-lock.yaml | 4 + 6 files changed, 179 insertions(+), 113 deletions(-) create mode 100644 packages/cli/ete-tests/src/tests/upgrade-generator/__snapshots__/upgrade-generator.test.ts.snap diff --git a/packages/cli/cli/src/cli.ts b/packages/cli/cli/src/cli.ts index 4550b64874b..78594baad2e 100644 --- a/packages/cli/cli/src/cli.ts +++ b/packages/cli/cli/src/cli.ts @@ -18,7 +18,7 @@ import { loadOpenAPIFromUrl, LoadOpenAPIStatus } from "../../init/src/utils/load import { CliContext } from "./cli-context/CliContext"; import { getLatestVersionOfCli } from "./cli-context/upgrade-utils/getLatestVersionOfCli"; import { GlobalCliOptions, loadProjectAndRegisterWorkspacesWithContext } from "./cliCommons"; -import { addGeneratorListCommand, addGetOrganizationCommand } from "./cliV2"; +import { addGeneratorCommands, addGetOrganizationCommand } from "./cliV2"; import { addGeneratorToWorkspaces } from "./commands/add-generator/addGeneratorToWorkspaces"; import { previewDocsWorkspace } from "./commands/docs-dev/devDocsWorkspace"; import { formatWorkspaces } from "./commands/format/formatWorkspaces"; @@ -148,7 +148,6 @@ async function tryRunCli(cliContext: CliContext) { addWriteOverridesCommand(cli, cliContext); addTestCommand(cli, cliContext); addUpdateApiSpecCommand(cli, cliContext); - addUpgradeGeneratorCommand(cli, cliContext); addUpgradeCommand({ cli, cliContext, @@ -159,7 +158,7 @@ async function tryRunCli(cliContext: CliContext) { // CLI V2 Sanctioned Commands addGetOrganizationCommand(cli, cliContext); - addGeneratorListCommand(cli, cliContext); + addGeneratorCommands(cli, cliContext); cli.middleware(async (argv) => { cliContext.setLogLevel(argv["log-level"]); @@ -666,57 +665,6 @@ function addUpgradeCommand({ ); } -function addUpgradeGeneratorCommand(cli: Argv, cliContext: CliContext) { - cli.command( - "generator upgrade", - `Upgrades the specified generator in ${GENERATORS_CONFIGURATION_FILENAME} to the latest stable version.`, - (yargs) => - yargs - .option("generator", { - string: true, - description: "The type of generator to upgrade, ex: `fern-typescript-node-sdk`." - }) - .option("group", { - string: true, - description: - "The group in which the generator is located, if group is not specified, the all generators of the specified type will be upgraded." - }) - .option("api", { - string: true, - description: - "The API to upgrade the generator for. If not specified, the generator will be upgraded for all APIs." - }) - .option("include-major", { - boolean: true, - default: false, - description: - "Whether or not to include major versions within the upgrade. Defaults to false, meaning major versions will be skipped." - }), - async (argv) => { - cliContext.instrumentPostHogEvent({ - command: "fern generator upgrade", - properties: { - generator: argv.generator, - version: argv.version, - api: argv.api, - group: argv.group, - includeMajor: argv.includeMajor - } - }); - await upgradeGenerator({ - cliContext, - generator: argv.generator, - group: argv.group, - project: await loadProjectAndRegisterWorkspacesWithContext(cliContext, { - commandLineApiWorkspace: argv.api, - defaultToAllApiWorkspaces: true - }), - includeMajor: argv.includeMajor - }); - } - ); -} - function addUpdateApiSpecCommand(cli: Argv, cliContext: CliContext) { cli.command( "api update", diff --git a/packages/cli/cli/src/cliV2.ts b/packages/cli/cli/src/cliV2.ts index e0240b71689..92fe74dcfe8 100644 --- a/packages/cli/cli/src/cliV2.ts +++ b/packages/cli/cli/src/cliV2.ts @@ -1,8 +1,10 @@ +import { GENERATORS_CONFIGURATION_FILENAME } from "@fern-api/configuration"; import { Argv } from "yargs"; import { CliContext } from "./cli-context/CliContext"; import { GlobalCliOptions, loadProjectAndRegisterWorkspacesWithContext } from "./cliCommons"; import { getGeneratorList } from "./commands/generator-list/getGeneratorList"; import { getOrganziation } from "./commands/organization/getOrganization"; +import { upgradeGenerator } from "./commands/upgrade/upgradeGenerator"; export function addGetOrganizationCommand(cli: Argv, cliContext: CliContext): void { cli.command( @@ -34,62 +36,113 @@ export function addGetOrganizationCommand(cli: Argv, cliContex ); } -export function addGeneratorListCommand(cli: Argv, cliContext: CliContext): void { - cli.command( - "generator list", - // Hides the command from the help message - false, - (yargs) => - yargs - .option("output", { - string: true, - alias: "o", - description: "The location to output the list as a text file, defaults to standard out." - }) - .option("generators", { - string: true, - type: "array", - description: - "The type of generator to include in the list, ex: `fern-typescript-node-sdk`. If omitted, all generators will be listed." - }) - .option("groups", { - type: "array", - string: true, - description: - "The groups to include generators from, if group is not specified, the all generators of the specified type will be listed." - }) - .option("apis", { - type: "array", - string: true, - description: - "The APIs to list the generators for. If not specified, the generator will be upgraded for all APIs." - }) - .option("api-fallback", { - string: true, - // Don't love this, but also don't know how else to maintain this structure without assuming some sentinel, - // which this feels better than. - description: - "The APIs to list the generators for. If not specified, the generator will be upgraded for all APIs." - }), - async (argv) => { - cliContext.instrumentPostHogEvent({ - command: "fern generator list", - properties: { - outputLocation: argv.output +export function addGeneratorCommands(cli: Argv, cliContext: CliContext): void { + cli.command("generator", "Operate on the generators within your Fern configuration", (yargs) => { + yargs + .command( + "list", + // Hides the command from the help message + false, + (yargs) => + yargs + .option("output", { + string: true, + alias: "o", + description: "The location to output the list as a text file, defaults to standard out." + }) + .option("generators", { + string: true, + type: "array", + description: + "The type of generator to include in the list, ex: `fern-typescript-node-sdk`. If omitted, all generators will be listed." + }) + .option("groups", { + type: "array", + string: true, + description: + "The groups to include generators from, if group is not specified, the all generators of the specified type will be listed." + }) + .option("apis", { + type: "array", + string: true, + description: + "The APIs to list the generators for. If not specified, the generator will be upgraded for all APIs." + }) + .option("api-fallback", { + string: true, + // Don't love this, but also don't know how else to maintain this structure without assuming some sentinel, + // which this feels better than. + description: + "The APIs to list the generators for. If not specified, the generator will be upgraded for all APIs." + }), + async (argv) => { + cliContext.instrumentPostHogEvent({ + command: "fern generator list", + properties: { + outputLocation: argv.output + } + }); + await getGeneratorList({ + project: await loadProjectAndRegisterWorkspacesWithContext(cliContext, { + commandLineApiWorkspace: undefined, + defaultToAllApiWorkspaces: true + }), + generatorFilter: argv.generators ? new Set(argv.generators) : undefined, + groupFilter: argv.groups ? new Set(argv.groups) : undefined, + apiFilter: argv.apis ? new Set(argv.apis) : undefined, + apiKeyFallback: argv.apiFallback, + cliContext, + outputLocation: argv.output + }); } - }); - await getGeneratorList({ - project: await loadProjectAndRegisterWorkspacesWithContext(cliContext, { - commandLineApiWorkspace: undefined, - defaultToAllApiWorkspaces: true - }), - generatorFilter: argv.generators ? new Set(argv.generators) : undefined, - groupFilter: argv.groups ? new Set(argv.groups) : undefined, - apiFilter: argv.apis ? new Set(argv.apis) : undefined, - apiKeyFallback: argv.apiFallback, - cliContext, - outputLocation: argv.output - }); - } - ); + ) + .command( + "upgrade", + `Upgrades the specified generator in ${GENERATORS_CONFIGURATION_FILENAME} to the latest stable version.`, + (yargs) => + yargs + .option("generator", { + string: true, + description: "The type of generator to upgrade, ex: `fern-typescript-node-sdk`." + }) + .option("group", { + string: true, + description: + "The group in which the generator is located, if group is not specified, the all generators of the specified type will be upgraded." + }) + .option("api", { + string: true, + description: + "The API to upgrade the generator for. If not specified, the generator will be upgraded for all APIs." + }) + .option("include-major", { + boolean: true, + default: false, + description: + "Whether or not to include major versions within the upgrade. Defaults to false, meaning major versions will be skipped." + }), + async (argv) => { + cliContext.instrumentPostHogEvent({ + command: "fern generator upgrade", + properties: { + generator: argv.generator, + version: argv.version, + api: argv.api, + group: argv.group, + includeMajor: argv.includeMajor + } + }); + await upgradeGenerator({ + cliContext, + generator: argv.generator, + group: argv.group, + project: await loadProjectAndRegisterWorkspacesWithContext(cliContext, { + commandLineApiWorkspace: argv.api, + defaultToAllApiWorkspaces: true + }), + includeMajor: argv.includeMajor + }); + } + ); + }); } diff --git a/packages/cli/ete-tests/src/tests/help/__snapshots__/help.test.ts.snap b/packages/cli/ete-tests/src/tests/help/__snapshots__/help.test.ts.snap index c3369a6ec86..fe41d695085 100644 --- a/packages/cli/ete-tests/src/tests/help/__snapshots__/help.test.ts.snap +++ b/packages/cli/ete-tests/src/tests/help/__snapshots__/help.test.ts.snap @@ -24,11 +24,11 @@ Commands: fern-dev api update Pulls the latest OpenAPI spec from the specified origin in generators.yml and updates the local spec. - fern-dev generator upgrade Upgrades the specified generator in - generators.yml to the latest stable version. fern-dev upgrade Upgrades version in fern.config.json. Also upgrades generators in generators.yml to their minimum-compatible versions. + fern-dev generator Operate on the generators within your Fern + configuration Options: --help Show help [boolean] diff --git a/packages/cli/ete-tests/src/tests/upgrade-generator/__snapshots__/upgrade-generator.test.ts.snap b/packages/cli/ete-tests/src/tests/upgrade-generator/__snapshots__/upgrade-generator.test.ts.snap new file mode 100644 index 00000000000..50c185a2efa --- /dev/null +++ b/packages/cli/ete-tests/src/tests/upgrade-generator/__snapshots__/upgrade-generator.test.ts.snap @@ -0,0 +1,35 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`fern generator upgrade > fern generator help commands 1`] = ` +"fern-dev generator + +Operate on the generators within your Fern configuration + +Commands: + fern-dev generator upgrade Upgrades the specified generator in generators.yml + to the latest stable version. + +Options: + --help Show help [boolean] + --log-level [choices: "debug", "info", "warn", "error"] [default: "info"]" +`; + +exports[`fern generator upgrade > fern generator help commands 2`] = ` +"fern-dev generator upgrade + +Upgrades the specified generator in generators.yml to the latest stable version. + +Options: + --help Show help [boolean] + --log-level [choices: "debug", "info", "warn", "error"] [default: "info"] + --generator The type of generator to upgrade, ex: + \`fern-typescript-node-sdk\`. [string] + --group The group in which the generator is located, if group is not + specified, the all generators of the specified type will be + upgraded. [string] + --api The API to upgrade the generator for. If not specified, the + generator will be upgraded for all APIs. [string] + --include-major Whether or not to include major versions within the upgrade. + Defaults to false, meaning major versions will be skipped. + [boolean] [default: false]" +`; diff --git a/packages/cli/ete-tests/src/tests/upgrade-generator/upgrade-generator.test.ts b/packages/cli/ete-tests/src/tests/upgrade-generator/upgrade-generator.test.ts index 7b115b202ff..58022620aae 100644 --- a/packages/cli/ete-tests/src/tests/upgrade-generator/upgrade-generator.test.ts +++ b/packages/cli/ete-tests/src/tests/upgrade-generator/upgrade-generator.test.ts @@ -23,4 +23,30 @@ describe("fern generator upgrade", () => { expect(await getDirectoryContents(outputPath)).not.toBeNull(); }, 60_000); + + it("fern generator help commands", async () => { + // Create tmpdir and copy contents + const tmpDir = await tmp.dir(); + const directory = AbsoluteFilePath.of(tmpDir.path); + + await cp(FIXTURES_DIR, directory, { recursive: true }); + + expect( + ( + await runFernCli(["generator", "--help"], { + cwd: directory, + reject: false + }) + ).stdout + ).toMatchSnapshot(); + + expect( + ( + await runFernCli(["generator", "upgrade", "--help"], { + cwd: directory, + reject: false + }) + ).stdout + ).toMatchSnapshot(); + }, 60_000); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96ca87a537c..a0846d50376 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3183,6 +3183,10 @@ importers: specifier: 4.6.4 version: 4.6.4 + packages/cli/cli/dist/dev: {} + + packages/cli/cli/dist/prod: {} + packages/cli/configuration: dependencies: '@fern-api/core-utils':