Skip to content

Commit ebf2a44

Browse files
committed
Create fetcher package and refactor main CLI module
1 parent b35609d commit ebf2a44

File tree

10 files changed

+113
-80
lines changed

10 files changed

+113
-80
lines changed

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ describe('main', () => {
537537
install: jest.fn().mockResolvedValue(undefined),
538538
require: jest.fn().mockImplementation((codemodName: string) => {
539539
if (codemodName.startsWith('@codeshift')) {
540-
throw new Error('Attempted to fetch codemod from community folder');
540+
return {};
541541
}
542542

543543
return {

packages/cli/src/main.ts

Lines changed: 32 additions & 78 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,44 @@ 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
);
62+
remoteConfig = await fetchRemotePackage(pkgName, packageManager);
12263
} catch (error) {}
12364

124-
try {
125-
remoteConfig = await fetchRemotePackageConfig(pkgName, packageManager);
126-
} catch (error) {}
127-
128-
if (!communityConfig && !remoteConfig) {
65+
if (!codeshiftConfig && !remoteConfig) {
12966
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.`,
67+
`Unable to locate package from codeshift-community or NPM.
68+
Make sure the package name "${pkgName}" is correct and try again.`,
13269
);
13370
}
13471

135-
const config: CodeshiftConfig = merge({}, communityConfig, remoteConfig);
72+
if (codeshiftConfig) {
73+
console.log(
74+
chalk.green(`Found codeshift package:`),
75+
getCodeshiftPackageName(pkgName),
76+
);
77+
}
78+
79+
if (remoteConfig) {
80+
console.log(chalk.green(`Found codeshift package:`), pkgName);
81+
}
82+
83+
const config: CodeshiftConfig = merge({}, remoteConfig, codeshiftConfig);
84+
85+
if (!isValidConfig(config)) {
86+
throw new Error(
87+
`Unable to locate a valid codeshift.config in package ${pkgName}`,
88+
);
89+
}
13690

13791
const rawTransformIds = pkg.split(/(?=[@#])/).filter(str => !!str);
13892
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: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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+
"live-plugin-manager": "^0.15.1",
13+
"ts-node": "^9.1.1"
14+
}
15+
}

packages/fetcher/src/index.spec.ts

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

packages/fetcher/src/index.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import path from 'path';
2+
import { PluginManager } from 'live-plugin-manager';
3+
4+
import { CodeshiftConfig } from '@codeshift/types';
5+
6+
export function fetchConfig(filePath: string): CodeshiftConfig | undefined {
7+
let config: CodeshiftConfig | undefined;
8+
9+
[
10+
path.join(filePath, 'codeshift.config.js'),
11+
path.join(filePath, 'codeshift.config.ts'),
12+
path.join(filePath, 'src', 'codeshift.config.js'),
13+
path.join(filePath, 'src', 'codeshift.config.ts'),
14+
path.join(filePath, 'codemods', 'codeshift.config.js'),
15+
path.join(filePath, 'codemods', 'codeshift.config.ts'),
16+
].forEach(searchPath => {
17+
try {
18+
// eslint-disable-next-line @typescript-eslint/no-var-requires
19+
const pkg = require(searchPath);
20+
const searchConfig = pkg.default ? pkg.default : pkg;
21+
config = searchConfig;
22+
} catch (e) {}
23+
});
24+
25+
return config;
26+
}
27+
28+
export async function fetchPackage(
29+
packageName: string,
30+
packageManager: PluginManager,
31+
): Promise<CodeshiftConfig | undefined> {
32+
await packageManager.install(packageName);
33+
const pkg = packageManager.require(packageName);
34+
const config: CodeshiftConfig = pkg.default ? pkg.default : pkg;
35+
return config;
36+
}
37+
38+
export async function fetchRemotePackage(
39+
packageName: string,
40+
packageManager: PluginManager,
41+
): Promise<CodeshiftConfig | undefined> {
42+
let config = await fetchPackage(packageName, packageManager);
43+
44+
if (config) return config;
45+
46+
const info = packageManager.getInfo(packageName);
47+
48+
if (!info) return undefined;
49+
50+
return fetchConfig(info.location);
51+
}

0 commit comments

Comments
 (0)