hpds is the command-line tool for the Stanford Health Policy Data Science lab.
It is a single binary for macOS, Linux, and Windows that does three jobs:
- Scaffold projects from lab templates (
hpds init,hpds use ...). - Set up machines with the lab toolchain (
hpds install ...,hpds setup). - Audit repos against lab standards, locally and across the GitHub org (
hpds audit,hpds audit all).
Formatting and linting are provided by the lab's separate togi tool.
Everything works with zero configuration; hpds.toml only overrides defaults.
The defaults encode several of the lab's agreements.
The install script downloads a prebuilt binary for your platform and places it on your PATH:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/StanfordHPDS/hpds-cli/releases/latest/download/hpds-installer.sh | shOn Windows, use the PowerShell installer:
powershell -ExecutionPolicy Bypass -c "irm https://github.com/StanfordHPDS/hpds-cli/releases/latest/download/hpds-installer.ps1 | iex"With Homebrew:
brew install StanfordHPDS/tap/hpdsFrom source with Cargo (needs a stable Rust toolchain):
cargo install --git https://github.com/StanfordHPDS/hpds-cli hpdsConfirm the install:
$ hpds version
hpds 0.1.0 # no-verifyhpds init walks you through a new or existing project interactively.
For scripts and CI, drive it non-interactively with flags:
$ hpds init
$ hpds init --yes --language both --use pipeline,readmeAdd individual components to a project that already exists.
hpds use with no argument lists what's available:
$ hpds use
$ hpds use hpds.toml
$ hpds use readme
$ hpds use pipeline --kind targetsGenerate Docker, Apptainer, or both container definitions with the project runtime metadata available in the current directory:
$ hpds use container --kind docker --language r
$ hpds use container --kind both --language both --r-version 4.4.3For R projects, --r-version takes precedence over R.Version in
renv.lock. When neither is available, hpds resolves the current R release.
For Python projects, an existing .python-version is copied before the first
locked uv sync; projects without that optional file continue to use their
pyproject.toml and uv.lock metadata. Regenerate the container files if you
add or remove .python-version later. Docker generation also creates a
.dockerignore that excludes host environments and caches while retaining
project source, lockfiles, .Rprofile, and vendored files under renv/.
During a container build, the generated files download the matching hpds
release for Linux amd64 or arm64 and verify its published SHA256 checksum
before installing it.
To use the same locked environment in Visual Studio Code or Positron, first generate a Dockerfile and then add the opt-in Dev Container configuration:
$ hpds use container --kind docker --language both
$ hpds use devcontainerIn either editor, run Dev Containers: Reopen in Container from the Command
Palette. After changing the configuration, run Dev Containers: Rebuild Container. To open the production analysis image interactively outside an editor, use
docker build --target hpds-analysis -t my-project-analysis . and then
docker run --rm -it my-project-analysis.
hpds use devcontainer runs offline. It checks for the generated hpds-dev target
and creates .devcontainer/devcontainer.json plus setup guidance in
.devcontainer/README.md; it does not build or start a container. The editor
workspace is mounted under /workspaces/<checkout-folder>, while Python, R,
and their caches remain under /opt so the source mount cannot hide them.
Existing customized Dockerfiles are validated and left untouched. Projects
with older Dockerfiles must regenerate or manually adopt the hpds-project,
hpds-dev, and final hpds-analysis stage contract first.
The generated configuration uses the checkout folder literally because
Positron does not substitute variables in build arguments. Regenerate it with
hpds use devcontainer --force after renaming the checkout. On Linux, set its
literal HPDS_UID and HPDS_GID arguments from id -u and id -g, then
rebuild. Windows Dev Container use has not yet been validated.
Formatting and linting the code you write there is togi's job (togi format, togi lint). hpds install togi installs the latest stable release by default; run it again to update the installed entry point. Use --version X.Y.Z when you need an exact entry-point release. Project-level togi version locks and dispatch are planned upstream and are not interpreted by hpds.
Fetch the lab's document templates into the current directory:
$ hpds use slides
$ hpds use poster
$ hpds use thesisEach command creates a subdirectory named after its template repository.
Use thesis for the Stanford dissertation and thesis template.
| Component | Template repository | Destination subdirectory |
|---|---|---|
slides |
StanfordHPDS/hpds-slides-theme | hpds-slides-theme/ |
poster |
StanfordHPDS/hpds-poster | hpds-poster/ |
thesis |
StanfordHPDS/typst-stanford-thesis | typst-stanford-thesis/ |
All three commands require network access. For slides and posters, hpds
uses quarto use template when Quarto is on PATH; otherwise it clones
the repository. The thesis template is always cloned. Cloning uses the
GitHub CLI (gh) when available, or git otherwise, and requires Git
even when using gh.
Existing destination directories are refused, including empty directories
and when --force is given. Choose another working directory or move the
existing destination before fetching again.
Install a single tool:
$ hpds install quarto
✓ quarto 1.8.27 already installedhpds setup runs the whole toolchain bundle.
Preview the plan before it runs:
$ hpds setup --plan
$ hpds setup --profile devThe supported way to provision a lab server is:
$ hpds setup --profile server --yesThe Linux-only server profile installs the official Docker Engine packages,
stable Rust, R, Python, Quarto, TinyTeX, RStudio Server, code-server, and the
lab command-line tools. It adds the invoking user to the Docker group, merges
the managed RStudio and code-server preferences, and enables that user's
code-server service. Log in again after the run before using Docker without
sudo. The profile does not install Miniconda, perform a blanket system
upgrade, or reboot the server. dev (the default) installs the toolchain on
your own machine.
Audit the current repo against lab standards, or emit JSON for the bot:
$ hpds audit
errors:
✗ [lifecycle-metadata] the repo has no hpds.toml
fix: run `hpds use hpds.toml`
✗ [readme] the repo has no README
fix: add one, for example with `hpds use readme`
$ hpds audit --format jsonSweep every repo in the org into one report:
$ hpds audit all --limit 50Apply the lab's global git ignore patterns, configure sensible git defaults, and create a repo the lab-manual way:
$ hpds git vaccinate
✓ added 21 ignore pattern(s) to ~/.gitignore
$ hpds git setup
$ hpds repo create- docs/audit-bot.md: how the audit bot files issues and comments on pull requests.
Requires a stable Rust toolchain (Rust 2024 edition; rust-toolchain.toml pins the channel and components).
See CONTRIBUTING.md for the developer workflow. CI requires these gates on Linux, macOS, and Windows (the typos check runs on Linux only):
cargo fmt --check
cargo clippy --all-targets --all-features --locked -- -D warnings
cargo test --locked
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --locked
typosCI also runs cargo test --features online-tests in a separate job that is allowed to fail; those tests exercise the network and real tool downloads and are not required.
Container runtime validation is explicit because it downloads base images and package runtimes. Build hpds, start Docker, and run:
cargo build --locked
python3 tests/container-runtime/run.pyThe harness exits with an error when Docker or its daemon is unavailable. It
builds and runs R, Python, and mixed fixtures, then removes the temporary image
tags it created. Each fixture also checks the installed hpds release. Native
Linux CI exercises Docker with a non-default host UID and validates bind-mount,
environment, source-edit, lock-rebuild, and analysis-target behavior. With
Apptainer installed, pass --engine all to validate both generated formats,
as that CI job does. Where unprivileged Apptainer builds are unavailable, add
--apptainer-build-as-root; runtime checks still execute as the calling user
with a fresh home directory. Real Visual Studio Code and Positron launches are
validated separately on macOS because they require the desktop applications.
MIT. See LICENSE.