@bigking67/pi-67 0.10.0 → 0.10.1
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/CHANGELOG.md +8 -0
- package/README.md +4 -0
- package/package.json +1 -1
- package/scripts/check.mjs +17 -0
- package/src/lib/shell-runner.mjs +23 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.1]
|
|
4
|
+
|
|
5
|
+
- Falls back from `npm` to `npm.cmd` on Windows when checking npm registry state
|
|
6
|
+
or running `pi-67 self-update`, avoiding `spawnSync npm ENOENT` in PowerShell
|
|
7
|
+
environments where only the command shim is directly spawnable.
|
|
8
|
+
- Clarifies that global install is the normal daily path and `npx @latest` is
|
|
9
|
+
the always-fresh one-shot validation or recovery path.
|
|
10
|
+
|
|
3
11
|
## [0.10.0]
|
|
4
12
|
|
|
5
13
|
- Initial npm manager CLI for pi-67.
|
package/README.md
CHANGED
|
@@ -55,6 +55,10 @@ If the local manager may be stale, run the latest npm package for one repair:
|
|
|
55
55
|
npx -y @bigking67/pi-67@latest update --repair
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
Use `npm install -g @bigking67/pi-67` for normal daily operation. Use `npx -y
|
|
59
|
+
@bigking67/pi-67@latest ...` when you want a zero-install, always-fresh one-shot
|
|
60
|
+
check or repair before trusting the globally installed manager.
|
|
61
|
+
|
|
58
62
|
## Safety defaults
|
|
59
63
|
|
|
60
64
|
`pi-67 update` preserves local runtime choices:
|
package/package.json
CHANGED
package/scripts/check.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { npmPublishTargetStatus } from "../src/lib/npm-registry.mjs";
|
|
7
|
+
import { commandCandidatesForPlatform } from "../src/lib/shell-runner.mjs";
|
|
7
8
|
import { readExtensionRegistry, validateExtensionRegistry } from "../src/lib/extension-registry.mjs";
|
|
8
9
|
import { buildPlanDecisions, classifyGitShort } from "../src/lib/update-plan.mjs";
|
|
9
10
|
import {
|
|
@@ -26,6 +27,7 @@ for (const file of files.filter((item) => item.endsWith(".json"))) {
|
|
|
26
27
|
JSON.parse(fs.readFileSync(file, "utf8"));
|
|
27
28
|
}
|
|
28
29
|
runPublishTargetSelfTests();
|
|
30
|
+
runShellRunnerSelfTests();
|
|
29
31
|
runExtensionRegistrySelfTests();
|
|
30
32
|
runUpdatePlanSelfTests();
|
|
31
33
|
runUpdateSafetySelfTests();
|
|
@@ -92,6 +94,21 @@ function runPublishTargetSelfTests() {
|
|
|
92
94
|
);
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
function runShellRunnerSelfTests() {
|
|
98
|
+
assert(
|
|
99
|
+
JSON.stringify(commandCandidatesForPlatform("npm", "win32")) === JSON.stringify(["npm", "npm.cmd"]),
|
|
100
|
+
"Windows npm execution must fall back to npm.cmd",
|
|
101
|
+
);
|
|
102
|
+
assert(
|
|
103
|
+
JSON.stringify(commandCandidatesForPlatform("git", "win32")) === JSON.stringify(["git"]),
|
|
104
|
+
"Windows non-npm execution should keep the requested command",
|
|
105
|
+
);
|
|
106
|
+
assert(
|
|
107
|
+
JSON.stringify(commandCandidatesForPlatform("npm", "darwin")) === JSON.stringify(["npm"]),
|
|
108
|
+
"POSIX npm execution should keep the requested command",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
95
112
|
function runExtensionRegistrySelfTests() {
|
|
96
113
|
const registry = readExtensionRegistry(path.join(root, "src", "data", "extension-registry.json"));
|
|
97
114
|
const manifest = extensionRegistryTestManifest();
|
package/src/lib/shell-runner.mjs
CHANGED
|
@@ -7,7 +7,7 @@ export function runCommand(command, args = [], options = {}) {
|
|
|
7
7
|
info(`DRY-RUN (${cwd}) ${[command, ...args].join(" ")}`);
|
|
8
8
|
return { status: 0, stdout: "", stderr: "" };
|
|
9
9
|
}
|
|
10
|
-
const result =
|
|
10
|
+
const { result } = spawnWithFallback(command, args, {
|
|
11
11
|
cwd,
|
|
12
12
|
stdio: options.stdio || "inherit",
|
|
13
13
|
env: { ...process.env, ...(options.env || {}) },
|
|
@@ -24,7 +24,7 @@ export function runCommand(command, args = [], options = {}) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export function captureCommand(command, args = [], options = {}) {
|
|
27
|
-
const result =
|
|
27
|
+
const { result } = spawnWithFallback(command, args, {
|
|
28
28
|
cwd: options.cwd || process.cwd(),
|
|
29
29
|
env: { ...process.env, ...(options.env || {}) },
|
|
30
30
|
encoding: "utf8",
|
|
@@ -38,3 +38,24 @@ export function captureCommand(command, args = [], options = {}) {
|
|
|
38
38
|
error: result.error ? result.error.message : "",
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
export function commandCandidatesForPlatform(command, platform = process.platform) {
|
|
43
|
+
if (platform === "win32" && command === "npm") {
|
|
44
|
+
return ["npm", "npm.cmd"];
|
|
45
|
+
}
|
|
46
|
+
return [command];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function spawnWithFallback(command, args, options) {
|
|
50
|
+
let lastResult;
|
|
51
|
+
for (const candidate of commandCandidatesForPlatform(command)) {
|
|
52
|
+
const result = spawnSync(candidate, args, options);
|
|
53
|
+
lastResult = result;
|
|
54
|
+
if (!isCommandNotFound(result)) return { command: candidate, result };
|
|
55
|
+
}
|
|
56
|
+
return { command, result: lastResult };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function isCommandNotFound(result) {
|
|
60
|
+
return result?.error?.code === "ENOENT";
|
|
61
|
+
}
|