Skip to content

Commit bd10e1c

Browse files
author
Robert Jackson
authored
Merge pull request #179 from rwjblue/cwd-options
2 parents 3715c74 + 1c77b97 commit bd10e1c

7 files changed

Lines changed: 109 additions & 17 deletions

File tree

commands/local/generate/codemod.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ module.exports.builder = function builder(yargs) {
66
.positional('codemod-name', {
77
describe: 'the name of the codemod to generate',
88
})
9+
.option('codemod-dir', {
10+
type: 'string',
11+
describe: 'the path to the transform directory',
12+
default: `./transforms/`,
13+
})
914
.option('type', {
1015
alias: 't',
1116
describe: 'choose the transform type',
@@ -16,13 +21,14 @@ module.exports.builder = function builder(yargs) {
1621

1722
function jsHandler(options) {
1823
const fs = require('fs-extra');
24+
const path = require('path');
1925
const { stripIndent } = require('common-tags');
2026
const importCwd = require('import-cwd');
2127
const generateFixture = require('./fixture').handler;
2228

2329
let { codemodName } = options;
2430
let projectName = importCwd('./package.json').name;
25-
let codemodDir = `${process.cwd()}/transforms/${codemodName}`;
31+
let codemodDir = path.join(options.codemodDir, codemodName);
2632

2733
fs.outputFileSync(
2834
`${codemodDir}/index.js`,
@@ -58,6 +64,8 @@ function jsHandler(options) {
5864
5965
runTransformTest({
6066
name: '${codemodName}',
67+
path: require.resolve('./index.js'),
68+
fixtureDir: \`\${__dirname}/__testfixtures__/\`,
6169
});
6270
`,
6371
'utf8'
@@ -94,7 +102,12 @@ function jsHandler(options) {
94102
'utf8'
95103
);
96104

97-
generateFixture({ codemodName, fixtureName: 'basic', type: options.type });
105+
generateFixture({
106+
codemodName,
107+
codemodDir: options.codemodDir,
108+
fixtureName: 'basic',
109+
type: options.type,
110+
});
98111
}
99112

100113
function hbsHandler(options) {
@@ -173,7 +186,12 @@ function hbsHandler(options) {
173186
'utf8'
174187
);
175188

176-
generateFixture({ codemodName, fixtureName: 'basic', type: options.type });
189+
generateFixture({
190+
codemodName,
191+
codemodDir: options.codemodDir,
192+
fixtureName: 'basic',
193+
type: options.type,
194+
});
177195
}
178196

179197
module.exports.handler = function handler(options) {

commands/local/generate/fixture.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,21 @@ module.exports.builder = function builder(yargs) {
88
})
99
.positional('fixture-name', {
1010
describe: 'the name of the fixture to generate',
11+
})
12+
.option('codemod-dir', {
13+
type: 'string',
14+
describe: 'the path to the transform directory',
15+
default: `./transforms/`,
1116
});
1217
};
1318

1419
module.exports.handler = function handler(options) {
1520
const fs = require('fs-extra');
21+
const path = require('path');
1622
const { getTransformType } = require('../../../src/transform-support');
1723

1824
let { codemodName, fixtureName } = options;
19-
let codemodDir = `${process.cwd()}/transforms/${codemodName}`;
25+
let codemodDir = path.resolve(process.cwd(), path.join(options.codemodDir, codemodName));
2026
let fixturePath = `${codemodDir}/__testfixtures__/${fixtureName}`;
2127

2228
let transformType = getTransformType(codemodDir);

src/bin-support.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22

33
const DEFAULT_JS_EXTENSIONS = 'js,ts';
44

5-
async function runJsTransform(root, transformName, args, extensions = DEFAULT_JS_EXTENSIONS) {
5+
async function runJsTransform(transformPath, args, extensions = DEFAULT_JS_EXTENSIONS) {
66
const globby = require('globby');
77
const execa = require('execa');
88
const chalk = require('chalk');
99
const path = require('path');
1010
const { parseTransformArgs } = require('./options-support');
11-
const { getTransformPath } = require('./transform-support');
1211

1312
let { paths, options, transformerOptions } = parseTransformArgs(args);
1413

@@ -17,7 +16,6 @@ async function runJsTransform(root, transformName, args, extensions = DEFAULT_JS
1716
expandDirectories: { extensions: extensions.split(',') },
1817
gitignore: true,
1918
});
20-
let transformPath = getTransformPath(root, transformName);
2119

2220
let jscodeshiftPkg = require('jscodeshift/package');
2321
let jscodeshiftPath = path.dirname(require.resolve('jscodeshift/package'));
@@ -46,17 +44,15 @@ async function runJsTransform(root, transformName, args, extensions = DEFAULT_JS
4644
}
4745
}
4846

49-
async function runTemplateTransform(root, transformName, args) {
47+
async function runTemplateTransform(transformPath, args) {
5048
const execa = require('execa');
5149
const chalk = require('chalk');
5250
const path = require('path');
5351
const { parseTransformArgs } = require('./options-support');
54-
const { getTransformPath } = require('./transform-support');
5552

5653
let { paths, options } = parseTransformArgs(args);
5754

5855
try {
59-
let transformPath = getTransformPath(root, transformName);
6056
let binOptions = ['-t', transformPath, ...paths];
6157
let templateRecastDir = path.dirname(require.resolve('ember-template-recast/package.json'));
6258
let templateRecastPkg = require('ember-template-recast/package');
@@ -86,9 +82,9 @@ async function runTransform(binRoot, transformName, args, extensions) {
8682

8783
switch (type) {
8884
case 'js':
89-
return runJsTransform(root, transformName, args, extensions);
85+
return runJsTransform(transformPath, args, extensions);
9086
case 'hbs':
91-
return runTemplateTransform(root, transformName, args);
87+
return runTemplateTransform(transformPath, args);
9288
default:
9389
throw new Error(`Unknown type passed to runTransform: "${type}"`);
9490
}

src/test-support.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ function testRunner(options, runTest) {
1818
cwd: details.fixtureDir,
1919
absolute: true,
2020
})
21-
.map((entry) =>
22-
entry.slice(entry.indexOf('__testfixtures__') + '__testfixtures__'.length + 1)
23-
)
21+
.map((entry) => entry.slice(details.fixtureDir.length))
2422
.forEach((filename) => {
2523
let extension = path.extname(filename);
2624
let testName = filename.replace(`.input${extension}`, '');

src/test-support/utils.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ function transformDetails(options) {
44
const { getTransformType, getTransformPath } = require('../transform-support');
55
const path = require('path');
66

7-
let transformPath = getTransformPath(process.cwd(), options.name);
7+
let transformPath = options.path ? options.path : getTransformPath(process.cwd(), options.name);
88
let root = path.dirname(transformPath);
99
let transformType = getTransformType(transformPath);
10+
let fixtureDir = options.fixtureDir ? options.fixtureDir : path.join(root, '__testfixtures__/');
1011

1112
return {
1213
name: options.name,
1314
root,
1415
transformPath,
1516
transformType,
16-
fixtureDir: path.join(root, '__testfixtures__/'),
17+
fixtureDir,
1718
};
1819
}
1920

src/transform-support.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
function getTransformPath(root, transformName) {
44
const path = require('path');
55

6+
// transformName **IS** a valid path, no need to resolve manually
7+
if (transformName.startsWith('.') || transformName.startsWith('/')) {
8+
return transformName;
9+
}
10+
611
return require.resolve(path.join(root, 'transforms', transformName));
712
}
813

tests/cli-test.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,27 @@ QUnit.module('codemod-cli', function (hooks) {
158158
]);
159159
});
160160

161+
QUnit.test('should generate a codemod in a custom directory', async function (assert) {
162+
let result = await execa(EXECUTABLE_PATH, [
163+
'generate',
164+
'codemod',
165+
'main',
166+
'--codemod-dir',
167+
'other-dir',
168+
]);
169+
170+
assert.equal(result.exitCode, 0, 'exited with zero');
171+
assert.deepEqual(walkSync(codemodProject.path('other-dir')), [
172+
'main/',
173+
'main/README.md',
174+
'main/__testfixtures__/',
175+
'main/__testfixtures__/basic.input.js',
176+
'main/__testfixtures__/basic.output.js',
177+
'main/index.js',
178+
'main/test.js',
179+
]);
180+
});
181+
161182
QUnit.test('should generate a hbs codemod', async function (assert) {
162183
let result = await execa(EXECUTABLE_PATH, ['generate', 'codemod', 'main', '--type', 'hbs']);
163184

@@ -237,6 +258,27 @@ QUnit.module('codemod-cli', function (hooks) {
237258
assert.equal(result.exitCode, 0, 'exited with zero');
238259
});
239260

261+
QUnit.test('should pass for an empty codemod in a custom directory', async function (assert) {
262+
await execa(EXECUTABLE_PATH, [
263+
'generate',
264+
'codemod',
265+
'main',
266+
'--codemod-dir',
267+
'other-transform-path',
268+
]);
269+
await execa(EXECUTABLE_PATH, [
270+
'generate',
271+
'fixture',
272+
'main',
273+
'this-dot-owner',
274+
'--codemod-dir',
275+
'other-transform-path',
276+
]);
277+
278+
let result = await execa(EXECUTABLE_PATH, ['test']);
279+
assert.equal(result.exitCode, 0, 'exited with zero');
280+
});
281+
240282
QUnit.test('should fail when input and output do not match', async function (assert) {
241283
await execa(EXECUTABLE_PATH, ['generate', 'codemod', 'main']);
242284
await execa(EXECUTABLE_PATH, ['generate', 'fixture', 'main', 'this-dot-owner']);
@@ -415,6 +457,32 @@ QUnit.module('codemod-cli', function (hooks) {
415457
},
416458
});
417459
});
460+
461+
QUnit.test('works with custom codemod directory', async function (assert) {
462+
userProject.write({
463+
foo: { 'something.js': 'let blah = bar', 'other.js': 'let blah = bar' },
464+
});
465+
466+
await execa(
467+
EXECUTABLE_PATH,
468+
['generate', 'codemod', 'secondary', '--codemod-dir', 'other-dir'],
469+
{
470+
cwd: codemodProject.path(),
471+
}
472+
);
473+
474+
await execa(codemodProject.path('bin/cli.js'), [
475+
codemodProject.path('./other-dir/secondary/index.js'),
476+
'foo/*thing.js',
477+
]);
478+
479+
assert.deepEqual(userProject.read(), {
480+
foo: {
481+
'something.js': 'let halb = rab',
482+
'other.js': 'let blah = bar',
483+
},
484+
});
485+
});
418486
});
419487

420488
QUnit.module('programmatic API', function (hooks) {

0 commit comments

Comments
 (0)