


























@@ -1,14 +1,16 @@
11#!/usr/bin/env node
22import { spawn, spawnSync } from "node:child_process";
3-import { mkdtempSync, readFileSync, rmSync, statSync } from "node:fs";
3+import { accessSync, constants, mkdtempSync, readFileSync, rmSync, statSync } from "node:fs";
44import { tmpdir } from "node:os";
55import { delimiter, dirname, extname, isAbsolute, relative, resolve } from "node:path";
66import { fileURLToPath } from "node:url";
77import { resolvePathEnvKey } from "./windows-cmd-helpers.mjs";
8899const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
1010const repoLocal = resolveCrabboxBinary(process.env, process.platform);
11-const binary = repoLocal ?? resolvePathBinary("crabbox", process.env, process.platform);
11+const pathLocal = resolvePathBinary("crabbox", process.env, process.platform);
12+const binary =
13+repoLocal ?? pathLocal ?? resolveGitCommonCrabboxBinary(process.env, process.platform) ?? "crabbox";
1214const args = process.argv.slice(2);
13151416if (args[0] === "--") {
@@ -32,37 +34,63 @@ function commandCandidates(command, platform) {
3234function resolveCrabboxBinary(env, platform) {
3335const base = resolve(repoRoot, "../crabbox/bin/crabbox");
3436for (const candidate of commandCandidates(base, platform)) {
35-if (isFile(candidate)) {
37+if (isExecutableFile(candidate, platform)) {
3638return candidate;
3739}
3840}
3941return null;
4042}
41434244function resolvePathBinary(command, env, platform) {
43-if (platform !== "win32") {
44-return command;
45-}
46-for (const candidate of commandCandidates(command, platform)) {
47-if (isFile(candidate)) {
48-return candidate;
49-}
50-}
5145const pathValue = env[resolvePathEnvKey(env)] ?? "";
5246for (const dir of pathValue.split(delimiter).filter(Boolean)) {
5347for (const candidate of commandCandidates(command, platform)) {
5448const fullPath = resolve(dir, candidate);
55-if (isFile(fullPath)) {
49+if (isExecutableFile(fullPath, platform)) {
5650return fullPath;
5751}
5852}
5953}
60-return command;
54+return null;
6155}
625663-function isFile(path) {
57+function resolveGitCommonCrabboxBinary(env, platform) {
58+const gitBinary = resolvePathBinary("git", env, platform) ?? "git";
59+const invocation = spawnInvocation(gitBinary, ["rev-parse", "--git-common-dir"], env, platform);
60+const result = spawnSync(invocation.command, invocation.args, {
61+cwd: repoRoot,
62+encoding: "utf8",
63+stdio: ["ignore", "pipe", "ignore"],
64+windowsVerbatimArguments: invocation.windowsVerbatimArguments,
65+});
66+if ((result.status ?? 1) !== 0) {
67+return null;
68+}
69+const gitCommonDir = result.stdout.trim();
70+if (!gitCommonDir) {
71+return null;
72+}
73+const absoluteGitCommonDir = isAbsolute(gitCommonDir)
74+ ? gitCommonDir
75+ : resolve(repoRoot, gitCommonDir);
76+const base = resolve(absoluteGitCommonDir, "../..", "crabbox/bin/crabbox");
77+for (const candidate of commandCandidates(base, platform)) {
78+if (isExecutableFile(candidate, platform)) {
79+return candidate;
80+}
81+}
82+return null;
83+}
84+85+function isExecutableFile(path, platform) {
6486try {
65-return statSync(path).isFile();
87+if (!statSync(path).isFile()) {
88+return false;
89+}
90+if (platform !== "win32") {
91+accessSync(path, constants.X_OK);
92+}
93+return true;
6694} catch {
6795return false;
6896}
@@ -116,7 +144,7 @@ function checkedOutput(command, commandArgs) {
116144}
117145118146function gitOutput(commandArgs) {
119-const gitBinary = resolvePathBinary("git", process.env, process.platform);
147+const gitBinary = resolvePathBinary("git", process.env, process.platform) ?? "git";
120148const invocation = spawnInvocation(gitBinary, commandArgs, process.env, process.platform);
121149const result = spawnSync(invocation.command, invocation.args, {
122150cwd: repoRoot,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。