|
1 | 1 | #!/usr/bin/env node
|
2 | 2 |
|
3 |
| -import program from 'commander' |
4 |
| -import execa from 'execa' |
5 |
| - |
6 | 3 | import * as fs from 'fs'
|
7 | 4 | import * as path from 'path'
|
| 5 | +import Module from 'module' |
8 | 6 |
|
9 |
| -import { version } from '../package.json' |
10 |
| - |
11 |
| -program |
12 |
| - .name('vue-codemod') |
13 |
| - .version(version) |
14 |
| - |
15 |
| - .requiredOption('-t, --transformation <name>', 'Name or path of a transfromation module') |
16 |
| - .requiredOption('-f, --file <glob>', 'Files or directory to run codemod on') |
17 |
| - .option('--dry', 'Dry run (no changes are made to files)') |
18 |
| - |
19 |
| - .parse(process.argv) |
20 |
| - |
21 |
| -function resolveTransformation (name: string) { |
22 |
| - const builtInPath = require.resolve(`../transforms/${name}`) |
23 |
| - if (fs.existsSync(builtInPath)) { |
24 |
| - return builtInPath |
25 |
| - } |
26 |
| - |
27 |
| - const customModulePath = path.resolve(process.cwd(), name) |
28 |
| - if (fs.existsSync(customModulePath)) { |
29 |
| - return customModulePath |
| 7 | +import * as yargs from 'yargs' |
| 8 | +import * as globby from 'globby' |
| 9 | + |
| 10 | +import createDebug from 'debug' |
| 11 | + |
| 12 | +import builtInTransformations from '../transformations' |
| 13 | +import runTransformation from '../src/run-transformation' |
| 14 | + |
| 15 | +const debug = createDebug('vue-codemod') |
| 16 | +const log = console.log.bind(console) |
| 17 | + |
| 18 | +const { _: files, transformation: transformationName, params } = yargs |
| 19 | + .usage('Usage: $0 [file pattern]') |
| 20 | + .option('transformation', { |
| 21 | + alias: 't', |
| 22 | + type: 'string', |
| 23 | + describe: 'Name or path of the transformation module', |
| 24 | + }) |
| 25 | + .option('params', { |
| 26 | + alias: 'p', |
| 27 | + describe: 'Custom params to the transformation', |
| 28 | + }) |
| 29 | + .demandOption('transformation') |
| 30 | + .help().argv |
| 31 | + |
| 32 | +// TODO: port the `Runner` interface of jscodeshift |
| 33 | +async function main() { |
| 34 | + const resolvedPaths = globby.sync(files) |
| 35 | + const transformation = loadTransformation(transformationName) |
| 36 | + |
| 37 | + log(`Processing ${resolvedPaths.length} files…`) |
| 38 | + |
| 39 | + for (const p of resolvedPaths) { |
| 40 | + debug(`Processing ${p}…`) |
| 41 | + const fileInfo = { |
| 42 | + path: p, |
| 43 | + source: fs.readFileSync(p).toString(), |
| 44 | + } |
| 45 | + try { |
| 46 | + const result = runTransformation( |
| 47 | + fileInfo, |
| 48 | + transformation, |
| 49 | + params as object |
| 50 | + ) |
| 51 | + fs.writeFileSync(p, result) |
| 52 | + } catch (e) { |
| 53 | + console.error(e) |
| 54 | + } |
30 | 55 | }
|
31 | 56 | }
|
32 | 57 |
|
33 |
| -const transformationPath = resolveTransformation(program.transformation) |
34 |
| -if (!transformationPath) { |
35 |
| - console.error(`Cannot find transformation module ${program.transformation}`) |
| 58 | +main().catch((err) => { |
| 59 | + console.error(err) |
36 | 60 | process.exit(1)
|
37 |
| -} |
38 |
| - |
39 |
| -// TODO: |
40 |
| -// don't depend on the jscodeshift **CLI** interface |
41 |
| -// so that we can apply the adapter to all code transforms directly |
42 |
| -const jscodeshiftExecutable = require.resolve('.bin/jscodeshift') |
43 |
| -execa.sync(jscodeshiftExecutable, ['-t', transformationPath, program.file, '--extensions', 'vue,js'], { |
44 |
| - stdio: 'inherit', |
45 |
| - stripFinalNewline: false |
46 | 61 | })
|
| 62 | + |
| 63 | +function loadTransformation(nameOrPath: string) { |
| 64 | + let transformation = builtInTransformations[nameOrPath] |
| 65 | + if (transformation) { |
| 66 | + return transformation |
| 67 | + } |
| 68 | + |
| 69 | + const customModulePath = path.resolve(process.cwd(), nameOrPath) |
| 70 | + if (fs.existsSync(customModulePath)) { |
| 71 | + const requireFunc = Module.createRequire( |
| 72 | + path.resolve(process.cwd(), './package.json') |
| 73 | + ) |
| 74 | + // TODO: interop with ES module |
| 75 | + // TODO: fix absolute path |
| 76 | + const module = requireFunc(`./${nameOrPath}`) |
| 77 | + const transformation = |
| 78 | + typeof module.default === 'function' ? module.default : module |
| 79 | + return transformation |
| 80 | + } |
| 81 | + |
| 82 | + throw new Error(`Cannot find transformation module ${nameOrPath}`) |
| 83 | +} |
0 commit comments