Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/commands/migrate.meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ export const meta = {
name: 'migrate',
description: 'Migrate from a package to a more performant alternative.',
args: {
all: {
type: 'boolean',
default: false,
description:
'Migrate all fixable replacements that exist in project dependencies.'
},
'dry-run': {
type: 'boolean',
default: false,
Expand Down
57 changes: 39 additions & 18 deletions src/commands/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {getPackageJson} from '../utils/package-json.js';

export async function run(ctx: CommandContext<typeof meta>) {
const [_commandName, ...targetModules] = ctx.positionals;
const all = ctx.values.all === true;
const dryRun = ctx.values['dry-run'] === true;
const interactive = ctx.values.interactive === true;
const include = ctx.values.include;
Expand All @@ -37,7 +38,7 @@ export async function run(ctx: CommandContext<typeof meta>) {
.map((rep) => rep.from)
);

if (interactive) {
if (interactive && !all) {
const additionalTargets = await prompts.autocompleteMultiselect({
message: 'Select packages to migrate',
maxItems: 10,
Expand All @@ -60,34 +61,54 @@ export async function run(ctx: CommandContext<typeof meta>) {
}
}

if (targetModules.length === 0) {
prompts.cancel(
'Error: Please specify a package to migrate. For example, `migrate chalk`'
);
return;
}
let selectedReplacements: Replacement[];

const selectedReplacements: Replacement[] = [];

for (const targetModule of targetModules) {
const replacement = fixableReplacements.find(
(rep) => rep.from === targetModule
if (all) {
selectedReplacements = fixableReplacements.filter((rep) =>
fixableReplacementsTargets.has(rep.from)
);
if (!replacement) {
if (selectedReplacements.length === 0) {
prompts.cancel('No fixable replacements found in project dependencies.');
return;
}
} else {
if (targetModules.length === 0) {
prompts.cancel(
`Error: Target package has no available migrations (${targetModule})`
'Error: Please specify a package to migrate. For example, `migrate chalk`'
);
return;
}

selectedReplacements.push(replacement);
selectedReplacements = [];

for (const targetModule of targetModules) {
if (!fixableReplacementsTargets.has(targetModule)) {
prompts.cancel(
`Error: Target package is not in project dependencies (${targetModule})`
);
return;
}

const replacement = fixableReplacements.find(
(rep) => rep.from === targetModule
);
if (!replacement) {
prompts.cancel(
`Error: Target package has no available migrations (${targetModule})`
);
return;
}

selectedReplacements.push(replacement);
}
}

if (!interactive) {
const targetNames = selectedReplacements.map((r) => r.from);
const targetModuleSummary =
targetModules.length > 6
? `${targetModules.slice(0, 6).join(', ')} and ${targetModules.length - 6} more`
: targetModules.join(', ');
targetNames.length > 6
? `${targetNames.slice(0, 6).join(', ')} and ${targetNames.length - 6} more`
: targetNames.join(', ');
prompts.log.message(`Targets: ${colors.dim(targetModuleSummary)}`);
}

Expand Down
41 changes: 41 additions & 0 deletions src/test/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,44 @@ describe('CLI', () => {
expect(normalizeStderr(stderr)).toMatchSnapshot();
});
});

describe('migrate --all', () => {
it('should migrate all fixable replacements with --all --dry-run when project has fixable deps', async () => {
const chalkDir = await createTempDir();
await createTestPackage(chalkDir, {
name: 'chalk-test',
version: '1.0.0',
type: 'module',
main: 'index.js',
dependencies: {chalk: '^4.0.0'}
});
await fs.writeFile(
path.join(chalkDir, 'index.js'),
"import chalk from 'chalk';\nconsole.log(chalk.cyan('hello'));"
);
try {
const {stdout, stderr, code} = await runCliProcess(
['migrate', '--all', '--dry-run'],
chalkDir
);
expect(code).toBe(0);
const output = stdout + stderr;
expect(output).toContain('Migration complete');
expect(output).toContain('chalk');
} finally {
await cleanupTempDir(chalkDir);
}
});

it('should show message when --all is used but no fixable replacements exist in dependencies', async () => {
const {stdout, stderr, code} = await runCliProcess(
['migrate', '--all'],
tempDir
);
const output = stdout + stderr;
expect(output).toContain(
'No fixable replacements found in project dependencies'
);
expect(code).toBe(0);
});
});
Loading