Skip to content

Commit b316132

Browse files
committed
🔨 Initialiser now properly supports preset creation
1 parent 8b264de commit b316132

File tree

10 files changed

+93
-64
lines changed

10 files changed

+93
-64
lines changed

.changeset/selfish-donkeys-deny.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@codeshift/cli': minor
3+
---
4+
5+
CLI Init command now supports the ability to create a stub preset

packages/cli/src/errors.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
export class ValidationError extends Error {}
21
export class NoTransformsExistError extends Error {}
32
export class InvalidUserInputError extends Error {}

packages/cli/src/index.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,15 @@ import main from './main';
33
import list from './list';
44
import init from './init';
55
import validate from './validate';
6-
import {
7-
ValidationError,
8-
NoTransformsExistError,
9-
InvalidUserInputError,
10-
} from './errors';
6+
import { NoTransformsExistError, InvalidUserInputError } from './errors';
117

128
import packageJson from '../package.json';
13-
import { Command, Option } from 'commander';
9+
import { Command, Option, CommanderError } from 'commander';
1410

1511
const program = new Command();
1612

1713
program
18-
.command(`${packageJson.name} [path...]`, { isDefault: true })
14+
.command(`codeshift/cli [path...]`, { isDefault: true })
1915
.version(packageJson.version, '-v, --version')
2016
.usage('[global options] <file-paths>...')
2117
.option(
@@ -103,24 +99,27 @@ Examples:
10399

104100
program.exitOverride();
105101

106-
program.parseAsync(process.argv).catch(e => {
107-
if (e instanceof ValidationError) {
108-
console.error(program.help());
109-
console.error(chalk.red(e.message));
110-
process.exit(1);
102+
try {
103+
program.parse(process.argv);
104+
} catch (error) {
105+
if (error instanceof CommanderError) {
106+
console.log(error);
107+
108+
console.error(chalk.red(error.message));
109+
process.exit(error.exitCode);
111110
}
112111

113-
if (e instanceof InvalidUserInputError) {
112+
if (error instanceof InvalidUserInputError) {
114113
console.warn(program.help());
115-
console.warn(chalk.red(e.message));
114+
console.warn(chalk.red(error.message));
116115
process.exit(9);
117116
}
118117

119-
if (e instanceof NoTransformsExistError) {
120-
console.warn(chalk.yellow(e.message));
118+
if (error instanceof NoTransformsExistError) {
119+
console.warn(chalk.yellow(error.message));
121120
process.exit(0);
122121
}
123122

124-
console.error(chalk.red(e));
123+
console.error(chalk.red(error));
125124
process.exit(3);
126-
});
125+
}

packages/cli/src/init.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@ import { initDirectory } from '@codeshift/initializer';
22

33
export default async function init(
44
packageName: string,
5-
version: string,
5+
transform?: string,
6+
preset?: string,
67
targetPath: string = '.',
78
) {
8-
initDirectory(packageName, version, targetPath);
9+
if (transform) {
10+
initDirectory(packageName, transform, 'version', targetPath);
11+
}
12+
13+
if (preset) {
14+
initDirectory(packageName, preset, 'preset', targetPath);
15+
}
916

1017
console.log(
1118
`🚚 New codemod package created at: ${targetPath}/${packageName}`,

packages/initializer/src/index.ts

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ export function getPackageJson(packageName: string, version: string = '0.0.0') {
1414
build: 'tsc --build',
1515
test: 'jest',
1616
},
17-
dependencies: {
18-
'@codeshift/utils': `^${utilVersion}`,
19-
},
17+
dependencies: {},
2018
devDependencies: {
19+
'@codeshift/utils': `^${utilVersion}`,
2120
'@codeshift/test-utils': '*',
21+
'@types/node': '^16.11.0',
2222
'@types/jest': '^26.0.15',
2323
jest: '^26.6.0',
2424
jscodeshift: '^0.12.0',
@@ -32,46 +32,60 @@ export function getPackageJson(packageName: string, version: string = '0.0.0') {
3232
);
3333
}
3434

35-
function getConfig(packageName: string, version: string) {
36-
return `export default {
35+
function getConfig(packageName: string, transform?: string, preset?: string) {
36+
return `module.exports = {
3737
maintainers: [],
3838
target: [],
3939
description: 'Codemods for ${packageName}',
40-
transforms: {
41-
'${version}': require('./${version}/transform'),
42-
},
43-
presets: {},
40+
transforms: {${
41+
transform
42+
? `'${transform}': require.resolve('./${transform}/transform'),`
43+
: ''
44+
}},
45+
presets: {${
46+
preset ? `'${preset}': require.resolve('./${preset}/transform'),` : ''
47+
}},
4448
};
4549
`;
4650
}
4751

48-
function updateConfig(path: string, packageName: string, version: string) {
52+
function updateConfig(
53+
path: string,
54+
packageName: string,
55+
transformName: string,
56+
type: 'version' | 'preset',
57+
) {
4958
const source = fs.readFileSync(path, 'utf8');
5059
const ast = recast.parse(source);
5160
const b = recast.types.builders;
61+
const key = type === 'version' ? 'transforms' : 'presets';
5262

5363
recast.visit(ast, {
5464
visitProperty(path) {
5565
// @ts-ignore
56-
if (path.node.key.name !== 'transforms') return false;
66+
if (path.node.key.name !== key) return false;
5767
// @ts-ignore
5868
const properties = path.node.value.properties;
5969
// @ts-ignore
6070
properties.forEach(property => {
61-
if (semver.eq(property.key.value, version)) {
71+
if (property.key.value === transformName) {
6272
throw new Error(
63-
`Transform for ${packageName} version ${version} already exists`,
73+
`Transform for ${packageName} ${transformName} already exists`,
6474
);
6575
}
6676
});
6777

6878
properties.push(
6979
b.property(
7080
'init',
71-
b.stringLiteral(version),
72-
b.callExpression(b.identifier('require'), [
73-
b.stringLiteral(`./${version}/transform`),
74-
]),
81+
b.stringLiteral(transformName),
82+
b.callExpression(
83+
b.memberExpression(
84+
b.identifier('require'),
85+
b.identifier('resolve'),
86+
),
87+
[b.stringLiteral(`./${transformName}/transform`)],
88+
),
7589
),
7690
);
7791

@@ -84,46 +98,51 @@ function updateConfig(path: string, packageName: string, version: string) {
8498

8599
export function initDirectory(
86100
packageName: string,
87-
version: string,
88-
targetPath: string = './',
101+
transform: string,
102+
type: 'version' | 'preset',
103+
path: string = './',
89104
isReduced: boolean = false,
90105
) {
91-
if (!semver.valid(version)) {
106+
if (type === 'version' && !semver.valid(transform)) {
92107
throw new Error(
93-
`Provided version ${version} is not a valid semver version`,
108+
`Provided version ${transform} is not a valid semver version`,
94109
);
95110
}
96111

97-
const basePath = `${targetPath}/${packageName.replace('/', '__')}`;
98-
const codemodPath = `${basePath}${!isReduced ? '/src/' : ''}/${version}`;
112+
const basePath = `${path}/${packageName.replace('/', '__')}`;
113+
const transformPath = `${basePath}${!isReduced ? '/src/' : ''}/${transform}`;
99114
const configPath = `${basePath}${
100115
!isReduced ? '/src' : ''
101116
}/codeshift.config.ts`;
102117

103-
if (fs.existsSync(codemodPath)) {
104-
throw new Error(`Codemod for version "${version}" already exists`);
118+
if (fs.existsSync(transformPath)) {
119+
throw new Error(`Codemod for ${type} "${transform}" already exists`);
105120
}
106121

107122
fs.copySync(`${__dirname}/../template${isReduced ? '/src' : ''}`, basePath);
108-
fs.renameSync(`${basePath}${!isReduced ? '/src/' : ''}/codemod`, codemodPath);
123+
fs.renameSync(
124+
`${basePath}${!isReduced ? '/src/' : ''}/codemod`,
125+
transformPath,
126+
);
109127

110128
const testFile = fs
111-
.readFileSync(`${codemodPath}/transform.spec.ts`, 'utf8')
129+
.readFileSync(`${transformPath}/transform.spec.ts`, 'utf8')
112130
.replace('<% packageName %>', packageName)
113-
.replace('<% version %>', version);
131+
.replace('<% seperator %>', type === 'version' ? '@' : '#')
132+
.replace('<% transform %>', transform || '');
114133

115-
fs.writeFileSync(`${codemodPath}/transform.spec.ts`, testFile);
134+
fs.writeFileSync(`${transformPath}/transform.spec.ts`, testFile);
116135

117136
if (!isReduced) {
118137
fs.writeFileSync(`${basePath}/package.json`, getPackageJson(packageName));
119138
}
120139

121140
if (!fs.existsSync(configPath)) {
122-
fs.writeFileSync(configPath, getConfig(packageName, version));
141+
fs.writeFileSync(configPath, getConfig(packageName, transform));
123142
} else {
124143
fs.writeFileSync(
125144
configPath,
126-
updateConfig(configPath, packageName, version),
145+
updateConfig(configPath, packageName, transform || '', type),
127146
);
128147
}
129148
}
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
node_modules
21
src/
32
**/__test__
43
**/*.spec.(ts|js)
54
.vscode
65
jest.config.js
7-
tsconfig.json
8-
yarn-error.log

packages/initializer/template/jest.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ module.exports = {
22
transform: {
33
'^.+\\.ts$': 'ts-jest',
44
},
5-
moduleFileExtensions: ['ts', 'js'],
6-
testRegex: '^.+\\.spec\\.(ts|js)$',
5+
moduleFileExtensions: ['ts', 'tsx', 'js'],
6+
testRegex: '^.+\\.spec\\.(tsx|ts|js)$',
77
globals: {
88
'ts-jest': {
99
tsconfig: 'tsconfig.json',

packages/initializer/template/src/codemod/transform.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { applyTransform } from '@codeshift/test-utils';
22
import * as transformer from './transform';
33

4-
describe('<% packageName %>@<% version %> transform', () => {
4+
describe('<% packageName %><% seperator %><% transform %> transform', () => {
55
it('should transform correctly', () => {
66
const result = applyTransform(
77
transformer,

packages/initializer/template/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"compilerOptions": {
44
"outDir": "dist",
55
"esModuleInterop": true,
6-
"allowJs": true
6+
"allowJs": true,
7+
"types": ["jest", "node"]
78
}
89
}

scripts/initialize.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import { initDirectory } from '@codeshift/initializer';
22

3-
export function main(packageName: string, version: string) {
4-
const path = `${__dirname}/../community`;
3+
const targetPath = `${__dirname}/../community`;
54

5+
export function main(packageName: string, transform?: string) {
66
if (!packageName) throw new Error('Package name was not provided');
7-
if (!version) throw new Error('Version was not provided');
7+
if (!transform) throw new Error('Version was not provided');
88

9-
initDirectory(packageName, version, path, true);
9+
if (transform) {
10+
initDirectory(packageName, transform, 'version', targetPath);
11+
}
1012

1113
console.log(
12-
`🚚 New codemod package created at: community/${packageName}/${version}`,
14+
`🚚 New codemod package created at: community/${packageName}/${transform}`,
1315
);
1416
}
1517

0 commit comments

Comments
 (0)