Skip to content

Commit

Permalink
fix(cli): unhide generator upgrade command (#4403)
Browse files Browse the repository at this point in the history
  • Loading branch information
armandobelardo authored Aug 22, 2024
1 parent fde4d4b commit eec537a
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 113 deletions.
56 changes: 2 additions & 54 deletions packages/cli/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -148,7 +148,6 @@ async function tryRunCli(cliContext: CliContext) {
addWriteOverridesCommand(cli, cliContext);
addTestCommand(cli, cliContext);
addUpdateApiSpecCommand(cli, cliContext);
addUpgradeGeneratorCommand(cli, cliContext);
addUpgradeCommand({
cli,
cliContext,
Expand All @@ -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"]);
Expand Down Expand Up @@ -666,57 +665,6 @@ function addUpgradeCommand({
);
}

function addUpgradeGeneratorCommand(cli: Argv<GlobalCliOptions>, 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<GlobalCliOptions>, cliContext: CliContext) {
cli.command(
"api update",
Expand Down
167 changes: 110 additions & 57 deletions packages/cli/cli/src/cliV2.ts
Original file line number Diff line number Diff line change
@@ -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<GlobalCliOptions>, cliContext: CliContext): void {
cli.command(
Expand Down Expand Up @@ -34,62 +36,113 @@ export function addGetOrganizationCommand(cli: Argv<GlobalCliOptions>, cliContex
);
}

export function addGeneratorListCommand(cli: Argv<GlobalCliOptions>, 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<GlobalCliOptions>, 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
});
}
);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
@@ -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]"
`;
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
4 changes: 4 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit eec537a

Please # to comment.