# Zero-install: try a project without installing run-site first.
# `--yes` skips the cloning prompt — copy-paste-safe in tutorials/CI.
uv tool run --from django-run-site run-site run --from-git git@github.com:mpasternak/django-multiseek.git --yes
# Same effect once run-site is installed:
run-site run --from-git https://github.com/iplweb/bpp.git --branch main
# Pin to a tag:
run-site run --from-git https://github.com/iplweb/bpp.git --tag v1.0
# Or a specific commit:
run-site run --from-git https://github.com/iplweb/bpp.git --commit a1b2c3d
# Reuse an existing clone, no pull, no reinstall:
run-site run \
--from-git https://github.com/iplweb/bpp.git \
--no-pull --no-install --reuse
# Local checkout from someone else:
run-site run --from-path ~/Downloads/some-django-app
# Sanity check before doing the full run:
run-site doctor --from-git https://github.com/iplweb/bpp.git-
Resolve the checkout path
--checkout-path PATH→ use that path.--no-cache→ fresh tempdir, cleaned up on exit.- default →
~/.cache/run-site/checkouts/<slug>/, where<slug>is extracted from the URL (e.g.iplweb/bppforhttps://github.com/iplweb/bpp.git).
-
Clone or update
- If the path doesn't exist →
git clone. - If it exists and is cache-owned (under
~/.cache/...):git fetch && git reset --hard origin/<ref>— destructive is fine because the cache is CLI-owned. - If it exists and is user-owned (anywhere else):
git status --porcelainfirst; refuse on any uncommitted change. Otherwisegit fetch && git merge --ff-only origin/<ref>. - With
--no-pull: skip the update entirely. - With
--force-reset: explicit opt-in to destructivegit reset --hardeven on user-owned checkouts.
- If the path doesn't exist →
-
Check out the requested ref
--branch BR→git checkout BR && git pull --ff-only origin BR--tag TAG→git checkout tags/TAG--commit SHA→git checkout SHA- default → leave at HEAD of the default branch.
-
Set up the venv
- If
.venv/bin/pythonexists → reuse. - Otherwise →
uv venv .venv(preferred) orpython -m venv .venv. - With
--no-install: skip; error if venv is missing (don't silently fall back to the host Python).
- If
-
Install dependencies
uv.lockpresent →uv sync.pyproject.tomlonly →uv syncif uv is on PATH elsepip install -e ..requirements.txt→pip install -r requirements.txt.- Nothing recognizable → warn and skip.
- The CLI tracks a marker file (
.dev_helpers_installed_marker) so subsequent runs detect when deps files have changed and need reinstall.
-
Run as usual — discover
manage.py, start containers, etc.manage.pyauto-detection scans the repo root,src/, and one or two directories deep (e.g.test_project/manage.py,tests/test_project/manage.py); when severalmanage.pyfiles exist, those that actuallyimport djangoare preferred. Pass--manage-py PATH(relative paths anchor to the cloned root, not your CWD) to override.
--from-git URL runs arbitrary code from the URL — Django's
settings.py, hooks, every dependency pip install -e runs. The CLI does
not sandbox.
Defenses:
- TTY: interactive
Continue with cloning [URL]? [y/N]prompt with a 10s timeout that defaults to no. - Non-TTY (CI, pipes): refuses to proceed unless
--yes/-yis passed. --no-cacheis opt-in — by default the cache survives between runs, sorm -rf ~/.cache/run-site/checkouts/is the user's call.doctor --from-git URLclones + checks config + manage.py without starting containers or runserver. Safer first step.
run-site run \
--from-git https://github.com/myorg/myapp.git \
--branch main \
--reuse \
--yes # required in non-interactive contextUse git's standard auth — SSH keys in ~/.ssh/, or a ~/.netrc/PAT for
HTTPS. The CLI just shells out to git; whatever git can do, it can.
Out of scope for v0.3: explicit --git-token, deploy-key generation, etc.
For environments where you can't pass CLI flags (e.g. CI defining the config alongside the run), put the same info in the config:
[source]
type = "git"
url = "https://github.com/iplweb/bpp.git"
branch = "main"
no_install = falseCLI flags still take precedence.