Skip to content

Commit 598ec9e

Browse files
Merge pull request #119 from CodeshiftCommunity/refactor-init-logic
Refactor init logic
2 parents c9ae44d + b05fc3b commit 598ec9e

File tree

13 files changed

+105
-168
lines changed

13 files changed

+105
-168
lines changed

.github/workflows/release-all-codemods.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ jobs:
2222
- run: yarn install --frozen-lockfile
2323
- run: yarn validate
2424
- run: yarn test
25-
- run: yarn validate:codemods
26-
- run: yarn release-all:codemods
25+
- run: yarn community:validate
26+
- run: yarn community:release-all
2727
env:
2828
CI: true
2929
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/release-codemods.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ jobs:
2424
- run: yarn install --frozen-lockfile
2525
- run: yarn validate
2626
- run: yarn test
27-
- run: yarn validate:codemods
28-
- run: yarn release:codemods
27+
- run: yarn community:validate
28+
- run: yarn community:release
2929
env:
3030
CI: true
3131
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/validate-codmods.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
with:
2020
node-version: ${{ matrix.node-version }}
2121
- run: yarn install --frozen-lockfile
22-
- run: yarn validate:codemods
22+
- run: yarn community:validate
2323
env:
2424
CI: true
2525
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@
2424
"monorepo:fix": "manypkg fix && preconstruct fix",
2525
"cli:start": "node packages/cli/bin/codeshift-cli.js",
2626
"cli:validate": "node packages/cli/bin/codeshift-cli.js validate",
27+
"cli:init": "node packages/cli/bin/codeshift-cli.js init",
2728
"cli:list": "node packages/cli/bin/codeshift-cli.js list",
28-
"init:codemods": "ts-node scripts/initialize.ts",
29-
"validate:codemods": "ts-node scripts/validate.ts ./community",
30-
"release:codemods": "ts-node scripts/publish.ts ./community .tmp",
31-
"release-all:codemods": "ts-node scripts/publish-all.ts ./community .tmp",
32-
"release-all-dry:codemods": "ts-node scripts/publish-all-dry.ts ./community .tmp",
29+
"community:init": "ts-node scripts/initialize.ts",
30+
"community:validate": "ts-node scripts/validate.ts ./community",
31+
"community:release": "ts-node scripts/publish.ts ./community .tmp",
32+
"community:release-all": "ts-node scripts/publish-all.ts ./community .tmp",
33+
"community:release-all-dry": "ts-node scripts/publish-all-dry.ts ./community .tmp",
3334
"prerelease": "yarn validate && yarn test",
3435
"release": "yarn changeset publish"
3536
},

