#!/usr/bin/env bash set -euo pipefail # TubeSync development environment setup script # Usage: ./scripts/setup-dev.sh REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" PYTHON="${PYTHON:-python3}" # Fail fast if Python is too old (Django 6 requires 3.10+) "${PYTHON}" -c 'import sys; v=sys.version_info; (v.major==3 and v.minor>=10) or (print(f"Error: Python 3.10+ required for Django 6. Found {v.major}.{v.minor}", file=sys.stderr), sys.exit(1))' || exit 1 echo "==> Setting up TubeSync dev environment" echo " Python: $($PYTHON --version)" echo " Repo: $REPO_ROOT" echo # 1. Create a virtualenv if not already in one if [ -z "${VIRTUAL_ENV:-}" ]; then echo "==> Creating virtualenv in .venv/" $PYTHON -m venv "$REPO_ROOT/.venv" source "$REPO_ROOT/.venv/bin/activate" echo " Activated .venv" else echo "==> Using existing virtualenv: $VIRTUAL_ENV" fi # 2. Install dependencies echo "==> Installing dependencies from requirements.txt" pip install --upgrade pip -q pip install -r "$REPO_ROOT/requirements.txt" -q pip install -r "$REPO_ROOT/requirements-dev.txt" -q echo " Done" # 3. Apply yt-dlp patches echo "==> Applying yt-dlp patches" SITE_PACKAGES="$(python -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])')" cp -a "$REPO_ROOT/patches/yt_dlp/"* "$SITE_PACKAGES/yt_dlp/" echo " Patched yt_dlp in $SITE_PACKAGES" # 4. Copy local settings if missing if [ ! -f "$REPO_ROOT/tubesync/tubesync/local_settings.py" ]; then echo "==> Copying local_settings.py.example" cp "$REPO_ROOT/tubesync/tubesync/local_settings.py.example" \ "$REPO_ROOT/tubesync/tubesync/local_settings.py" else echo "==> local_settings.py already exists, skipping" fi # 5. Download Tailwind CSS CLI if not present (verified via asfald) if [ ! -x "$REPO_ROOT/tailwindcss" ]; then echo "==> Downloading Tailwind CSS CLI (with asfald checksum verification)" ARCH="$(uname -m)" OS="$(uname -s | tr '[:upper:]' '[:lower:]')" case "$(uname -s)" in Darwin) OS='macos' ;; Linux) OS='linux' ;; esac case "$(uname -m)" in aarch64|arm64) ARCH='arm64' ;; x86_64) ARCH='x64' ;; esac case "${OS}-${ARCH}" in macos-arm64|macos-x64|linux-arm64|linux-x64) TW_BIN="tailwindcss-${OS}-${ARCH}" ;; *) echo " Unsupported platform: $OS-$ARCH"; TW_BIN="" ;; esac if [ -n "$TW_BIN" ]; then asfald_uri='asfaload/asfald/releases/download/v0.6.0' case "${OS}-${ARCH}" in (linux-arm64) fn='asfald-aarch64-unknown-linux-musl.tar.gz' ;; (linux-x64) fn='asfald-x86_64-unknown-linux-musl.tar.gz' ;; (macos-arm64) fn='asfald-aarch64-apple-darwin.tar.gz' ;; (macos-x64) fn='asfald-x86_64-apple-darwin.tar.gz' ;; esac extract_asfald() { local gtar=; case "$(tar --version 2>/dev/null)" in (*'(GNU tar)'*) gtar=t;; esac; tar --strip-components=1 ${gtar:+--wildcards} -xvvpf "${1}" 'asfald-*/asfald'; } curl -sSLO -- "https://github.com/${asfald_uri}/${fn}" curl -sSL -- "https://gh.checksums.asfaload.com/github.com/${asfald_uri}/checksums.txt" | "${PYTHON}" "${REPO_ROOT}/tubesync/shasum.py" -a sha256 - && extract_asfald "${fn}" && TMPDIR="$(mktemp -d "${REPO_ROOT}/.tmp.XXXXXXXX")" ./asfald -o "${REPO_ROOT}/tailwindcss" -p '${path}/sha256sums.txt' "https://github.com/tailwindlabs/tailwindcss/releases/latest/download/${TW_BIN}" rm -v -f "${fn}" ./asfald unset -v asfald_uri fn rmdir -v "${REPO_ROOT}"/.tmp.* 2>/dev/null || true chmod -v a+rx "${REPO_ROOT}/tailwindcss" echo " Downloaded and verified $TW_BIN" fi else echo "==> Tailwind CSS CLI already present" fi # 6. Compile Tailwind CSS echo "==> Compiling Tailwind CSS" "$REPO_ROOT/tailwindcss" --input "$REPO_ROOT/tubesync/common/static/styles/tailwind/tubesync.css" --output "$REPO_ROOT/tubesync/common/static/styles/tailwind/tubesync-compiled.css" --cwd "$REPO_ROOT" # 7. Run migrations echo "==> Running database migrations" $PYTHON "$REPO_ROOT/tubesync/manage.py" migrate --run-syncdb -v 0 # 8. Collect static files echo "==> Collecting static files" $PYTHON "$REPO_ROOT/tubesync/manage.py" collectstatic --noinput -v 0 echo echo "==> Setup complete!" echo " Activate the virtualenv: source .venv/bin/activate" echo " Run the dev server: cd tubesync && python manage.py runserver" echo " Run tests: cd tubesync && python manage.py test --verbosity=2"