feat(codex): auto-install git bash via winget on windows

This commit is contained in:
YeonGyu-Kim
2026-05-31 11:00:30 +09:00
parent 021d4e3c97
commit 4fded80f6a
8 changed files with 351 additions and 26 deletions
@@ -1,7 +1,7 @@
import assert from "node:assert/strict";
import test from "node:test";
import { resolveGitBash } from "./git-bash.mjs";
import { prepareGitBashForInstall, resolveGitBash } from "./git-bash.mjs";
const programFilesGitBash = "C:\\Program Files\\Git\\bin\\bash.exe";
const programFilesX86GitBash = "C:\\Program Files (x86)\\Git\\bin\\bash.exe";
@@ -68,3 +68,63 @@ test("#given Windows without Git Bash #when resolving #then returns install guid
assert.match(result.installHint, /winget install --id Git\.Git -e --source winget/);
assert.match(result.installHint, /rerun `bunx omo install --platform=codex`/);
});
test("#given Windows without Git Bash and winget is allowed #when preparing #then winget runs and resolver retries", async () => {
const runCalls = [];
const resolutions = [
{ found: false, checkedPaths: [programFilesGitBash], installHint: "install hint" },
{ found: true, path: programFilesGitBash, source: "program-files" },
];
let resolveCallCount = 0;
const result = await prepareGitBashForInstall({
platform: "win32",
env: {},
cwd: "C:\\repo",
resolveGitBash: () => resolutions[resolveCallCount++] ?? resolutions[resolutions.length - 1],
runCommand: async (command, args, options) => {
runCalls.push([command, ...args, options.cwd].join(" "));
},
});
assert.deepEqual(runCalls, ["winget install --id Git.Git -e --source winget C:\\repo"]);
assert.equal(resolveCallCount, 2);
assert.deepEqual(result, { found: true, path: programFilesGitBash, source: "program-files" });
});
test("#given Windows without Git Bash and skip env is set #when preparing #then winget is not run and install hint remains", async () => {
const runCalls = [];
const missingResolution = {
found: false,
checkedPaths: [programFilesGitBash, programFilesX86GitBash],
installHint: "install hint",
};
const result = await prepareGitBashForInstall({
platform: "win32",
env: { OMO_CODEX_SKIP_GIT_BASH_AUTO_INSTALL: "1" },
cwd: "C:\\repo",
resolveGitBash: () => missingResolution,
runCommand: async (command, args, options) => {
runCalls.push([command, ...args, options.cwd].join(" "));
},
});
assert.deepEqual(runCalls, []);
assert.deepEqual(result, missingResolution);
});
test("#given non-Windows platform #when preparing #then winget is never called", async () => {
const runCalls = [];
const result = await prepareGitBashForInstall({
platform: "linux",
env: {},
cwd: "/repo",
runCommand: async (command, args, options) => {
runCalls.push([command, ...args, options.cwd].join(" "));
},
});
assert.deepEqual(runCalls, []);
assert.deepEqual(result, { found: true, path: null, source: "not-required" });
});