packages/cli/src/index.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,24 +94,30 @@ Examples:
9494
program
9595
.command('init [path]')
9696
.description('creates a new codeshift package')
97-
.requiredOption('--package-name <value>', 'Name of the package')
97+
.option('-c, --config-only', 'Output only a configuration file')
9898
.option('-t, --transform <value>', 'Transform version')
9999
.option('-p, --preset <value>', 'Preset transfrom')
100100
.action((path, options) =>
101-
init(options.packageName, options.transform, options.preset, path),
101+
init(options.transform, options.preset, options.configOnly, path),
102102
)
103103
.addHelpText(
104104
'after',
105105
`
106106
Examples:
107-
# Initializes an empty codeshift package at the ~/Desktop directory
108-
$ codeshift init --package-name foobar --transform 10.0.0 ~/Desktop
107+
# Initializes an empty codeshift package at the current directory
108+
$ codeshift init --transform 10.0.0 my-codemod-package
109109
110-
# Initializes a new codeshift package with a transform for 10.0.0
111-
$ codeshift init --package-name foobar --transform 10.0.0 ~/Desktop
110+
# Initializes an empty codeshift package at the current directory
111+
$ codeshift init --transform 10.0.0 .
112+
113+
# Initializes a new codeshift package with a transform for 10.0.0 at the foobar dir
114+
$ codeshift init --transform 10.0.0 ~/foobar
112115
113116
# Initializes a new codeshift package with a preset "update-imports"
114-
$ codeshift init --package-name foobar --preset update-imports ~/Desktop`,
117+
$ codeshift init --package-name foobar --preset update-imports foobar
118+
119+
# Initializes a configuration file only
120+
$ codeshift init --config-only --preset update-imports path/to/src`,
115121
);
116122

117123
program

packages/cli/src/init.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
import path from 'path';
2-
import { initDirectory, initTransform } from '@codeshift/initializer';
2+
import chalk from 'chalk';
3+
import {
4+
initConfig,
5+
initDirectory,
6+
initTransform,
7+
} from '@codeshift/initializer';
38

49
export default async function init(
5-
packageName: string,
610
transform?: string,
711
preset?: string,
12+
configOnly?: boolean,
813
targetPath = '.',
914
) {
10-
initDirectory(packageName, targetPath);
15+
const packageName =
16+
targetPath !== '.' ? path.basename(targetPath) : 'codeshift-community';
17+
18+
if (configOnly) {
19+
initConfig(packageName, targetPath);
20+
} else {
21+
initDirectory(packageName, targetPath);
22+
}
1123

1224
if (transform) initTransform(packageName, transform, 'version', targetPath);
1325
if (preset) initTransform(packageName, preset, 'preset', targetPath);
1426

15-
console.log(
16-
`🚚 New codemod package created at: ${path.join(targetPath, packageName)}`,
17-
);
27+
console.log(chalk.green(`🚚 New codemod package created at: ${targetPath}`));
1828
}

packages/cli/src/validate.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { isValidConfigAtPath, isValidPackageJson } from '@codeshift/validator';
1+
import chalk from 'chalk';
2+
3+
import { isValidConfigAtPath } from '@codeshift/validator';
24

35
export default async function validate(targetPath = '.') {
46
await isValidConfigAtPath(targetPath);
5-
await isValidPackageJson(targetPath);
67

7-
console.log('Valid ✅');
8+
console.log(chalk.green('Valid ✅'));
89
}

packages/initializer/src/index.ts

Lines changed: 44 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jest.config.js
4747
function getConfig(packageName: string, transform?: string, preset?: string) {
4848
return `module.exports = {
4949
maintainers: [],
50-
target: [],
50+
targets: [],
5151
description: 'Codemods for ${packageName}',
5252
transforms: {${
5353
transform
@@ -62,22 +62,24 @@ function getConfig(packageName: string, transform?: string, preset?: string) {
6262
}
6363

6464
function updateConfig(
65-
path: string,
65+
targetPath: string,
6666
packageName: string,
6767
transformName: string,
6868
type: 'version' | 'preset',
69+
isReduced = false,
6970
) {
70-
const source = fs.readFileSync(path, 'utf8');
71+
const configPath = path.join(targetPath, 'codeshift.config.js');
72+
const source = fs.readFileSync(configPath, 'utf8');
7173
const ast = recast.parse(source);
7274
const b = recast.types.builders;
7375
const key = type === 'version' ? 'transforms' : 'presets';
7476

7577
recast.visit(ast, {
76-
visitProperty(path) {
78+
visitProperty(propertyPath) {
7779
// @ts-ignore
78-
if (path.node.key.name !== key) return false;
80+
if (propertyPath.node.key.name !== key) return false;
7981
// @ts-ignore
80-
const properties = path.node.value.properties;
82+
const properties = propertyPath.node.value.properties;
8183
// @ts-ignore
8284
properties.forEach(property => {
8385
if (property.key.value === transformName) {
@@ -87,6 +89,10 @@ function updateConfig(
8789
}
8890
});
8991

92+
const transformPath = `./${
93+
!isReduced ? 'src/' : ''
94+
}${transformName}/transform`;
95+
9096
properties.push(
9197
b.property(
9298
'init',
@@ -96,7 +102,7 @@ function updateConfig(
96102
b.identifier('require'),
97103
b.identifier('resolve'),
98104
),
99-
[b.stringLiteral(`./${transformName}/transform`)],
105+
[b.stringLiteral(transformPath)],
100106
),
101107
),
102108
);
@@ -105,41 +111,47 @@ function updateConfig(
105111
},
106112
});
107113

108-
return recast.prettyPrint(ast, { quote: 'single', trailingComma: true }).code;
114+
fs.writeFileSync(
115+
configPath,
116+
recast.prettyPrint(ast, {
117+
quote: 'single',
118+
trailingComma: true,
119+
tabWidth: 2,
120+
}).code,
121+
);
122+
}
123+
124+
export function initConfig(packageName: string, targetPath = './') {
125+
const configPath = path.join(targetPath, 'codeshift.config.js');
126+
127+
if (!fs.existsSync(configPath)) {
128+
fs.writeFileSync(configPath, getConfig(packageName));
129+
}
109130
}
110131

111132
export function initDirectory(
112133
packageName: string,
113134
targetPath = './',
114135
isReduced = false,
115136
) {
116-
const basePath = path.join(targetPath, packageName.replace('/', '__'));
117-
const configPath = path.join(
118-
basePath,
119-
!isReduced ? 'src' : '',
120-
'codeshift.config.js',
121-
);
122-
123137
fs.copySync(
124138
path.join(__dirname, '..', 'template', isReduced ? 'src' : ''),
125-
basePath,
139+
targetPath,
126140
{
127141
filter: src => !src.includes('src/codemod'),
128142
},
129143
);
130144

131145
if (!isReduced) {
132146
fs.writeFileSync(
133-
path.join(basePath, 'package.json'),
147+
path.join(targetPath, 'package.json'),
134148
getPackageJson(packageName),
135149
);
136150

137-
fs.writeFileSync(path.join(basePath, '.npmignore'), getNpmIgnore());
151+
fs.writeFileSync(path.join(targetPath, '.npmignore'), getNpmIgnore());
138152
}
139153

140-
if (!fs.existsSync(configPath)) {
141-
fs.writeFileSync(configPath, getConfig(packageName));
142-
}
154+
initConfig(packageName, targetPath);
143155
}
144156

145157
export function initTransform(
@@ -153,26 +165,23 @@ export function initTransform(
153165
throw new Error(`Provided version ${id} is not a valid semver version`);
154166
}
155167

156-
const basePath = path.join(targetPath, packageName.replace('/', '__'));
157-
const transformPath = path.join(basePath, !isReduced ? 'src' : '', id);
158-
const configPath = path.join(
159-
basePath,
160-
!isReduced ? 'src' : '',
161-
'codeshift.config.js',
162-
);
168+
const transformPath = path.join(targetPath, !isReduced ? 'src' : '', id);
163169

164170
if (fs.existsSync(transformPath)) {
165171
throw new Error(`Codemod for ${type} "${id}" already exists`);
166172
}
167173

168-
fs.copySync(
169-
path.join(__dirname, '..', 'template', isReduced ? 'src' : ''),
170-
basePath,
174+
const codemodTemplateDestinationPath = path.join(
175+
targetPath,
176+
!isReduced ? 'src' : '',
177+
'codemod',
171178
);
172-
fs.renameSync(
173-
path.join(basePath, !isReduced ? 'src' : '', 'codemod'),
174-
transformPath,
179+
180+
fs.copySync(
181+
path.join(__dirname, '..', 'template', 'src', 'codemod'),
182+
codemodTemplateDestinationPath,
175183
);
184+
fs.renameSync(codemodTemplateDestinationPath, transformPath);
176185

177186
const testFilePath = path.join(transformPath, 'transform.spec.ts');
178187
const testFile = fs
@@ -183,15 +192,5 @@ export function initTransform(
183192

184193
fs.writeFileSync(testFilePath, testFile);
185194

186-
if (!isReduced) {
187-
fs.writeFileSync(
188-
path.join(basePath, 'package.json'),
189-
getPackageJson(packageName),
190-
);
191-
}
192-
193-
fs.writeFileSync(
194-
configPath,
195-
updateConfig(configPath, packageName, id || '', type),
196-
);
195+
updateConfig(targetPath, packageName, id || '', type, isReduced);
197196
}

packages/validator/src/index.spec.ts

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
jest.mock('fs-extra');
22
jest.mock('@codeshift/fetcher');
33

4-
import fs from 'fs-extra';
5-
64
import { fetchConfig } from '@codeshift/fetcher';
75

8-
import {
9-
isValidPackageName,
10-
isValidConfig,
11-
isValidConfigAtPath,
12-
isValidPackageJson,
13-
} from '.';
6+
import { isValidPackageName, isValidConfig, isValidConfigAtPath } from '.';
147

158
describe('validator', () => {
169
describe('isValidPackageName', () => {
@@ -173,54 +166,4 @@ Please make sure all presets are kebab case and contain no spaces or special cha
173166
);
174167
});
175168
});
176-
177-
describe('isValidPackageJson', () => {
178-
afterEach(() => jest.resetAllMocks());
179-
180-
it('should detect valid package.json', async () => {
181-
(fs.readFile as jest.Mock).mockReturnValue(`{
182-
"name": "codeshift-package",
183-
"main": "dist/index.js",
184-
"version": "0.0.1"
185-
}`);
186-
187-
const result = await isValidPackageJson('path/to/');
188-
expect(result).toEqual(true);
189-
expect(fs.readFile).toHaveBeenCalledWith('path/to/package.json', 'utf8');
190-
});
191-
192-
it('should detect invalid package.json', async () => {
193-
expect.assertions(2);
194-
195-
{
196-
(fs.readFile as jest.Mock).mockReturnValue(`{
197-
"name": "codeshift-package"
198-
}`);
199-
200-
try {
201-
await isValidPackageJson('path/to/');
202-
} catch (error) {
203-
// @ts-ignore
204-
expect(error.message).toMatch(
205-
'No main entrypoint provided in package.json',
206-
);
207-
}
208-
}
209-
210-
{
211-
(fs.readFile as jest.Mock).mockReturnValue(`{
212-
"main": "dist/index.js"
213-
}`);
214-
215-
try {
216-
await isValidPackageJson('path/to/');
217-
} catch (error) {
218-
// @ts-ignore
219-
expect(error.message).toMatch(
220-
'No package name provided in package.json',
221-
);
222-
}
223-
}
224-
});
225-
});
226169
});

0 commit comments

Comments
 (0)