Skip to content

Commit 3dd1e8e

Browse files
authored
Merge pull request #45 from ssutar/master
Add support for passing options to jscodeshift
2 parents fd6ce79 + dd57dba commit 3dd1e8e

6 files changed

Lines changed: 129 additions & 6 deletions

File tree

commands/local/generate/codemod.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ module.exports.handler = function handler(options) {
2121
`${codemodDir}/index.js`,
2222
stripIndent`
2323
const { getParser } = require('codemod-cli').jscodeshift;
24+
const { getOptions } = require('codemod-cli');
2425
2526
module.exports = function transformer(file, api) {
2627
const j = getParser(api);
28+
const options = getOptions();
2729
2830
return j(file.source)
2931
.find(j.Identifier)

src/bin-support.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
'use strict';
22

3-
function runTransform(binRoot, transformName, paths) {
3+
function runTransform(binRoot, transformName, args) {
44
const globby = require('globby');
55
const execa = require('execa');
66
const chalk = require('chalk');
77
const path = require('path');
8+
const { parseTransformArgs } = require('./options-support');
9+
10+
let { paths, options } = parseTransformArgs(args);
811

912
return globby(paths)
1013
.then(paths => {
@@ -16,6 +19,9 @@ function runTransform(binRoot, transformName, paths) {
1619

1720
return execa(binPath, ['-t', transformPath, '--extensions', 'js,ts', ...paths], {
1821
stdio: 'inherit',
22+
env: {
23+
CODEMOD_CLI_ARGS: JSON.stringify(options),
24+
},
1925
});
2026
})
2127
.catch(error => {

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
const TestSupport = require('./test-support');
44
const BinSupport = require('./bin-support');
55
const TransformSupport = require('./transform-support');
6+
const OptionsSupport = require('./options-support');
67

78
module.exports = {
89
runTransformTest: TestSupport.runTransformTest,
910
runTransform: BinSupport.runTransform,
1011
jscodeshift: TransformSupport.jscodeshift,
12+
getOptions: OptionsSupport.getOptions,
1113
};

src/options-support.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const yargs = require('yargs');
2+
3+
function parseTransformArgs(args) {
4+
let parsedArgs = yargs.parse(args);
5+
let paths = parsedArgs._;
6+
let options = Object.keys(parsedArgs).reduce((acc, key) => {
7+
if (!['_', '$0', 'help', 'version'].includes(key)) {
8+
acc[key] = parsedArgs[key];
9+
}
10+
return acc;
11+
}, {});
12+
return { paths, options };
13+
}
14+
15+
function getOptions() {
16+
try {
17+
return JSON.parse(process.env.CODEMOD_CLI_ARGS);
18+
} catch (e) {
19+
return {};
20+
}
21+
}
22+
23+
module.exports = { parseTransformArgs, getOptions };

src/test-support.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
/* global it, describe */
3+
/* global it, describe, beforeEach, afterEach */
44

55
const { runInlineTest } = require('jscodeshift/dist/testUtils');
66
const fs = require('fs-extra');
@@ -36,8 +36,18 @@ function jscodeshiftTest(options) {
3636
let testName = filename.replace(`.input${extension}`, '');
3737
let inputPath = path.join(details.fixtureDir, `${testName}.input${extension}`);
3838
let outputPath = path.join(details.fixtureDir, `${testName}.output${extension}`);
39+
let optionsPath = path.join(details.fixtureDir, `${testName}.options.json`);
40+
let options = fs.pathExistsSync(optionsPath) ? fs.readFileSync(optionsPath) : '{}';
3941

4042
describe(testName, function() {
43+
beforeEach(function() {
44+
process.env.CODEMOD_CLI_ARGS = options;
45+
});
46+
47+
afterEach(function() {
48+
process.env.CODEMOD_CLI_ARGS = '';
49+
});
50+
4151
it('transforms correctly', function() {
4252
runInlineTest(
4353
transform,

tests/cli-test.js

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,46 @@ QUnit.module('codemod-cli', function(hooks) {
186186
})
187187
);
188188

189+
QUnit.test(
190+
'transform should receive options from ${name}.options.json',
191+
wrap(function*(assert) {
192+
const expectedReplacement = 'AAAAHHHHHH';
193+
194+
yield execa(EXECUTABLE_PATH, ['generate', 'codemod', 'main']);
195+
196+
codemodProject.write({
197+
transforms: {
198+
main: {
199+
'index.js': `
200+
const { getParser } = require('codemod-cli').jscodeshift;
201+
const { getOptions } = require('codemod-cli');
202+
module.exports = function transformer(file, api) {
203+
const options = getOptions();
204+
const j = getParser(api);
205+
return j(file.source)
206+
.find(j.Literal)
207+
.forEach(path => {
208+
path.replace(
209+
j.stringLiteral(options.replaceAll)
210+
);
211+
})
212+
.toSource();
213+
}
214+
`,
215+
__testfixtures__: {
216+
'basic.input.js': 'var foo = "foo";',
217+
'basic.output.js': `var foo = "${expectedReplacement}";`,
218+
'basic.options.json': `{ "replaceAll": "${expectedReplacement}" }`,
219+
},
220+
},
221+
},
222+
});
223+
224+
let result = yield execa(EXECUTABLE_PATH, ['test']);
225+
assert.equal(result.code, 0, 'exited with zero');
226+
})
227+
);
228+
189229
QUnit.test(
190230
'transform should receive a file path in tests',
191231
wrap(function*(assert) {
@@ -295,10 +335,7 @@ QUnit.module('codemod-cli', function(hooks) {
295335
'works with globs',
296336
wrap(function*(assert) {
297337
userProject.write({
298-
foo: {
299-
'something.js': 'let blah = bar',
300-
'other.js': 'let blah = bar',
301-
},
338+
foo: { 'something.js': 'let blah = bar', 'other.js': 'let blah = bar' },
302339
});
303340

304341
yield execa(codemodProject.path('bin/cli.js'), ['main', 'foo/*thing.js']);
@@ -356,6 +393,49 @@ QUnit.module('codemod-cli', function(hooks) {
356393
})
357394
);
358395

396+
QUnit.test(
397+
'runs transform with options',
398+
wrap(function*(assert) {
399+
codemodProject.write({
400+
transforms: {
401+
main: {
402+
'index.js': `
403+
const { getParser } = require('codemod-cli').jscodeshift;
404+
const { getOptions } = require('codemod-cli');
405+
module.exports = function transformer(file, api) {
406+
const options = getOptions();
407+
const j = getParser(api);
408+
return j(file.source)
409+
.find(j.Literal)
410+
.forEach(path => {
411+
path.replace(
412+
j.stringLiteral(options.biz + options.baz)
413+
);
414+
})
415+
.toSource();
416+
}
417+
`,
418+
},
419+
},
420+
});
421+
userProject.write({
422+
foo: { 'something.js': `let blah = "bar";` },
423+
});
424+
425+
yield CodemodCLI.runTransform(codemodProject.path('bin'), 'main', [
426+
'--biz',
427+
'A',
428+
'--baz',
429+
'B',
430+
'foo/*ing.[jt]s',
431+
]);
432+
433+
assert.deepEqual(userProject.read(), {
434+
foo: { 'something.js': `let blah = "AB";` },
435+
});
436+
})
437+
);
438+
359439
QUnit.test(
360440
'runs transform against class syntax',
361441
wrap(function*(assert) {

0 commit comments

Comments
 (0)