codemod 1.7.6 → 1.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -6
- package/codemod +112 -35
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -30,32 +30,37 @@ Whether you're an individual developer tackling tech debt, an OSS maintainer shi
|
|
|
30
30
|
## Installation
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
npm install -g codemod
|
|
33
|
+
npm install -g codemod
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
Or use via `npx` without installation:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
npx codemod
|
|
39
|
+
npx codemod
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
In an interactive terminal, bare `npx codemod` opens a launcher and refreshes to the latest published CLI before showing the prompt. In non-interactive contexts, it prints next steps and exits with status `1`.
|
|
43
|
+
|
|
42
44
|
## Quick Start
|
|
43
45
|
|
|
44
46
|
```bash
|
|
45
|
-
# 1.
|
|
47
|
+
# 1. Start with the launcher or scaffold directly
|
|
48
|
+
npx codemod
|
|
49
|
+
|
|
50
|
+
# 2. Create a codemod package
|
|
46
51
|
npx codemod init my-codemod
|
|
47
52
|
cd my-codemod
|
|
48
53
|
|
|
49
54
|
# You can create codemod packages with the help of AI using Codemod MCP or Studio
|
|
50
55
|
|
|
51
|
-
#
|
|
56
|
+
# 3. Run it locally
|
|
52
57
|
npx codemod workflow run -w ./example-codemod -t /abs/path/to/repo
|
|
53
58
|
|
|
54
|
-
#
|
|
59
|
+
# 4. Publish to registry
|
|
55
60
|
npx codemod login
|
|
56
61
|
npx codemod publish
|
|
57
62
|
|
|
58
|
-
#
|
|
63
|
+
# 5. Run from registry
|
|
59
64
|
npx codemod @your-org/example-codemod
|
|
60
65
|
```
|
|
61
66
|
|
package/codemod
CHANGED
|
@@ -5,6 +5,7 @@ const fs = require("fs");
|
|
|
5
5
|
const path = require("path");
|
|
6
6
|
|
|
7
7
|
const binaryName = process.platform === "win32" ? "codemod.exe" : "codemod";
|
|
8
|
+
const CODEMOD_BOOTSTRAPPED_ENV = "CODEMOD_BOOTSTRAPPED";
|
|
8
9
|
|
|
9
10
|
function detectPackageName() {
|
|
10
11
|
const { platform, arch } = process;
|
|
@@ -93,8 +94,6 @@ function resolveBinaryPath() {
|
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
console.log("pkgName", pkgName);
|
|
97
|
-
|
|
98
97
|
const releaseCandidate = path.join(
|
|
99
98
|
__dirname,
|
|
100
99
|
"..",
|
|
@@ -125,43 +124,121 @@ function resolveBinaryPath() {
|
|
|
125
124
|
failToLocateBinary(pkgName, moduleError);
|
|
126
125
|
}
|
|
127
126
|
|
|
128
|
-
|
|
127
|
+
function npmExecutable(platform = process.platform) {
|
|
128
|
+
return platform === "win32" ? "npm.cmd" : "npm";
|
|
129
|
+
}
|
|
129
130
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
function latestBootstrapArgs() {
|
|
132
|
+
return [
|
|
133
|
+
"exec",
|
|
134
|
+
"--yes",
|
|
135
|
+
"--prefer-online",
|
|
136
|
+
"--package",
|
|
137
|
+
"codemod@latest",
|
|
138
|
+
"--",
|
|
139
|
+
"codemod",
|
|
140
|
+
];
|
|
141
|
+
}
|
|
133
142
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
process.exit(1);
|
|
138
|
-
});
|
|
143
|
+
function shouldBootstrapLatestNoCommand(argv, env = process.env) {
|
|
144
|
+
return argv.length === 0 && !env[CODEMOD_BOOTSTRAPPED_ENV];
|
|
145
|
+
}
|
|
139
146
|
|
|
140
|
-
|
|
147
|
+
function spawnLatestCli({ env = process.env, platform = process.platform, spawnImpl = spawn }) {
|
|
148
|
+
return spawnImpl(npmExecutable(platform), latestBootstrapArgs(), {
|
|
149
|
+
stdio: "inherit",
|
|
150
|
+
env: {
|
|
151
|
+
...env,
|
|
152
|
+
[CODEMOD_BOOTSTRAPPED_ENV]: "1",
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
}
|
|
141
156
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
// Ignore
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
process.on(signal, handler);
|
|
154
|
-
return { signal, handler };
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
child.on("exit", (code, signal) => {
|
|
158
|
-
forwarders.forEach(({ signal, handler }) => {
|
|
159
|
-
process.removeListener(signal, handler);
|
|
157
|
+
function spawnResolvedBinary({
|
|
158
|
+
argv,
|
|
159
|
+
spawnImpl = spawn,
|
|
160
|
+
resolveBinaryPathImpl = resolveBinaryPath,
|
|
161
|
+
}) {
|
|
162
|
+
const { binaryPath } = resolveBinaryPathImpl();
|
|
163
|
+
return spawnImpl(binaryPath, argv, {
|
|
164
|
+
stdio: "inherit",
|
|
160
165
|
});
|
|
166
|
+
}
|
|
161
167
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
168
|
+
function run({
|
|
169
|
+
argv = process.argv.slice(2),
|
|
170
|
+
env = process.env,
|
|
171
|
+
platform = process.platform,
|
|
172
|
+
spawnImpl = spawn,
|
|
173
|
+
resolveBinaryPathImpl = resolveBinaryPath,
|
|
174
|
+
} = {}) {
|
|
175
|
+
if (shouldBootstrapLatestNoCommand(argv, env)) {
|
|
176
|
+
return spawnLatestCli({ env, platform, spawnImpl });
|
|
166
177
|
}
|
|
167
|
-
|
|
178
|
+
|
|
179
|
+
return spawnResolvedBinary({ argv, spawnImpl, resolveBinaryPathImpl });
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function attachChildLifecycle(
|
|
183
|
+
child,
|
|
184
|
+
{
|
|
185
|
+
signalSource = process,
|
|
186
|
+
processObject = process,
|
|
187
|
+
logger = console.error,
|
|
188
|
+
} = {},
|
|
189
|
+
) {
|
|
190
|
+
child.on("error", (error) => {
|
|
191
|
+
logger("Failed to execute codemod binary.");
|
|
192
|
+
logger(error);
|
|
193
|
+
processObject.exit(1);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const signals = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
197
|
+
|
|
198
|
+
const forwarders = signals.map((signal) => {
|
|
199
|
+
const handler = () => {
|
|
200
|
+
if (child.killed) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
child.kill(signal);
|
|
205
|
+
} catch (_) {
|
|
206
|
+
// Ignore
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
signalSource.on(signal, handler);
|
|
210
|
+
return { signal, handler };
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
child.on("exit", (code, signal) => {
|
|
214
|
+
forwarders.forEach(({ signal, handler }) => {
|
|
215
|
+
signalSource.removeListener(signal, handler);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
if (signal) {
|
|
219
|
+
processObject.kill(processObject.pid, signal);
|
|
220
|
+
} else {
|
|
221
|
+
processObject.exit(code == null ? 1 : code);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function main() {
|
|
227
|
+
const child = run();
|
|
228
|
+
attachChildLifecycle(child);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (require.main === module) {
|
|
232
|
+
main();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
module.exports = {
|
|
236
|
+
CODEMOD_BOOTSTRAPPED_ENV,
|
|
237
|
+
latestBootstrapArgs,
|
|
238
|
+
npmExecutable,
|
|
239
|
+
shouldBootstrapLatestNoCommand,
|
|
240
|
+
spawnLatestCli,
|
|
241
|
+
spawnResolvedBinary,
|
|
242
|
+
run,
|
|
243
|
+
attachChildLifecycle,
|
|
244
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codemod",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.7",
|
|
4
4
|
"description": "Codemod platform for semantic code transformations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ast",
|
|
@@ -19,15 +19,18 @@
|
|
|
19
19
|
"README.md",
|
|
20
20
|
"codemod"
|
|
21
21
|
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"test": "node --test tests/*.test.js"
|
|
24
|
+
},
|
|
22
25
|
"dependencies": {
|
|
23
26
|
"detect-libc": "^2.0.3"
|
|
24
27
|
},
|
|
25
28
|
"optionalDependencies": {
|
|
26
|
-
"@codemod.com/cli-darwin-arm64": "1.7.
|
|
27
|
-
"@codemod.com/cli-darwin-x64": "1.7.
|
|
28
|
-
"@codemod.com/cli-linux-arm64-gnu": "1.7.
|
|
29
|
-
"@codemod.com/cli-linux-x64-gnu": "1.7.
|
|
30
|
-
"@codemod.com/cli-win32-x64-msvc": "1.7.
|
|
29
|
+
"@codemod.com/cli-darwin-arm64": "1.7.7",
|
|
30
|
+
"@codemod.com/cli-darwin-x64": "1.7.7",
|
|
31
|
+
"@codemod.com/cli-linux-arm64-gnu": "1.7.7",
|
|
32
|
+
"@codemod.com/cli-linux-x64-gnu": "1.7.7",
|
|
33
|
+
"@codemod.com/cli-win32-x64-msvc": "1.7.7"
|
|
31
34
|
},
|
|
32
35
|
"engines": {
|
|
33
36
|
"node": ">= 16.0.0"
|