Skip to content

Commit e9b263e

Browse files
committed
🐛 Fixes error when preset or transforms arent specified by the config
1 parent 2ea6bab commit e9b263e

File tree

3 files changed

+150
-40
lines changed

3 files changed

+150
-40
lines changed

.changeset/pretty-rocks-yawn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@codeshift/cli': patch
3+
---
4+
5+
CLI will no longer error if either transforms or presets were undefined in the config

packages/cli/src/main.spec.ts

Lines changed: 121 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,37 @@
1+
jest.mock('live-plugin-manager');
12
jest.mock('jscodeshift/src/Runner', () => ({
23
run: jest.fn().mockImplementation(() => Promise.resolve()),
34
}));
45

5-
jest.mock('live-plugin-manager', () => ({
6-
PluginManager: () => ({
7-
install: () => Promise.resolve(undefined),
8-
require: (codemodName: string) => ({
9-
default: {
10-
transforms: {
11-
'18.0.0': `${codemodName}/path/to/18.js`,
12-
'19.0.0': `${codemodName}/path/to/19.js`,
13-
'20.0.0': `${codemodName}/path/to/20.js`,
14-
},
15-
presets: {
16-
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
17-
'update-imports': `${codemodName}/path/to/update-imports.js`,
18-
},
19-
},
20-
}),
21-
uninstallAll: () => Promise.resolve(),
22-
}),
23-
}));
24-
256
// @ts-ignore
267
import * as jscodeshift from 'jscodeshift/src/Runner';
27-
8+
import { PluginManager } from 'live-plugin-manager';
289
import main from './main';
2910

3011
const mockPath = 'src/pages/home-page/';
3112

3213
describe('main', () => {
3314
beforeEach(() => {
15+
(PluginManager as jest.Mock).mockReturnValue({
16+
install: () => Promise.resolve(undefined),
17+
require: (codemodName: string) => ({
18+
default: {
19+
transforms: {
20+
'18.0.0': `${codemodName}/path/to/18.js`,
21+
'19.0.0': `${codemodName}/path/to/19.js`,
22+
'20.0.0': `${codemodName}/path/to/20.js`,
23+
},
24+
presets: {
25+
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
26+
'update-imports': `${codemodName}/path/to/update-imports.js`,
27+
},
28+
},
29+
}),
30+
uninstallAll: () => Promise.resolve(),
31+
});
32+
});
33+
34+
afterEach(() => {
3435
jest.resetAllMocks();
3536
});
3637

@@ -327,6 +328,55 @@ describe('main', () => {
327328
expect.any(Object),
328329
);
329330
});
331+
332+
it('should not throw when attempting to run transform that is not present in config', async () => {
333+
(PluginManager as jest.Mock).mockReturnValue({
334+
install: () => Promise.resolve(undefined),
335+
require: (codemodName: string) => ({
336+
default: {
337+
presets: {
338+
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
339+
},
340+
},
341+
}),
342+
uninstallAll: () => Promise.resolve(),
343+
});
344+
345+
await expect(
346+
main([mockPath], {
347+
packages: 'mylib@20.0.0',
348+
parser: 'babel',
349+
extensions: 'js',
350+
}),
351+
).rejects.toEqual(
352+
Error(
353+
'Invalid version provided to the --packages flag. Unable to resolve version "20.0.0" for package "mylib"',
354+
),
355+
);
356+
});
357+
358+
it('should not throw when transform are not present in the config', async () => {
359+
(PluginManager as jest.Mock).mockReturnValue({
360+
install: () => Promise.resolve(undefined),
361+
// @ts-ignore
362+
require: (codemodName: string) => ({
363+
default: {
364+
presets: {
365+
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
366+
},
367+
},
368+
}),
369+
uninstallAll: () => Promise.resolve(),
370+
});
371+
372+
await expect(
373+
main([mockPath], {
374+
packages: 'mylib#update-formatting',
375+
parser: 'babel',
376+
extensions: 'js',
377+
}),
378+
).resolves.not.toThrow();
379+
});
330380
});
331381

