Skip to content

Commit d446899

Browse files
authored
Call JS API of jscodeshift instead of using spawn (#349)
1 parent c316196 commit d446899

File tree

7 files changed

+210
-96
lines changed

7 files changed

+210
-96
lines changed

.changeset/sharp-months-battle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"aws-sdk-js-codemod": patch
3+
---
4+
5+
Call JS API of jscodeshift instead of using spawn

src/cli.spec.ts

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/cli.ts

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,39 +18,64 @@
1818
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1919
*/
2020

21-
import { spawn } from "child_process";
21+
// Most of the code from here is from bin/jscodeshift.js
22+
// It's kept that way so that users can reuse jscodeshift options.
2223

2324
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
24-
// @ts-ignore: package.json will be imported from dist folders
25-
import { version } from "../package.json"; // eslint-disable-line
25+
// @ts-nocheck
26+
import Runner from "jscodeshift/dist/Runner";
27+
import path from "path";
28+
2629
import {
27-
getArgsWithUpdatedTransformFile,
2830
getHelpParagraph,
29-
getTransformFileFromArgs,
31+
getJsCodeshiftParser,
3032
getTransforms,
3133
getUpdatedTransformFile,
3234
} from "./utils";
3335

34-
export const run = async (args: string[]): Promise<void> => {
35-
const transforms = getTransforms();
36-
37-
if (args[0] === "--version") {
38-
process.stdout.write(`aws-sdk-js-codemod: ${version}\n\n`);
39-
} else if (args[0] === "--help" || args[0] === "-h") {
40-
process.stdout.write(getHelpParagraph(transforms));
41-
} else if (args.includes("-t") || args.some((arg) => arg.startsWith("--transform="))) {
42-
const transformFile = getTransformFileFromArgs(args);
43-
if (transforms.map(({ name }) => name).includes(transformFile)) {
44-
const updatedTransformFile = getUpdatedTransformFile(transformFile);
45-
args = getArgsWithUpdatedTransformFile(args, updatedTransformFile);
46-
}
36+
const args = process.argv;
37+
const transforms = getTransforms();
38+
39+
if (args[2] === "--help" || args[2] === "-h") {
40+
process.stdout.write(getHelpParagraph(transforms));
41+
}
42+
43+
const parser = getJsCodeshiftParser();
44+
45+
let options, positionalArguments;
46+
try {
47+
({ options, positionalArguments } = parser.parse());
48+
if (positionalArguments.length === 0 && !options.stdin) {
49+
process.stderr.write(
50+
"Error: You have to provide at least one file/directory to transform." +
51+
"\n\n---\n\n" +
52+
parser.getHelpText()
53+
);
54+
process.exit(1);
4755
}
48-
spawn("npm", ["exec", "jscodeshift", "--", ...args], {
49-
stdio: "inherit",
50-
shell: process.platform == "win32",
51-
});
52-
};
56+
} catch (e) {
57+
const exitCode = e.exitCode === undefined ? 1 : e.exitCode;
58+
(exitCode ? process.stderr : process.stdout).write(e.message);
59+
process.exit(exitCode);
60+
}
61+
62+
const { transform } = options;
63+
if (transforms.map(({ name }) => name).includes(transform)) {
64+
options.transform = getUpdatedTransformFile(transform);
65+
}
5366

54-
const [, , ...args] = process.argv;
67+
function run(paths, options) {
68+
Runner.run(
69+
/^https?/.test(options.transform) ? options.transform : path.resolve(options.transform),
70+
paths,
71+
options
72+
);
73+
}
5574

56-
run(args);
75+
if (options.stdin) {
76+
let buffer = "";
77+
process.stdin.on("data", (data) => (buffer += data));
78+
process.stdin.on("end", () => run(buffer.split("\n"), options));
79+
} else {
80+
run(positionalArguments, options);
81+
}

src/utils/getArgsWithUpdatedTransformFile.ts

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/utils/getJsCodeshiftParser.ts

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Most of the code from here is from bin/jscodeshift.js
2+
// It's kept that way so that users can reuse jscodeshift options.
3+
4+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
5+
// @ts-nocheck
6+
7+
import { readFileSync } from "fs";
8+
import argsParser from "jscodeshift/dist/argsParser";
9+
import { dirname, join } from "path";
10+
11+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
12+
// @ts-ignore: package.json will be imported from dist folders
13+
import { version } from "../../package.json";
14+
15+
const requirePackage = (name: string) => {
16+
const entry = require.resolve(name);
17+
let dir = dirname(entry);
18+
while (dir !== "/") {
19+
try {
20+
// eslint-disable-next-line @typescript-eslint/no-var-requires
21+
const pkg = require(join(dir, "package.json"));
22+
return pkg.name === name ? pkg : {};
23+
} catch (error) {} // eslint-disable-line no-empty
24+
dir = dirname(dir);
25+
}
26+
return {};
27+
};
28+
29+
/* eslint-disable @typescript-eslint/naming-convention */
30+
export const getJsCodeshiftParser = () =>
31+
argsParser.options({
32+
transform: {
33+
display_index: 15,
34+
abbr: "t",
35+
default: "./transform.js",
36+
help: "path to the transform file. Can be either a local path or url",
37+
metavar: "FILE",
38+
required: true,
39+
},
40+
cpus: {
41+
display_index: 1,
42+
abbr: "c",
43+
help: "start at most N child processes to process source files",
44+
defaultHelp: "max(all - 1, 1)",
45+
metavar: "N",
46+
process: Number,
47+
},
48+
verbose: {
49+
display_index: 16,
50+
abbr: "v",
51+
choices: [0, 1, 2],
52+
default: 0,
53+
help: "show more information about the transform process",
54+
metavar: "N",
55+
process: Number,
56+
},
57+
dry: {
58+
display_index: 2,
59+
abbr: "d",
60+
flag: true,
61+
default: false,
62+
help: "dry run (no changes are made to files)",
63+
},
64+
print: {
65+
display_index: 11,
66+
abbr: "p",
67+
flag: true,
68+
default: false,
69+
help: "print transformed files to stdout, useful for development",
70+
},
71+
babel: {
72+
display_index: 0,
73+
flag: true,
74+
default: true,
75+
help: "apply babeljs to the transform file",
76+
},
77+
extensions: {
78+
display_index: 3,
79+
default: "js",
80+
help: "transform files with these file extensions (comma separated list)",
81+
metavar: "EXT",
82+
},
83+
ignorePattern: {
84+
display_index: 7,
85+
full: "ignore-pattern",
86+
list: true,
87+
help: "ignore files that match a provided glob expression",
88+
metavar: "GLOB",
89+
},
90+
ignoreConfig: {
91+
display_index: 6,
92+
full: "ignore-config",
93+
list: true,
94+
help: "ignore files if they match patterns sourced from a configuration file (e.g. a .gitignore)",
95+
metavar: "FILE",
96+
},
97+
gitignore: {
98+
display_index: 8,
99+
flag: true,
100+
default: false,
101+
help: "adds entries the current directory's .gitignore file",
102+
},
103+
runInBand: {
104+
display_index: 12,
105+
flag: true,
106+
default: false,
107+
full: "run-in-band",
108+
help: "run serially in the current process",
109+
},
110+
silent: {
111+
display_index: 13,
112+
abbr: "s",
113+
flag: true,
114+
default: false,
115+
help: "do not write to stdout or stderr",
116+
},
117+
parser: {
118+
display_index: 9,
119+
choices: ["babel", "babylon", "flow", "ts", "tsx"],
120+
default: "babel",
121+
help: "the parser to use for parsing the source files",
122+
},
123+
parserConfig: {
124+
display_index: 10,
125+
full: "parser-config",
126+
help: "path to a JSON file containing a custom parser configuration for flow or babylon",
127+
metavar: "FILE",
128+
process: (file: string) => JSON.parse(readFileSync(file).toString()),
129+
},
130+
failOnError: {
131+
display_index: 4,
132+
flag: true,
133+
help: "Return a non-zero code when there are errors",
134+
full: "fail-on-error",
135+
default: false,
136+
},
137+
version: {
138+
display_index: 17,
139+
help: "print version and exit",
140+
callback: function () {
141+
return [
142+
`aws-sdk-js-codemod: ${version}`,
143+
`- jscodeshift: ${requirePackage("jscodeshift").version}`,
144+
`- recast: ${requirePackage("recast").version}\n`,
145+
].join("\n");
146+
},
147+
},
148+
stdin: {
149+
display_index: 14,
150+
help: "read file/directory list from stdin",
151+
flag: true,
152+
default: false,
153+
},
154+
});

src/utils/getTransformFileFromArgs.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/utils/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
export * from "./getArgsWithUpdatedTransformFile";
21
export * from "./getHelpParagraph";
3-
export * from "./getTransformFileFromArgs";
2+
export * from "./getJsCodeshiftParser";
43
export * from "./getTransforms";
54
export * from "./getUpdatedTransformFile";

0 commit comments

Comments
 (0)