Skip to content

Commit 6096cb0

Browse files
author
Marvin Zhang
committed
feat: Add script to stop running lean-spec processes before rebuilds
1 parent 0aa3eb9 commit 6096cb0

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

scripts/copy-rust-binaries.mjs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,42 @@ function getCurrentPlatform() {
4646
return platformKey;
4747
}
4848

49+
async function killProcessesUsingBinary(binaryPath) {
50+
if (process.platform === 'win32') {
51+
// Windows: use handle.exe or just try to copy
52+
return;
53+
}
54+
55+
try {
56+
// Use lsof to find processes using the binary
57+
const { execSync } = await import('node:child_process');
58+
const output = execSync(`lsof "${binaryPath}" 2>/dev/null || true`, { encoding: 'utf-8' });
59+
60+
if (!output.trim()) {
61+
return; // No processes using the file
62+
}
63+
64+
// Extract PIDs (skip header line)
65+
const lines = output.trim().split('\n').slice(1);
66+
const pids = [...new Set(lines.map(line => line.split(/\s+/)[1]).filter(Boolean))];
67+
68+
if (pids.length > 0) {
69+
console.log(`⚠️ Found ${pids.length} process(es) using ${path.basename(binaryPath)}, stopping them...`);
70+
for (const pid of pids) {
71+
try {
72+
execSync(`kill ${pid}`, { stdio: 'ignore' });
73+
} catch (e) {
74+
// Process might already be dead
75+
}
76+
}
77+
// Give processes time to exit
78+
await new Promise(resolve => setTimeout(resolve, 500));
79+
}
80+
} catch (e) {
81+
// lsof not available or other error, continue anyway
82+
}
83+
}
84+
4985
async function copyBinary(binaryName, platformKey) {
5086
const isWindows = platformKey.startsWith('windows-');
5187
const sourceExt = isWindows ? '.exe' : '';
@@ -67,6 +103,14 @@ async function copyBinary(binaryName, platformKey) {
67103
// Ensure destination directory exists
68104
await fs.mkdir(destDir, { recursive: true });
69105

106+
// Kill any processes using the destination binary
107+
try {
108+
await fs.access(destPath);
109+
await killProcessesUsingBinary(destPath);
110+
} catch (e) {
111+
// Destination doesn't exist yet, that's fine
112+
}
113+
70114
// Copy binary
71115
await fs.copyFile(sourcePath, destPath);
72116

scripts/stop-leanspec-processes.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env bash
2+
# stop-leanspec-processes.sh
3+
# Stops all running lean-spec and leanspec-mcp processes
4+
# Useful before rebuilding or when processes are stuck
5+
6+
echo "🔍 Looking for lean-spec processes..."
7+
8+
# Find all lean-spec related processes (excluding this script and grep)
9+
PIDS=$(ps aux | grep -E "lean-spec|leanspec-mcp" | grep -v grep | grep -v "stop-leanspec-processes" | awk '{print $2}')
10+
11+
if [ -z "$PIDS" ]; then
12+
echo "✅ No lean-spec processes found"
13+
exit 0
14+
fi
15+
16+
echo "🛑 Found processes to stop:"
17+
ps aux | grep -E "lean-spec|leanspec-mcp" | grep -v grep | grep -v "stop-leanspec-processes"
18+
echo ""
19+
20+
for PID in $PIDS; do
21+
echo " Killing PID $PID..."
22+
kill "$PID" 2>/dev/null || true
23+
done
24+
25+
# Wait a moment for processes to exit
26+
sleep 1
27+
28+
# Check if any survived
29+
REMAINING=$(ps aux | grep -E "lean-spec|leanspec-mcp" | grep -v grep | grep -v "stop-leanspec-processes" | wc -l)
30+
31+
if [ "$REMAINING" -gt 0 ]; then
32+
echo "⚠️ Some processes didn't stop, force killing..."
33+
for PID in $PIDS; do
34+
kill -9 "$PID" 2>/dev/null || true
35+
done
36+
fi
37+
38+
echo "✅ All lean-spec processes stopped"

0 commit comments

Comments
 (0)