332382
describe('when running presets with the -p flag', () => {
@@ -416,5 +466,55 @@ describe('main', () => {
416466
);
417467
}
418468
});
469+
470+
it('should not throw when attempting to run preset that is not present in config', async () => {
471+
(PluginManager as jest.Mock).mockReturnValue({
472+
install: () => Promise.resolve(undefined),
473+
// @ts-ignore
474+
require: (codemodName: string) => ({
475+
default: {
476+
transforms: {
477+
'20.0.0': `${codemodName}/path/to/20.js`,
478+
},
479+
},
480+
}),
481+
uninstallAll: () => Promise.resolve(),
482+
});
483+
484+
await expect(
485+
main([mockPath], {
486+
packages: 'mylib#foo-bar',
487+
parser: 'babel',
488+
extensions: 'js',
489+
}),
490+
).rejects.toEqual(
491+
Error(
492+
'Invalid preset provided to the --packages flag. Unable to resolve preset "foo-bar" for package "mylib"',
493+
),
494+
);
495+
});
496+
497+
it('should not throw when presets are not present in the config', async () => {
498+
(PluginManager as jest.Mock).mockReturnValue({
499+
install: () => Promise.resolve(undefined),
500+
// @ts-ignore
501+
require: (codemodName: string) => ({
502+
default: {
503+
transforms: {
504+
'20.0.0': `${codemodName}/path/to/20.js`,
505+
},
506+
},
507+
}),
508+
uninstallAll: () => Promise.resolve(),
509+
});
510+
511+
await expect(
512+
main([mockPath], {
513+
packages: 'mylib@20.0.0',
514+
parser: 'babel',
515+
extensions: 'js',
516+
}),
517+
).resolves.not.toThrow();
518+
});
419519
});
420520
});

packages/cli/src/main.ts

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export default async function main(paths: string[], flags: Flags) {
3939
const codemodName = `@codeshift/mod-${pkgName}`;
4040

4141
await packageManager.install(codemodName);
42+
// TODO: check if default exists first. module.exports might not have it
4243
const { default: codeshiftConfig } = packageManager.require(codemodName);
4344

4445
const codemodIds = pkg.split(/(?=[@#])/).filter(str => !!str);
@@ -65,44 +66,48 @@ export default async function main(paths: string[], flags: Flags) {
6566
);
6667
}
6768

68-
if (!codeshiftConfig.transforms[id]) {
69+
if (!codeshiftConfig.transforms || !codeshiftConfig.transforms[id]) {
6970
throw new InvalidUserInputError(
7071
`Invalid version provided to the --packages flag. Unable to resolve version "${id}" for package "${pkgName}"`,
7172
);
7273
}
7374
});
7475

7576
presetIds.forEach(id => {
76-
if (!codeshiftConfig.presets[id]) {
77+
if (!codeshiftConfig.presets || !codeshiftConfig.presets[id]) {
7778
throw new InvalidUserInputError(
78-
`Invalid preset provided to the --packages flag. Unable to resolve preset "${id}" for package "${pkgName}""`,
79+
`Invalid preset provided to the --packages flag. Unable to resolve preset "${id}" for package "${pkgName}"`,
7980
);
8081
}
8182
});
8283

8384
// Get transform file paths
84-
if (flags.sequence) {
85-
Object.entries(codeshiftConfig.transforms as Record<string, string>)
86-
.filter(([key]) => semver.satisfies(key, `>=${transformIds[0]}`))
87-
.forEach(([, path]) => transforms.push(path));
88-
} else {
89-
Object.entries(
90-
codeshiftConfig.transforms as Record<string, string>,
91-
).forEach(([id, path]) => {
92-
if (transformIds.includes(id)) {
93-
transforms.push(path);
94-
}
95-
});
85+
if (codeshiftConfig.transforms) {
86+
if (flags.sequence) {
87+
Object.entries(codeshiftConfig.transforms as Record<string, string>)
88+
.filter(([key]) => semver.satisfies(key, `>=${transformIds[0]}`))
89+
.forEach(([, path]) => transforms.push(path));
90+
} else {
91+
Object.entries(
92+
codeshiftConfig.transforms as Record<string, string>,
93+
).forEach(([id, path]) => {
94+
if (transformIds.includes(id)) {
95+
transforms.push(path);
96+
}
97+
});
98+
}
9699
}
97100

98101
// Get preset file paths
99-
Object.entries(codeshiftConfig.presets as Record<string, string>).forEach(
100-
([id, path]) => {
102+
if (codeshiftConfig.presets) {
103+
Object.entries(
104+
codeshiftConfig.presets as Record<string, string>,
105+
).forEach(([id, path]) => {
101106
if (presetIds.includes(id)) {
102107
transforms.push(path);
103108
}
104-
},
105-
);
109+
});
110+
}
106111
}
107112
}
108113

0 commit comments

Comments
 (0)