mirror of
https://github.com/morluto/rea.git
synced 2026-11-06 23:06:18 +00:00
Resolve Windows ADB, Apktool and update commands against the selected PATH/PATHEXT before launch. Keep explicit paths and relative PATH choices, report lookup failures, and reuse absolute batch invocation and ownership. Add native launch/argv regressions, real npm metadata probes and focused CI ownership so these boundaries retain Windows verification on the fast tier. Fixes #7724 Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage) Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing) Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
import { existsSync, statSync } from "node:fs";
|
|
import { win32 } from "node:path";
|
|
import { windowsPathEntries } from "../process/WindowsExecutable.js";
|
|
|
|
export interface WindowsExecutableLookup {
|
|
/** Windows-formatted working directory; defaults to the process CWD. */
|
|
readonly cwd?: string;
|
|
/** Test seam for Windows paths when running on a non-Windows host. */
|
|
readonly isFile?: (path: string) => boolean;
|
|
}
|
|
|
|
const isRegularFile = (path: string): boolean => {
|
|
try {
|
|
return existsSync(path) && statSync(path).isFile();
|
|
} catch {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/** Resolve Windows bare command names against the captured child environment. */
|
|
export const resolveWindowsProviderExecutable = (
|
|
executable: string,
|
|
environment: Readonly<NodeJS.ProcessEnv>,
|
|
lookup: WindowsExecutableLookup = {},
|
|
): string => {
|
|
const cwd = lookup.cwd ?? process.cwd();
|
|
const absolute = (...paths: string[]): string => win32.resolve(cwd, ...paths);
|
|
if (
|
|
win32.isAbsolute(executable) ||
|
|
executable.includes("/") ||
|
|
executable.includes("\\") ||
|
|
win32.parse(executable).root !== ""
|
|
)
|
|
return absolute(executable);
|
|
|
|
const pathValue = environment.PATH ?? environment.Path ?? environment.path;
|
|
if (pathValue === undefined) return executable;
|
|
const pathEntries = windowsPathEntries(pathValue);
|
|
const explicitExtension = win32.extname(executable).toLowerCase();
|
|
if (explicitExtension !== "" && ![".com", ".exe"].includes(explicitExtension))
|
|
return executable;
|
|
const extensions =
|
|
explicitExtension !== ""
|
|
? [""]
|
|
: (environment.PATHEXT ?? environment.PathExt ?? ".COM;.EXE")
|
|
.split(";")
|
|
.filter((extension) =>
|
|
[".com", ".exe"].includes(extension.toLowerCase()),
|
|
);
|
|
|
|
for (const entry of pathEntries) {
|
|
if (entry.length === 0) continue;
|
|
for (const extension of extensions) {
|
|
const candidate = absolute(entry, `${executable}${extension}`);
|
|
if ((lookup.isFile ?? isRegularFile)(candidate)) return candidate;
|
|
}
|
|
}
|
|
return executable;
|
|
};
|