feat: add color option to CLI and configuration file

The option is used to force enable/disable color output and is passed to the reporter which should respect it
This commit is contained in:
Joakim Carlstein 2023-12-20 09:06:13 +01:00 committed by Joakim Carlstein
parent 7bae76f496
commit f9a16d87a1
14 changed files with 112 additions and 11 deletions

View file

@ -6,6 +6,14 @@ import { getConfig } from './get-config.js';
type Action = (args: string[]) => Promise<void>;
const useColors = (values: { color?: boolean; 'no-color'?: boolean }) => {
if (values['no-color']) {
return false;
}
return values.color;
};
const up: Action = async (args) => {
const config = await getConfig('up');
const { values } = parseArgs({
@ -36,6 +44,12 @@ const up: Action = async (args) => {
multiple: true,
default: [],
},
color: {
type: 'boolean',
},
'no-color': {
type: 'boolean',
},
},
allowPositionals: false,
});
@ -52,6 +66,8 @@ Options:
-p, --plugin The plugin(s) to use (can be specified multiple times)
-r, --reporter The reporter to use for reporting the migration progress
--dry List the pending migrations that would be run without actually running them
--color Force color output (this option is passed to the reporter)
--no-color Disable color output (this option is passed to the reporter)
Examples:
@ -71,7 +87,7 @@ Examples:
try {
const { default: upCommand } = await import('./commands/up.js');
process.exitCode = await upCommand({ storage, reporter, directory, plugins, dry });
process.exitCode = await upCommand({ storage, reporter, directory, plugins, dry, color: useColors(values) });
} catch (error) {
if (error instanceof ShowUsageError) {
console.error(error.message, '\n');
@ -115,6 +131,12 @@ const newMigration: Action = async (args) => {
multiple: true,
default: [],
},
color: {
type: 'boolean',
},
'no-color': {
type: 'boolean',
},
},
allowPositionals: true,
});
@ -137,6 +159,8 @@ Options:
(if the extension option is not provided the template file's extension will be used)
-e, --extension The extension to use for the new migration file
(if no template or plugin is provided an empty migration file will be created with the given extension)
--color Force color output (this option is passed to the reporter)
--no-color Disable color output (this option is passed to the reporter)
One of the --template, --extension or the --plugin options must be specified
@ -165,7 +189,7 @@ Examples:
try {
const { default: newCommand } = await import('./commands/new.js');
await newCommand({ directory, template, plugins, extension, reporter }, name);
await newCommand({ directory, template, plugins, extension, reporter, color: useColors(values) }, name);
} catch (error) {
if (error instanceof ShowUsageError) {
console.error(error.message, '\n');
@ -199,6 +223,12 @@ const list: Action = async (args) => {
type: 'string',
short: 's',
},
color: {
type: 'boolean',
},
'no-color': {
type: 'boolean',
},
},
allowPositionals: false,
});
@ -213,6 +243,8 @@ Options:
-d, --directory The directory where the migration files are located (required)
-r, --reporter The reporter to use for reporting the migrations
-s, --storage The storage to use to get the migration history (required)
--color Force color output (this option is passed to the reporter)
--no-color Disable color output (this option is passed to the reporter)
Examples:
@ -230,7 +262,7 @@ Examples:
try {
const { default: listCommand } = await import('./commands/list.js');
process.exitCode = await listCommand({ directory, storage, reporter });
process.exitCode = await listCommand({ directory, storage, reporter, color: useColors(values) });
} catch (error) {
if (error instanceof ShowUsageError) {
console.error(error.message, '\n');
@ -268,6 +300,12 @@ const remove: Action = async (args) => {
type: 'string',
short: 's',
},
color: {
type: 'boolean',
},
'no-color': {
type: 'boolean',
},
},
allowPositionals: true,
});
@ -289,6 +327,8 @@ Options:
-s, --storage The storage to use to get the migration history (required)
-f, --force Force removal of the migration history entry even if the migration file does not exist
or it's in a non-failed state
--color Force color output (this option is passed to the reporter)
--no-color Disable color output (this option is passed to the reporter)
Examples:
@ -306,7 +346,10 @@ Examples:
try {
const { default: removeCommand } = await import('./commands/remove.js');
process.exitCode = await removeCommand({ directory, storage, reporter, force }, positionals[0] ?? '');
process.exitCode = await removeCommand(
{ directory, storage, reporter, force, color: useColors(values) },
positionals[0] ?? '',
);
} catch (error) {
if (error instanceof ShowUsageError) {
console.error(error.message, '\n');

View file

@ -10,7 +10,12 @@ import { version } from '../get-package-info.js';
const lazyDefaultReporter = async () => import('../reporters/default.js');
export default async function listCommand({ directory, reporter: reporterConfig, storage: storageConfig }: Config) {
export default async function listCommand({
directory,
reporter: reporterConfig,
storage: storageConfig,
color,
}: Config) {
if (!directory) {
throw MissingOptionError.fromOption('directory');
}
@ -31,7 +36,7 @@ export default async function listCommand({ directory, reporter: reporterConfig,
);
}
await reporter.onInit?.({ command: 'list', version, cwd, dry: false, directory });
await reporter.onInit?.({ command: 'list', version, cwd, dry: false, directory, color });
const [storage, storageError] = await exec(async () => storagePlugin.initializeStorage());

View file

@ -19,7 +19,7 @@ import { getDuration } from '../get-duration.js';
const lazyDefaultReporter = async () => import('../reporters/default.js');
export default async function newCommand(
{ directory, template, reporter: reporterConfig, plugins = [], extension }: Config,
{ directory, template, reporter: reporterConfig, plugins = [], extension, color }: Config,
name: string,
) {
if (!directory) {
@ -45,7 +45,7 @@ export default async function newCommand(
);
}
await reporter.onInit?.({ command: 'new', version, cwd, dry: false, directory });
await reporter.onInit?.({ command: 'new', version, cwd, dry: false, directory, color });
const start = process.hrtime();

View file

@ -22,7 +22,7 @@ type ExtraFlags = {
const lazyDefaultReporter = async () => import('../reporters/default.js');
export default async function removeCommand(
{ directory, reporter: reporterConfig, storage: storageConfig, force }: Config & ExtraFlags,
{ directory, reporter: reporterConfig, storage: storageConfig, color, force = false }: Config & ExtraFlags,
name: string,
) {
if (!directory) {
@ -57,7 +57,7 @@ export default async function removeCommand(
return 1;
}
await reporter.onInit?.({ command: 'remove', version, cwd, dry: false, directory });
await reporter.onInit?.({ command: 'remove', version, cwd, dry: false, directory, color });
const [migrationFile, fileError] = await exec(async () => getMigration(cwd, directory, name, !force));

View file

@ -33,6 +33,7 @@ describe('up', () => {
command: 'up',
cwd: '/emigrate',
dry: false,
color: undefined,
version,
directory: 'migrations',
},
@ -111,6 +112,7 @@ describe('up', () => {
cwd: '/emigrate',
version,
dry: false,
color: undefined,
directory: 'migrations',
},
]);
@ -152,6 +154,7 @@ describe('up', () => {
cwd: '/emigrate',
version,
dry: true,
color: undefined,
directory: 'migrations',
},
]);
@ -193,6 +196,7 @@ describe('up', () => {
cwd: '/emigrate',
version,
dry: false,
color: undefined,
directory: 'migrations',
},
]);
@ -219,6 +223,7 @@ describe('up', () => {
cwd: '/emigrate',
version,
dry: false,
color: undefined,
directory: 'migrations',
},
]);
@ -265,6 +270,7 @@ describe('up', () => {
cwd: '/emigrate',
version,
dry: false,
color: undefined,
directory: 'migrations',
},
]);
@ -312,6 +318,7 @@ describe('up', () => {
cwd: '/emigrate',
version,
dry: false,
color: undefined,
directory: 'migrations',
},
]);

View file

@ -25,6 +25,7 @@ export default async function upCommand({
storage: storageConfig,
reporter: reporterConfig,
directory,
color,
dry = false,
plugins = [],
cwd = process.cwd(),
@ -49,7 +50,7 @@ export default async function upCommand({
);
}
await reporter.onInit?.({ command: 'up', version, cwd, dry, directory });
await reporter.onInit?.({ command: 'up', version, cwd, dry, directory, color });
const [storage, storageError] = await exec(async () => storagePlugin.initializeStorage());

View file

@ -11,6 +11,7 @@ export type Config = {
directory?: string;
template?: string;
extension?: string;
color?: boolean;
};
export type EmigrateConfig = Config & {