fix: stabilize windows ci portability

This commit is contained in:
Affaan Mustafa
2026-04-12 22:06:04 -07:00
parent 0f1106c21b
commit 057cfe3203
2 changed files with 62 additions and 40 deletions

View File

@@ -359,44 +359,65 @@ function gitRepoRoot(cwd) {
return runGit(['rev-parse', '--show-toplevel'], cwd); return runGit(['rev-parse', '--show-toplevel'], cwd);
} }
function repoRelativePath(repoRoot, filePath) { function candidateGitPaths(repoRoot, filePath) {
const resolvedRepoRoot = path.resolve(repoRoot);
const absolute = path.isAbsolute(filePath) const absolute = path.isAbsolute(filePath)
? path.resolve(filePath) ? path.resolve(filePath)
: path.resolve(process.cwd(), filePath); : path.resolve(process.cwd(), filePath);
const relative = path.relative(repoRoot, absolute); const relative = path.relative(resolvedRepoRoot, absolute);
if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) { if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
return null; return [];
} }
return relative.split(path.sep).join('/');
const candidates = [];
const pushCandidate = value => {
const candidate = String(value || '').trim();
if (!candidate || candidates.includes(candidate)) {
return;
}
candidates.push(candidate);
};
pushCandidate(relative);
pushCandidate(relative.split(path.sep).join('/'));
pushCandidate(absolute);
pushCandidate(absolute.split(path.sep).join('/'));
return candidates;
} }
function patchPreviewFromGitDiff(repoRoot, repoRelative) { function patchPreviewFromGitDiff(repoRoot, pathCandidates) {
const patch = runGit( for (const candidate of pathCandidates) {
['diff', '--no-ext-diff', '--no-color', '--unified=1', '--', repoRelative], const patch = runGit(
repoRoot ['diff', '--no-ext-diff', '--no-color', '--unified=1', '--', candidate],
repoRoot
);
if (!patch) {
continue;
}
const relevant = patch
.split(/\r?\n/)
.filter(line =>
line.startsWith('@@')
|| (line.startsWith('+') && !line.startsWith('+++'))
|| (line.startsWith('-') && !line.startsWith('---'))
)
.slice(0, 6);
if (relevant.length > 0) {
return relevant.join('\n');
}
}
return undefined;
}
function trackedInGit(repoRoot, pathCandidates) {
return pathCandidates.some(candidate =>
runGit(['ls-files', '--error-unmatch', '--', candidate], repoRoot) !== null
); );
if (!patch) {
return undefined;
}
const relevant = patch
.split(/\r?\n/)
.filter(line =>
line.startsWith('@@')
|| (line.startsWith('+') && !line.startsWith('+++'))
|| (line.startsWith('-') && !line.startsWith('---'))
)
.slice(0, 6);
if (relevant.length === 0) {
return undefined;
}
return relevant.join('\n');
}
function trackedInGit(repoRoot, repoRelative) {
return runGit(['ls-files', '--error-unmatch', '--', repoRelative], repoRoot) !== null;
} }
function enrichFileEventFromWorkingTree(toolName, event) { function enrichFileEventFromWorkingTree(toolName, event) {
@@ -409,14 +430,14 @@ function enrichFileEventFromWorkingTree(toolName, event) {
return event; return event;
} }
const repoRelative = repoRelativePath(repoRoot, event.path); const pathCandidates = candidateGitPaths(repoRoot, event.path);
if (!repoRelative) { if (pathCandidates.length === 0) {
return event; return event;
} }
const tool = String(toolName || '').trim().toLowerCase(); const tool = String(toolName || '').trim().toLowerCase();
const tracked = trackedInGit(repoRoot, repoRelative); const tracked = trackedInGit(repoRoot, pathCandidates);
const patchPreview = patchPreviewFromGitDiff(repoRoot, repoRelative) || event.patch_preview; const patchPreview = patchPreviewFromGitDiff(repoRoot, pathCandidates) || event.patch_preview;
const diffPreview = buildDiffPreviewFromPatchPreview(patchPreview) || event.diff_preview; const diffPreview = buildDiffPreviewFromPatchPreview(patchPreview) || event.diff_preview;
if (tool.includes('write')) { if (tool.includes('write')) {

View File

@@ -26,11 +26,12 @@ function main() {
let failed = 0 let failed = 0
const repoRoot = path.join(__dirname, "..", "..") const repoRoot = path.join(__dirname, "..", "..")
const packageJson = JSON.parse( const packageJson = JSON.parse(
fs.readFileSync(path.join(repoRoot, "package.json"), "utf8") fs.readFileSync(path.join(repoRoot, "package.json"), "utf8")
) )
const buildScript = path.join(repoRoot, "scripts", "build-opencode.js") const buildScript = path.join(repoRoot, "scripts", "build-opencode.js")
const distEntry = path.join(repoRoot, ".opencode", "dist", "index.js") const distEntry = path.join(repoRoot, ".opencode", "dist", "index.js")
const npmExecutable = process.platform === "win32" ? "npm.cmd" : "npm"
const tests = [ const tests = [
["package.json exposes the OpenCode build and prepack hooks", () => { ["package.json exposes the OpenCode build and prepack hooks", () => {
assert.strictEqual(packageJson.scripts["build:opencode"], "node scripts/build-opencode.js") assert.strictEqual(packageJson.scripts["build:opencode"], "node scripts/build-opencode.js")
@@ -46,7 +47,7 @@ function main() {
assert.ok(fs.existsSync(distEntry), ".opencode/dist/index.js should exist after build") assert.ok(fs.existsSync(distEntry), ".opencode/dist/index.js should exist after build")
}], }],
["npm pack includes the compiled OpenCode dist payload", () => { ["npm pack includes the compiled OpenCode dist payload", () => {
const result = spawnSync("npm", ["pack", "--dry-run", "--json"], { const result = spawnSync(npmExecutable, ["pack", "--dry-run", "--json"], {
cwd: repoRoot, cwd: repoRoot,
encoding: "utf8", encoding: "utf8",
}) })