-
Notifications
You must be signed in to change notification settings - Fork 228
Expand file tree
/
Copy pathcodemachine.js
More file actions
executable file
·136 lines (120 loc) · 4.4 KB
/
codemachine.js
File metadata and controls
executable file
·136 lines (120 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env bun
/**
* Shell wrapper for CodeMachine CLI
*
* This wrapper detects the user's platform and spawns the correct
* platform-specific binary from the appropriate optional dependency.
*
* The actual binaries are distributed as separate packages:
* - codemachine-linux-x64
* - codemachine-darwin-arm64
* - codemachine-darwin-x64
* - codemachine-windows-x64
*/
import { spawn } from 'node:child_process';
import { join, dirname, isAbsolute, resolve } from 'node:path';
import { existsSync, readFileSync } from 'node:fs';
import { platform, arch } from 'node:os';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT_FALLBACK = join(__dirname, '..');
function findPackageRoot(startDir) {
let current = startDir;
const maxDepth = 10;
let depth = 0;
while (current && depth < maxDepth) {
const candidate = join(current, 'package.json');
if (existsSync(candidate)) {
try {
const pkg = JSON.parse(readFileSync(candidate, 'utf8'));
if (pkg?.name === 'codemachine') {
return current;
}
} catch {
// ignore malformed package.json
}
}
const parent = dirname(current);
if (parent === current) break;
current = parent;
depth++;
}
return undefined;
}
const DEFAULT_PACKAGE_ROOT = findPackageRoot(ROOT_FALLBACK) ?? ROOT_FALLBACK;
function runBinary(binaryPath, packageRoot) {
const child = spawn(binaryPath, process.argv.slice(2), {
stdio: 'inherit',
windowsHide: false,
env: {
...process.env,
CODEMACHINE_PACKAGE_ROOT: packageRoot,
CODEMACHINE_PACKAGE_JSON: join(packageRoot, 'package.json'),
},
});
child.on('exit', (code, signal) => {
if (signal) {
process.kill(process.pid, signal);
} else {
process.exit(code ?? 1);
}
});
child.on('error', (error) => {
console.error('Error spawning binary:', error.message);
process.exit(1);
});
}
// Map Node.js platform/arch to our package names
const platformMap = {
'linux-x64': { pkg: 'codemachine-linux-x64', bin: 'codemachine' },
'linux-arm64': { pkg: 'codemachine-linux-arm64', bin: 'codemachine' },
'darwin-arm64': { pkg: 'codemachine-darwin-arm64', bin: 'codemachine' },
'darwin-x64': { pkg: 'codemachine-darwin-x64', bin: 'codemachine' },
'win32-x64': { pkg: 'codemachine-windows-x64', bin: 'codemachine.exe' },
};
const envBinary = process.env.CODEMACHINE_BIN_PATH;
if (envBinary) {
const resolvedEnvBinary = isAbsolute(envBinary) ? envBinary : resolve(process.cwd(), envBinary);
if (!existsSync(resolvedEnvBinary)) {
console.error(`Error: CODEMACHINE_BIN_PATH target not found (${resolvedEnvBinary})`);
process.exit(1);
}
const envRoot = findPackageRoot(dirname(resolvedEnvBinary)) ?? DEFAULT_PACKAGE_ROOT;
runBinary(resolvedEnvBinary, envRoot);
} else {
const currentPlatform = platform();
const currentArch = arch();
const platformKey = `${currentPlatform}-${currentArch}`;
const platformConfig = platformMap[platformKey];
if (!platformConfig) {
console.error(`Error: Unsupported platform ${platformKey}`);
console.error(`Supported platforms: ${Object.keys(platformMap).join(', ')}`);
process.exit(1);
}
// Try to find the platform-specific binary in multiple locations
const searchPaths = [
// 1. Nested node_modules (npm < 7 behavior)
join(ROOT_FALLBACK, 'node_modules', platformConfig.pkg, platformConfig.bin),
// 2. Hoisted to parent node_modules (npm >= 7 behavior, pnpm, yarn)
join(ROOT_FALLBACK, '..', platformConfig.pkg, platformConfig.bin),
// 3. Global install location (try to resolve from parent of codemachine)
join(dirname(ROOT_FALLBACK), platformConfig.pkg, platformConfig.bin),
];
let binaryPath = null;
for (const path of searchPaths) {
if (existsSync(path)) {
binaryPath = path;
break;
}
}
if (!binaryPath) {
console.error(`Error: Platform binary not found. Searched:`);
searchPaths.forEach((p) => console.error(` - ${p}`));
console.error(`\nThe ${platformConfig.pkg} package may not be installed.`);
console.error(`This is likely because your platform is not supported as an optional dependency.`);
console.error(`\nTry reinstalling: npm install -g codemachine`);
console.error(`\nPlease report this issue at: https://github.com/moazbuilds/CodeMachine-CLI/issues`);
process.exit(1);
}
runBinary(binaryPath, DEFAULT_PACKAGE_ROOT);
}