Skip to content

Commit 3350fd2

Browse files
Merge pull request #96 from CodeshiftCommunity/validator-refactor
Validator refactor
2 parents 4872226 + f6979d5 commit 3350fd2

File tree

17 files changed

+591
-119
lines changed

17 files changed

+591
-119
lines changed

.changeset/gentle-mugs-nail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@codeshift/validator': patch
3+
---
4+
5+
Adds additional test coverage to the validator package

.changeset/hungry-badgers-return.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+
Internal refactor, CLI now uses fetcher package

.changeset/selfish-wombats-peel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@codeshift/fetcher': patch
3+
---
4+
5+
Initial release

packages/cli/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
"start:dev": "ts-node src/index.ts"
1616
},
1717
"dependencies": {
18+
"@codeshift/fetcher": "0.0.1",
1819
"@codeshift/initializer": "0.1.8",
20+
"@codeshift/types": "*",
1921
"@codeshift/validator": "0.2.3",
2022
"chalk": "^4.1.0",
2123
"commander": "^8.2.0",

packages/cli/src/errors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export class InvalidUserInputError extends Error {}
2+
export class InvalidConfigError extends Error {}

packages/cli/src/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import main from './main';
55
import list from './list';
66
import init from './init';
77
import validate from './validate';
8-
import { InvalidUserInputError } from './errors';
8+
import { InvalidUserInputError, InvalidConfigError } from './errors';
99

1010
import packageJson from '../package.json';
1111

@@ -138,6 +138,11 @@ program.exitOverride();
138138
process.exit(9);
139139
}
140140

141+
if (error instanceof InvalidConfigError) {
142+
console.warn(chalk.red(error.message));
143+
process.exit(7);
144+
}
145+
141146
console.error(chalk.red(error));
142147
process.exit(1);
143148
}

packages/cli/src/main.spec.ts

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

7+
import path from 'path';
68
// @ts-ignore
79
import * as jscodeshift from 'jscodeshift/src/Runner';
810
import { PluginManager } from 'live-plugin-manager';
11+
import globby from 'globby';
912

1013
import main from './main';
1114

@@ -532,28 +535,45 @@ describe('main', () => {
532535
});
533536

