Built a universal manager and installer for all operating systems and environments. Bumped a lot of versions of things. Still needs deep testing.
This commit is contained in:
173
run_mac.zsh
173
run_mac.zsh
@@ -1,5 +1,9 @@
|
||||
#!/usr/bin/env zsh
|
||||
# Update-and-run script for macOS — portable Python 3.12 + PyTorch
|
||||
# Update-and-run script for macOS — thin bootstrap over the in-repo manager.
|
||||
#
|
||||
# Everything (venv via uv-managed Python, torch, requirements, portable
|
||||
# Node.js and FFmpeg, dependency updates) is handled by `python -m manager`;
|
||||
# this script only makes sure uv + a Python interpreter exist, then delegates.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
@@ -17,150 +21,37 @@ BANNER
|
||||
echo "\033[0m"
|
||||
echo "\033[90m macOS Setup & Launcher\033[0m"
|
||||
echo ""
|
||||
VENV_DIR="$SCRIPT_DIR/.venv"
|
||||
PIP="$VENV_DIR/bin/pip"
|
||||
PYTHON="$VENV_DIR/bin/python3"
|
||||
PYTHON_VERSION="3.12.8"
|
||||
RELEASE_TAG="20241219"
|
||||
|
||||
# --- Package versions (update these as needed) ---
|
||||
NODE_VERSION="23.11.1"
|
||||
TORCH_VERSION="2.11.0"
|
||||
TORCHVISION_VERSION="0.26.0"
|
||||
TORCHAUDIO_VERSION="2.11.0"
|
||||
|
||||
# Detect architecture
|
||||
ARCH="$(uname -m)"
|
||||
if [[ "$ARCH" == "arm64" ]]; then
|
||||
PLATFORM="aarch64-apple-darwin"
|
||||
elif [[ "$ARCH" == "x86_64" ]]; then
|
||||
PLATFORM="x86_64-apple-darwin"
|
||||
else
|
||||
echo "Error: Unsupported architecture: $ARCH"
|
||||
exit 1
|
||||
# ── 1. Ensure uv (prebuilt static binary, kept inside the repo) ─────
|
||||
export PATH="$SCRIPT_DIR/.uv:$PATH"
|
||||
export UV_PYTHON_INSTALL_DIR="$SCRIPT_DIR/.uv/python"
|
||||
if ! command -v uv >/dev/null 2>&1; then
|
||||
echo "Downloading uv (package/python manager) into .uv/ ..."
|
||||
curl -LsSf https://astral.sh/uv/install.sh | \
|
||||
UV_INSTALL_DIR="$SCRIPT_DIR/.uv" UV_NO_MODIFY_PATH=1 sh
|
||||
fi
|
||||
|
||||
# ── 1. Download standalone Python if needed ─────────────────────────
|
||||
PYTHON_DIR="$SCRIPT_DIR/.python"
|
||||
PYTHON_BIN="$PYTHON_DIR/bin/python3"
|
||||
|
||||
if [[ ! -x "$PYTHON_BIN" ]]; then
|
||||
TARBALL="cpython-${PYTHON_VERSION}+${RELEASE_TAG}-${PLATFORM}-install_only.tar.gz"
|
||||
URL="https://github.com/indygreg/python-build-standalone/releases/download/${RELEASE_TAG}/${TARBALL}"
|
||||
|
||||
TMPDIR_DL="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMPDIR_DL"' EXIT
|
||||
|
||||
echo "Downloading standalone Python ${PYTHON_VERSION} (${PLATFORM})..."
|
||||
curl -fSL --progress-bar -o "$TMPDIR_DL/$TARBALL" "$URL"
|
||||
|
||||
echo "Extracting..."
|
||||
tar -xzf "$TMPDIR_DL/$TARBALL" -C "$TMPDIR_DL"
|
||||
|
||||
# Move to permanent location (the archive extracts to a "python" folder)
|
||||
rm -rf "$PYTHON_DIR"
|
||||
mv "$TMPDIR_DL/python" "$PYTHON_DIR"
|
||||
|
||||
rm -rf "$TMPDIR_DL"
|
||||
trap - EXIT
|
||||
|
||||
echo "Standalone Python installed to $PYTHON_DIR"
|
||||
fi
|
||||
|
||||
# ── 2. Create venv if it doesn't exist ──────────────────────────────
|
||||
if [[ ! -d "$VENV_DIR" ]]; then
|
||||
echo "Creating virtual environment at $VENV_DIR..."
|
||||
"$PYTHON_BIN" -m venv "$VENV_DIR"
|
||||
echo "Virtual environment created."
|
||||
fi
|
||||
|
||||
# ── 3. Download / update portable Node.js ──────────────────────────
|
||||
NODE_DIR="$SCRIPT_DIR/.node"
|
||||
NODE_BIN="$NODE_DIR/bin/node"
|
||||
|
||||
NEED_NODE=false
|
||||
if [[ ! -x "$NODE_BIN" ]]; then
|
||||
NEED_NODE=true
|
||||
elif [[ "$("$NODE_BIN" --version 2>/dev/null)" != "v${NODE_VERSION}" ]]; then
|
||||
echo "Node.js version mismatch (want v${NODE_VERSION}, have $("$NODE_BIN" --version))."
|
||||
NEED_NODE=true
|
||||
fi
|
||||
|
||||
if $NEED_NODE; then
|
||||
if [[ "$ARCH" == "arm64" ]]; then
|
||||
NODE_ARCH="arm64"
|
||||
else
|
||||
NODE_ARCH="x64"
|
||||
fi
|
||||
|
||||
NODE_TARBALL="node-v${NODE_VERSION}-darwin-${NODE_ARCH}.tar.gz"
|
||||
NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TARBALL}"
|
||||
|
||||
TMPDIR_DL="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMPDIR_DL"' EXIT
|
||||
|
||||
echo "Downloading Node.js v${NODE_VERSION} (darwin-${NODE_ARCH})..."
|
||||
curl -fSL --progress-bar -o "$TMPDIR_DL/$NODE_TARBALL" "$NODE_URL"
|
||||
|
||||
echo "Extracting..."
|
||||
tar -xzf "$TMPDIR_DL/$NODE_TARBALL" -C "$TMPDIR_DL"
|
||||
|
||||
rm -rf "$NODE_DIR"
|
||||
mv "$TMPDIR_DL/node-v${NODE_VERSION}-darwin-${NODE_ARCH}" "$NODE_DIR"
|
||||
|
||||
rm -rf "$TMPDIR_DL"
|
||||
trap - EXIT
|
||||
|
||||
echo "Node.js v${NODE_VERSION} installed to $NODE_DIR"
|
||||
else
|
||||
echo "Node.js v${NODE_VERSION} is up to date."
|
||||
fi
|
||||
|
||||
# ── 4. Install / update PyTorch packages ────────────────────────────
|
||||
# Helper: returns 0 if the package is installed at the exact version
|
||||
pkg_ok() {
|
||||
local pkg="$1" want="$2"
|
||||
local got
|
||||
got="$("$PIP" show "$pkg" 2>/dev/null | awk '/^Version:/{print $2}')" || true
|
||||
[[ "$got" == "$want" ]]
|
||||
# ── 2. Find a Python to run the manager (stdlib-only, needs >= 3.9) ─
|
||||
find_python() {
|
||||
for cmd in python3 python; do
|
||||
if command -v "$cmd" >/dev/null 2>&1; then
|
||||
if "$cmd" -c 'import sys; sys.exit(0 if sys.version_info >= (3, 9) else 1)' 2>/dev/null; then
|
||||
echo "$cmd"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
PKGS_TO_INSTALL=()
|
||||
|
||||
pkg_ok "torch" "$TORCH_VERSION" || PKGS_TO_INSTALL+=("torch==$TORCH_VERSION")
|
||||
pkg_ok "torchvision" "$TORCHVISION_VERSION" || PKGS_TO_INSTALL+=("torchvision==$TORCHVISION_VERSION")
|
||||
pkg_ok "torchaudio" "$TORCHAUDIO_VERSION" || PKGS_TO_INSTALL+=("torchaudio==$TORCHAUDIO_VERSION")
|
||||
|
||||
if (( ${#PKGS_TO_INSTALL[@]} )); then
|
||||
echo "Installing / updating: ${PKGS_TO_INSTALL[*]}"
|
||||
"$PIP" install "${PKGS_TO_INSTALL[@]}"
|
||||
else
|
||||
echo "PyTorch packages are up to date."
|
||||
PYTHON="$(find_python || true)"
|
||||
if [[ -z "$PYTHON" ]]; then
|
||||
echo "No system Python found — provisioning one with uv..."
|
||||
uv python install 3.12
|
||||
PYTHON="$(uv python find 3.12)"
|
||||
fi
|
||||
|
||||
# ── 5. Install / update requirements.txt ────────────────────────────
|
||||
REQUIREMENTS="$SCRIPT_DIR/requirements.txt"
|
||||
REQ_HASH_FILE="$VENV_DIR/.requirements_hash"
|
||||
|
||||
if [[ -f "$REQUIREMENTS" ]]; then
|
||||
# Hash all requirements files (follows -r includes)
|
||||
CURRENT_HASH="$(cat "$SCRIPT_DIR"/requirements*.txt 2>/dev/null | shasum -a 256 | awk '{print $1}')"
|
||||
STORED_HASH=""
|
||||
[[ -f "$REQ_HASH_FILE" ]] && STORED_HASH="$(cat "$REQ_HASH_FILE")"
|
||||
|
||||
if [[ "$CURRENT_HASH" != "$STORED_HASH" ]]; then
|
||||
echo "Installing / updating requirements.txt..."
|
||||
"$PIP" install -r "$REQUIREMENTS"
|
||||
echo "$CURRENT_HASH" > "$REQ_HASH_FILE"
|
||||
else
|
||||
echo "Requirements are up to date."
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── 6. Build and start the UI ───────────────────────────────────────
|
||||
export PATH="$NODE_DIR/bin:$VENV_DIR/bin:$PATH"
|
||||
|
||||
echo ""
|
||||
echo "Starting UI..."
|
||||
cd "$SCRIPT_DIR/ui"
|
||||
npm run build_and_start
|
||||
# ── 3. Sync the environment and start the UI ────────────────────────
|
||||
cd "$SCRIPT_DIR"
|
||||
"$PYTHON" -m manager update --auto
|
||||
exec "$PYTHON" -m manager launch
|
||||
|
||||
Reference in New Issue
Block a user