118 lines
3.7 KiB
Bash
118 lines
3.7 KiB
Bash
#!/bin/bash
|
|
#
|
|
# install-system-deps.sh - Install optional system dependencies
|
|
#
|
|
# Reads config/system-deps.json and installs missing packages
|
|
# using the detected package manager (apt, brew, dnf, etc.)
|
|
#
|
|
# Usage: ./scripts/install-system-deps.sh [--dry-run]
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
DEPS_FILE="$PROJECT_DIR/config/system-deps.json"
|
|
DRY_RUN="${1:-}"
|
|
|
|
if [[ "$DRY_RUN" == "-h" || "$DRY_RUN" == "--help" ]]; then
|
|
echo "Usage: install-system-deps.sh [--dry-run]"
|
|
echo " --dry-run Show what would be installed without installing"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ ! -f "$DEPS_FILE" ]]; then
|
|
echo "Error: $DEPS_FILE not found"
|
|
exit 1
|
|
fi
|
|
|
|
echo "🦞 OpenClaw Command Center - System Dependencies"
|
|
echo "================================================="
|
|
echo ""
|
|
|
|
# Let node do all the heavy lifting — it parses the JSON, detects the
|
|
# platform/package-manager/chip, checks which binaries exist, and
|
|
# prints shell commands to stdout for us to eval.
|
|
node -e "
|
|
const { execSync } = require('child_process');
|
|
const os = require('os');
|
|
const deps = require('$DEPS_FILE');
|
|
|
|
const platform = process.platform === 'linux' ? 'linux' : process.platform === 'darwin' ? 'darwin' : null;
|
|
if (!platform) { console.log('echo \"Unsupported platform\"'); process.exit(0); }
|
|
|
|
// Detect package manager
|
|
const pmCandidates = platform === 'linux'
|
|
? ['apt', 'dnf', 'yum', 'pacman', 'apk']
|
|
: ['brew'];
|
|
let pkgManager = null;
|
|
for (const pm of pmCandidates) {
|
|
try { execSync('which ' + pm, { stdio: 'ignore' }); pkgManager = pm; break; } catch {}
|
|
}
|
|
|
|
console.log('Platform: ' + platform);
|
|
console.log('Package manager: ' + (pkgManager || 'none'));
|
|
console.log('');
|
|
|
|
if (!pkgManager) {
|
|
console.log('No supported package manager found.');
|
|
console.log('Supported: apt, dnf, yum, pacman, apk, brew');
|
|
process.exit(1);
|
|
}
|
|
|
|
// Detect chip
|
|
let isAppleSilicon = false;
|
|
if (platform === 'darwin') {
|
|
try {
|
|
const chip = execSync('sysctl -n machdep.cpu.brand_string', { encoding: 'utf8' });
|
|
isAppleSilicon = /apple/i.test(chip);
|
|
} catch {}
|
|
}
|
|
|
|
const entries = deps[platform] || [];
|
|
let installed = 0, toInstall = 0;
|
|
|
|
for (const dep of entries) {
|
|
if (dep.condition === 'intel' && isAppleSilicon) continue;
|
|
const cmd = dep.install[pkgManager];
|
|
if (!cmd) continue;
|
|
|
|
let hasBinary = false;
|
|
try { execSync('which ' + dep.binary, { stdio: 'ignore' }); hasBinary = true; } catch {}
|
|
if (!hasBinary && dep.binary === 'osx-cpu-temp') {
|
|
try { execSync('test -x ' + os.homedir() + '/bin/osx-cpu-temp', { stdio: 'ignore' }); hasBinary = true; } catch {}
|
|
}
|
|
|
|
if (hasBinary) {
|
|
console.log('✅ ' + dep.name + ' — already installed (' + dep.purpose + ')');
|
|
installed++;
|
|
} else {
|
|
toInstall++;
|
|
if ('$DRY_RUN' === '--dry-run') {
|
|
console.log('📦 ' + dep.name + ' — would install (' + dep.purpose + ')');
|
|
console.log(' Command: ' + cmd);
|
|
} else {
|
|
console.log('📦 Installing ' + dep.name + ' — ' + dep.purpose + '...');
|
|
console.log(' Running: ' + cmd);
|
|
try {
|
|
execSync(cmd, { stdio: 'inherit' });
|
|
console.log(' ✅ Installed successfully');
|
|
} catch (e) {
|
|
console.log(' ⚠️ Install failed: ' + e.message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log('');
|
|
if ('$DRY_RUN' === '--dry-run') {
|
|
console.log('Dry run complete. ' + installed + ' already installed, ' + toInstall + ' would be installed.');
|
|
} else {
|
|
console.log('Done! ' + installed + ' already installed, ' + toInstall + ' newly installed.');
|
|
if (toInstall > 0) {
|
|
console.log('');
|
|
console.log('Restart the Command Center to see enhanced vitals.');
|
|
}
|
|
}
|
|
"
|