534537
describe('when running transforms from NPM with the -p flag', () => {
538+
const mockMatchedPath = path.join(
539+
__dirname,
540+
'path',
541+
'to',
542+
'codeshift.config.js',
543+
);
544+
535545
beforeEach(() => {
546+
((globby as unknown) as jest.Mock).mockImplementation(() =>
547+
Promise.resolve([mockMatchedPath]),
548+
);
549+
536550
(PluginManager as jest.Mock).mockImplementation(() => ({
537551
install: jest.fn().mockResolvedValue(undefined),
538-
require: jest.fn().mockImplementation((codemodName: string) => {
539-
if (codemodName.startsWith('@codeshift')) {
540-
throw new Error('Attempted to fetch codemod from community folder');
541-
}
552+
require: jest.fn(),
553+
getInfo: jest
554+
.fn()
555+
.mockReturnValue({ location: path.join(__dirname, 'path', 'to') }),
556+
uninstallAll: jest.fn().mockResolvedValue(undefined),
557+
}));
558+
});
542559

543-
return {
560+
it('should run package transform for single version', async () => {
561+
jest.mock(
562+
mockMatchedPath,
563+
() => ({
564+
__esModule: true,
565+
default: {
544566
transforms: {
545-
'18.0.0': `${codemodName}/path/to/18.js`,
567+
'18.0.0': 'mylib/path/to/18.js',
546568
},
547569
presets: {
548-
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
570+
'update-formatting': 'mylib/path/to/update-formatting.js',
549571
},
550-
};
572+
},
551573
}),
552-
uninstallAll: jest.fn().mockResolvedValue(undefined),
553-
}));
554-
});
574+
{ virtual: true },
575+
);
555576

556-
it('should run package transform for single version', async () => {
557577
await main([mockPath], {
558578
packages: 'mylib@18.0.0',
559579
parser: 'babel',

packages/cli/src/main.ts

Lines changed: 32 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,20 @@
11
import semver from 'semver';
22
import chalk from 'chalk';
3-
import path from 'path';
3+
// import path from 'path';
44
import { PluginManager } from 'live-plugin-manager';
55
import merge from 'lodash/merge';
66
// @ts-ignore Run transform(s) on path https://github.com/facebook/jscodeshift/issues/398
77
import * as jscodeshift from 'jscodeshift/src/Runner';
8+
9+
import { fetchPackage, fetchRemotePackage } from '@codeshift/fetcher';
810
import { isValidConfig } from '@codeshift/validator';
911
import { CodeshiftConfig } from '@codeshift/types';
1012

1113
import { Flags } from './types';
1214
import { InvalidUserInputError } from './errors';
1315

14-
async function fetchCommunityPackageConfig(
15-
packageName: string,
16-
packageManager: PluginManager,
17-
) {
18-
const pkgName = packageName.replace('@', '').replace('/', '__');
19-
const commPackageName = `@codeshift/mod-${pkgName}`;
20-
21-
await packageManager.install(commPackageName);
22-
const pkg = packageManager.require(commPackageName);
23-
const config: CodeshiftConfig = pkg.default ? pkg.default : pkg;
24-
25-
if (!isValidConfig(config)) {
26-
throw new Error(`Invalid config found in module ${commPackageName}`);
27-
}
28-
29-
return config;
30-
}
31-
32-
async function fetchRemotePackageConfig(
33-
packageName: string,
34-
packageManager: PluginManager,
35-
) {
36-
await packageManager.install(packageName);
37-
const pkg = packageManager.require(packageName);
38-
39-
if (pkg) {
40-
const config: CodeshiftConfig = pkg.default ? pkg.default : pkg;
41-
42-
if (config && isValidConfig(config)) {
43-
// Found a config at the main entry-point
44-
return config;
45-
}
46-
}
47-
48-
const info = packageManager.getInfo(packageName);
49-
50-
if (info) {
51-
let config: CodeshiftConfig | undefined;
52-
53-
[
54-
path.join(info?.location, 'codeshift.config.js'),
55-
path.join(info?.location, 'codeshift.config.ts'),
56-
path.join(info?.location, 'src', 'codeshift.config.js'),
57-
path.join(info?.location, 'src', 'codeshift.config.ts'),
58-
path.join(info?.location, 'codemods', 'codeshift.config.js'),
59-
path.join(info?.location, 'codemods', 'codeshift.config.ts'),
60-
].forEach(searchPath => {
61-
try {
62-
// eslint-disable-next-line @typescript-eslint/no-var-requires
63-
const pkg = require(searchPath);
64-
const searchConfig: CodeshiftConfig = pkg.default ? pkg.default : pkg;
65-
66-
if (isValidConfig(searchConfig)) {
67-
config = searchConfig;
68-
}
69-
} catch (e) {}
70-
});
71-
72-
if (config) return config;
73-
}
74-
75-
throw new Error(
76-
`Unable to locate a valid codeshift.config in package ${packageName}`,
77-
);
16+
function getCodeshiftPackageName(packageName: string) {
17+
return `@codeshift/mod-${packageName.replace('@', '').replace('/', '__')}`;
7818
}
7919

8020
export default async function main(paths: string[], flags: Flags) {
@@ -109,30 +49,47 @@ export default async function main(paths: string[], flags: Flags) {
10949
const pkgName =
11050
shouldPrependAtSymbol + pkg.split(/[@#]/).filter(str => !!str)[0];
11151

112-
let communityConfig;
113-
let remoteConfig;
114-
11552
console.log(chalk.green('Attempting to download package:'), pkgName);
11653

54+
let codeshiftConfig: CodeshiftConfig | undefined;
55+
let remoteConfig: CodeshiftConfig | undefined;
56+
11757
try {
118-
communityConfig = await fetchCommunityPackageConfig(
119-
pkgName,
58+
codeshiftConfig = await fetchPackage(
59+
getCodeshiftPackageName(pkgName),
12060
packageManager,
12161
);
12262
} catch (error) {}
12363

12464
try {
125-
remoteConfig = await fetchRemotePackageConfig(pkgName, packageManager);
65+
remoteConfig = await fetchRemotePackage(pkgName, packageManager);
12666
} catch (error) {}
12767

128-
if (!communityConfig && !remoteConfig) {
68+
if (!codeshiftConfig && !remoteConfig) {
12969
throw new Error(
130-
`Unable to locate package from the codeshift-community packages or as a standalone NPM package.
131-
Make sure the package name ${pkgName} has been spelled correctly and exists before trying again.`,
70+
`Unable to locate package from codeshift-community or NPM.
71+
Make sure the package name "${pkgName}" is correct and try again.`,
72+
);
73+
}
74+
75+
if (codeshiftConfig) {
76+
console.log(
77+
chalk.green(`Found codeshift package:`),
78+
getCodeshiftPackageName(pkgName),
13279
);
13380
}
13481

135-
const config: CodeshiftConfig = merge({}, communityConfig, remoteConfig);
82+
if (remoteConfig) {
83+
console.log(chalk.green(`Found codeshift package:`), pkgName);
84+
}
85+
86+
const config: CodeshiftConfig = merge({}, remoteConfig, codeshiftConfig);
87+
88+
if (!isValidConfig(config)) {
89+
throw new Error(
90+
`Unable to locate a valid codeshift.config in package ${pkgName}`,
91+
);
92+
}
13693

13794
const rawTransformIds = pkg.split(/(?=[@#])/).filter(str => !!str);
13895
rawTransformIds.shift();

packages/fetcher/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# @codeshift/fetcher

packages/fetcher/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# @codeshift/fetcher
2+
3+
Responsible for fetching codemod packages and associated files.

packages/fetcher/package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "@codeshift/fetcher",
3+
"version": "0.0.1",
4+
"main": "dist/codeshift-fetcher.cjs.js",
5+
"types": "dist/codeshift-fetcher.cjs.d.ts",
6+
"license": "MIT",
7+
"repository": "https://github.com/CodeshiftCommunity/CodeshiftCommunity/tree/master/packages/fetcher",
8+
"dependencies": {
9+
"@codeshift/types": "*",
10+
"chalk": "^4.1.0",
11+
"fs-extra": "^9.1.0",
12+
"globby": "^11.1.0",
13+
"live-plugin-manager": "^0.15.1",
14+
"ts-node": "^9.1.1"
15+
}
16+
}

0 commit comments

Comments
 (0)