feat: update commands' types, add a hidden "to" command with a codemod target option

This commit is contained in:
Convly 2024-01-12 15:14:28 +01:00
parent 803724d019
commit 71336319dd
5 changed files with 91 additions and 28 deletions

View File

@ -1,12 +1,13 @@
import prompts from 'prompts';
import { loggerFactory } from '../../modules/logger';
import { Version } from '../../modules/version';
import { handleError } from '../errors';
import * as tasks from '../../tasks';
import type { Command } from '../types';
import type { CodemodsCommand } from '../types';
import type { Codemod } from '../../modules/codemod';
export const codemods: Command = async (options) => {
export const codemods: CodemodsCommand = async (options) => {
try {
const { silent, debug } = options;
const logger = loggerFactory({ silent, debug });
@ -66,9 +67,9 @@ export const codemods: Command = async (options) => {
selectCodemods,
dry: options.dry,
cwd: options.projectPath,
target: options.target,
target: Version.ReleaseType.Major,
});
} catch (err) {
handleError(err);
handleError(err, options.silent);
}
};

View File

@ -4,9 +4,9 @@ import { loggerFactory } from '../../modules/logger';
import { handleError } from '../errors';
import * as tasks from '../../tasks';
import type { Command } from '../types';
import type { UpgradeCommand } from '../types';
export const upgrade: Command = async (options) => {
export const upgrade: UpgradeCommand = async (options) => {
try {
const { silent, debug, yes } = options;
const logger = loggerFactory({ silent, debug });
@ -36,8 +36,9 @@ export const upgrade: Command = async (options) => {
dry: options.dry,
cwd: options.projectPath,
target: options.target,
codemodsTarget: options.codemodsTarget,
});
} catch (err) {
handleError(err);
handleError(err, options.silent);
}
};

View File

@ -1,9 +1,12 @@
import chalk from 'chalk';
export const handleError = (err: unknown) => {
export const handleError = (err: unknown, isSilent: boolean) => {
if (!isSilent) {
console.error(
chalk.red(`[ERROR]\t[${new Date().toISOString()}]`),
err instanceof Error ? err.message : err
);
}
process.exit(1);
};

View File

@ -1,11 +1,11 @@
import os from 'os';
import chalk from 'chalk';
import { Option, program } from 'commander';
import { InvalidArgumentError, Option, program } from 'commander';
import { version as packageJSONVersion } from '../../package.json';
import { Version } from '../modules/version';
import { isLiteralSemVer, isValidSemVer, semVerFactory, Version } from '../modules/version';
import type { CLIOptions } from './types';
import type { CLICodemodsOptions, CLIUpgradeOptions, CLIUpgradeToOptions } from './types';
const projectPathOption = new Option(
'-p, --project-path <project-path>',
@ -35,7 +35,7 @@ const addReleaseUpgradeCommand = (releaseType: Version.ReleaseType, description:
.addOption(debugOption)
.addOption(silentOption)
.addOption(automaticConfirmationOption)
.action(async (options: CLIOptions) => {
.action(async (options: CLIUpgradeOptions) => {
const { upgrade } = await import('./commands/upgrade.js');
return upgrade({ ...options, target: releaseType });
@ -66,9 +66,45 @@ program
.addOption(dryOption)
.addOption(debugOption)
.addOption(silentOption)
.action(async (options) => {
.action(async (options: CLICodemodsOptions) => {
const { codemods } = await import('./commands/codemods.js');
return codemods({ ...options, target: Version.ReleaseType.Major });
return codemods(options);
});
// Defines the 'to' command to upgrade to a specific Strapi version,
// with various options including custom codemod target.
// This command is meant for internal use for now (and is thus hidden)
program
.command('to <target>', { hidden: true })
.description('Upgrade to the specified version of Strapi')
.addOption(projectPathOption)
.addOption(dryOption)
.addOption(debugOption)
.addOption(silentOption)
.addOption(automaticConfirmationOption)
.addOption(
new Option(
'-c, --codemods-target <codemodsTarget>',
'Use a custom target for the codemods execution. Useful when targeting pre-releases'
).argParser((codemodsTarget) => {
if (!isLiteralSemVer(codemodsTarget)) {
throw new InvalidArgumentError(
`Expected a version with the following format: "<number>.<number>.<number>"`
);
}
return semVerFactory(codemodsTarget);
})
)
.action(async (target: string, options: CLIUpgradeToOptions) => {
if (!isValidSemVer(target)) {
console.error(`Invalid target supplied, expected a valid semver but got "${target}"`);
process.exit(1);
}
const { upgrade } = await import('./commands/upgrade.js');
return upgrade({ ...options, target: semVerFactory(target) });
});
program

View File

@ -1,16 +1,38 @@
import type { Version } from '../modules/version';
import type { MaybePromise } from '../types';
export interface CLIOptions {
dry: boolean;
debug: boolean;
silent: boolean;
yes?: boolean;
projectPath?: string;
// CLI
type DryOption = { dry: boolean };
type DebugOption = { debug: boolean };
type SilentOption = { silent: boolean };
type YesOption = { yes?: boolean };
type ProjectPathOption = { projectPath?: string };
export type CLIUpgradeOptions = DryOption &
DebugOption &
SilentOption &
YesOption &
ProjectPathOption;
export type CLIUpgradeToOptions = CLIUpgradeOptions & {
codemodsTarget?: Version.SemVer;
};
export type CLICodemodsOptions = DryOption & DebugOption & SilentOption & ProjectPathOption;
// COMMANDS OPTIONS
export interface UpgradeCommandOptions extends CLIUpgradeOptions {
target: Version.ReleaseType | Version.SemVer;
codemodsTarget?: Version.SemVer;
}
export interface CommandOptions extends CLIOptions {
target: Version.ReleaseType;
}
export interface CodemodsCommandOptions extends CLICodemodsOptions {}
export type Command = (options: CommandOptions) => MaybePromise<void>;
// COMMANDS
export type Command<TOptions extends object> = (options: TOptions) => MaybePromise<void>;
export type UpgradeCommand = Command<UpgradeCommandOptions>;
export type CodemodsCommand = Command<CodemodsCommandOptions>;