Skip to content

Commit dd57dba

Browse files
author
Santosh Sutar
committed
Add support for providing options to jscodeshift
1 parent e192864 commit dd57dba

6 files changed

Lines changed: 93 additions & 12 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: 12 additions & 3 deletions
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');
@@ -37,12 +37,21 @@ function jscodeshiftTest(options) {
3737
let inputPath = path.join(details.fixtureDir, `${testName}.input${extension}`);
3838
let outputPath = path.join(details.fixtureDir, `${testName}.output${extension}`);
3939
let optionsPath = path.join(details.fixtureDir, `${testName}.options.json`);
40+
let options = fs.pathExistsSync(optionsPath) ? fs.readFileSync(optionsPath) : '{}';
4041

4142
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+
4251
it('transforms correctly', function() {
4352
runInlineTest(
4453
transform,
45-
fs.pathExistsSync(optionsPath) ? JSON.parse(fs.readFileSync(optionsPath)) : {},
54+
{},
4655
{ path: inputPath, source: fs.readFileSync(inputPath, 'utf8') },
4756
fs.readFileSync(outputPath, 'utf8')
4857
);
@@ -51,7 +60,7 @@ function jscodeshiftTest(options) {
5160
it('is idempotent', function() {
5261
runInlineTest(
5362
transform,
54-
fs.pathExistsSync(optionsPath) ? JSON.parse(fs.readFileSync(optionsPath)) : {},
63+
{},
5564
{ path: inputPath, source: fs.readFileSync(outputPath, 'utf8') },
5665
fs.readFileSync(outputPath, 'utf8')
5766
);

tests/cli-test.js

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ QUnit.module('codemod-cli', function(hooks) {
189189
QUnit.test(
190190
'transform should receive options from ${name}.options.json',
191191
wrap(function*(assert) {
192-
const realCodemodProjectPath = fs.realpathSync(codemodProject.path());
193192
const expectedReplacement = 'AAAAHHHHHH';
194193

195194
yield execa(EXECUTABLE_PATH, ['generate', 'codemod', 'main']);
@@ -199,10 +198,10 @@ QUnit.module('codemod-cli', function(hooks) {
199198
main: {
200199
'index.js': `
201200
const { getParser } = require('codemod-cli').jscodeshift;
202-
203-
module.exports = function transformer(file, api, options) {
201+
const { getOptions } = require('codemod-cli');
202+
module.exports = function transformer(file, api) {
203+
const options = getOptions();
204204
const j = getParser(api);
205-
206205
return j(file.source)
207206
.find(j.Literal)
208207
.forEach(path => {
@@ -336,10 +335,7 @@ QUnit.module('codemod-cli', function(hooks) {
336335
'works with globs',
337336
wrap(function*(assert) {
338337
userProject.write({
339-
foo: {
340-
'something.js': 'let blah = bar',
341-
'other.js': 'let blah = bar',
342-
},
338+
foo: { 'something.js': 'let blah = bar', 'other.js': 'let blah = bar' },
343339
});
344340

345341
yield execa(codemodProject.path('bin/cli.js'), ['main', 'foo/*thing.js']);
@@ -397,6 +393,49 @@ QUnit.module('codemod-cli', function(hooks) {
397393
})
398394
);
399395

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+
400439
QUnit.test(
401440
'runs transform against class syntax',
402441
wrap(function*(assert) {

0 commit comments

Comments
 (0)