mirror of
https://gh-proxy.org/https://github.com/klinsmaya/LobsterAI.git
synced 2026-11-08 01:06:44 +08:00
- Add `openclaw.version` and `openclaw.repo` config in package.json - Add `ensure-openclaw-version.cjs` to auto-clone or checkout the pinned tag - Add build cache in `build-openclaw-runtime.sh` — skip rebuild when version matches - Enhanced `runtime-build-info.json` with openclawVersion and openclawCommit - Fix Windows: prefer Git Bash over WSL bash (WindowsApps\bash.exe) - Fix Windows: normalize PATH env for bash, use relative script path - Fix Windows: add `shell: true` for npm.cmd in openclaw-runtime-host.cjs - Add `.gitattributes` to enforce LF line endings for .sh files - Update README.md and README_zh.md with OpenClaw dev workflow and version management docs Co-Authored-By: Claude Opus 4.6 <[email protected]>
113 lines
3.8 KiB
JavaScript
113 lines
3.8 KiB
JavaScript
'use strict';
|
|
|
|
const { spawnSync } = require('child_process');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
function commandExists(command) {
|
|
const checker = process.platform === 'win32' ? 'where' : 'which';
|
|
const result = spawnSync(checker, [command], { stdio: 'ignore' });
|
|
return result.status === 0;
|
|
}
|
|
|
|
function resolveBashExecutable(rootDir) {
|
|
if (process.platform !== 'win32') {
|
|
return commandExists('bash') ? 'bash' : null;
|
|
}
|
|
|
|
// On Windows, we must use Git Bash (MSYS2), NOT WSL's bash.
|
|
// WSL bash (WindowsApps\bash.exe) runs in a separate Linux environment and
|
|
// cannot access Windows-installed node, npm, pnpm, etc.
|
|
|
|
// 1. Check all bash locations, prefer Git Bash over WSL bash.
|
|
try {
|
|
const result = spawnSync('where', ['bash'], {
|
|
encoding: 'utf-8',
|
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
});
|
|
if (result.status === 0 && result.stdout) {
|
|
const paths = result.stdout.trim().split(/\r?\n/).map(p => p.trim()).filter(Boolean);
|
|
const gitBash = paths.find(p => !p.toLowerCase().includes('windowsapps'));
|
|
if (gitBash) return gitBash;
|
|
}
|
|
} catch {}
|
|
|
|
// 2. Derive bash path from git installation.
|
|
try {
|
|
const gitResult = spawnSync('where', ['git'], {
|
|
encoding: 'utf-8',
|
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
});
|
|
if (gitResult.status === 0 && gitResult.stdout) {
|
|
const gitPath = gitResult.stdout.trim().split(/\r?\n/)[0].trim();
|
|
const gitRoot = path.resolve(path.dirname(gitPath), '..');
|
|
const gitBashCandidates = [
|
|
path.join(gitRoot, 'bin', 'bash.exe'),
|
|
path.join(gitRoot, 'usr', 'bin', 'bash.exe'),
|
|
];
|
|
for (const candidate of gitBashCandidates) {
|
|
if (fs.existsSync(candidate)) return candidate;
|
|
}
|
|
}
|
|
} catch {}
|
|
|
|
// 3. Bundled mingit bash.
|
|
const candidates = [
|
|
path.join(rootDir, 'resources', 'mingit', 'bin', 'bash.exe'),
|
|
path.join(rootDir, 'resources', 'mingit', 'usr', 'bin', 'bash.exe'),
|
|
];
|
|
for (const candidate of candidates) {
|
|
if (fs.existsSync(candidate)) {
|
|
return candidate;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
const targetId = (process.argv[2] || '').trim();
|
|
if (!targetId) {
|
|
console.error('[run-build-openclaw-runtime] Missing target id (example: mac-arm64, win-x64, linux-x64).');
|
|
process.exit(1);
|
|
}
|
|
|
|
const rootDir = path.resolve(__dirname, '..');
|
|
const bashExecutable = resolveBashExecutable(rootDir);
|
|
if (!bashExecutable) {
|
|
console.error('[run-build-openclaw-runtime] bash is required but not found.');
|
|
if (process.platform === 'win32') {
|
|
console.error('[run-build-openclaw-runtime] Install Git Bash or run `npm run setup:mingit` first.');
|
|
}
|
|
process.exit(1);
|
|
}
|
|
|
|
// On Windows, normalise the environment for bash:
|
|
// 1. Bash expects "PATH" (uppercase) but Windows may use "Path" — merge all
|
|
// case-variants into a single uppercase "PATH".
|
|
// 2. Prepend the directory containing the current node binary so that node,
|
|
// npm, pnpm, etc. are findable inside the bash script even when spawned
|
|
// through deeply-nested npm/cmd.exe process chains.
|
|
const env = { ...process.env };
|
|
if (process.platform === 'win32') {
|
|
const nodeDir = path.dirname(process.execPath);
|
|
const pathEntries = Object.entries(env).filter(([k]) => k.toUpperCase() === 'PATH');
|
|
const pathValue = pathEntries.map(([, v]) => v).join(path.delimiter);
|
|
for (const [k] of pathEntries) delete env[k];
|
|
env.PATH = `${nodeDir}${path.delimiter}${pathValue}`;
|
|
}
|
|
|
|
// Use a relative path so bash never sees Windows drive-letter paths like
|
|
// "D:/..." which can fail when invoked through nested npm/cmd.exe chains.
|
|
const scriptPath = 'scripts/build-openclaw-runtime.sh';
|
|
const result = spawnSync(bashExecutable, [scriptPath, targetId], {
|
|
cwd: rootDir,
|
|
env,
|
|
stdio: 'inherit',
|
|
});
|
|
|
|
if (typeof result.status === 'number') {
|
|
process.exit(result.status);
|
|
}
|
|
|
|
process.exit(1);
|