Skip to main content

Backend-agnostic installer with Dockerfile-style layer caching and resumable installs.

Project description

anchored-install (ai)

English | 简体中文

A backend-agnostic installer with Dockerfile-style layer caching and resumable installs.

Why "anchored"? Every step that succeeds is dropped as an anchor — a checkpoint you can't drift back past. A failed re-run resumes from the last anchor instead of casting off from chapter one.

Write your install steps as a plain list of shell commands. anchored-install runs them one by one and caches each step that succeeds. When a run fails, fix the problem and re-run — already-succeeded steps are skipped and execution resumes from the first unfinished step, instead of starting over from chapter one every time.

  • Resumable — a failed reinstall doesn't repeat everything that already worked.
  • No "is it already installed?" checks — the cache is the state.
  • Backend-agnostic — each line is just a command handed to your shell; if the command works on this machine, ai can run it.
  • It's a normal script — keep the native extension (.sh on Linux). The #ai markers are plain comments, so bash install.sh runs the exact same file natively, with or without ai.
  • Native & portable — pure Python standard library, zero dependencies.

Tested on Ubuntu with bash. Other shells/platforms are a planned extension.

Install

pip install anchored-install        # provides the `ai` command (and `anchored-install`)
# or, from a checkout:
pip install -e .

Requires Python ≥ 3.8 and a POSIX shell (/bin/bash by default).

Quick start

Write a manifest (e.g. install.sh — use the native shell extension) — it's just commands, one logical line per step, and runs as a normal bash script too:

echo "==> setting up"
export BUILD_DIR=/opt/myapp
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"

# Multi-line constructs (if / for / heredoc): wrap them in a block.
#ai >>>
if ! command -v node >/dev/null; then
  curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
  sudo apt-get install -y nodejs
fi
#ai <<<

git clone https://github.com/me/myapp . || git pull
npm ci

# This step runs every time, even when everything else is cached.
#ai: always
echo "installed at $(date)"

Run it:

bash install.sh        # plain native run, no caching (the #ai markers are comments)

ai run install.sh      # execute with caching; cached steps are skipped
ai status install.sh   # show which steps are cached vs pending
ai plan install.sh     # dry-run: parsed steps + cache keys, nothing executed
ai clean install.sh    # forget cached progress for this manifest

If a step fails, ai stops and tells you where. Fix it, run ai run install.sh again, and it picks up exactly where it left off.

The file keeps its native extension (.sh on Linux) and stays a valid shell script — ai adds caching/resume on top without a special file format.

How it works

Steps

  • Each non-comment logical line is one step (\ continues a line).
  • Comments (# ...) and blank lines are ignored and never affect the cache — reformatting comments won't bust anything.
  • #ai >>>#ai <<< collapses several lines into one step (for if/for/heredocs).
  • #ai: always marks the next step to run on every invocation; #ai: name <label> labels it.

Layer caching (chained hashes)

Each step's cache key folds in the previous step's key:

key[i] = sha256(key[i-1] + normalized(step[i].text))

So editing step i invalidates step i and everything after it, while steps 0..i-1 stay cached — exactly Docker's layer model. Appending new steps at the end leaves all earlier steps cached.

Environment carries across steps (and across cached skips)

Steps run in separate shell invocations, yet cd and export still persist: after each successful step ai snapshots the delta it made to the environment and working directory (a Docker-like layer). When a cached step is skipped, its delta is replayed, so later steps still see the right directory and variables — even ones set by steps that didn't re-run.

Cache lives under ~/.cache/anchored-install/<manifest-id>/ (0700), one snapshot file per succeeded step.

CLI reference

ai run    <file> [--no-cache] [--from N] [--workdir DIR] [--shell PATH] [--no-env-snapshot]
ai status <file>
ai plan   <file>
ai clean  <file>
  • --no-cache — ignore existing cache for this run (still records fresh results).
  • --from N — force re-run from step N (1-based) onward.
  • --workdir DIR — starting directory (default: the manifest's own directory).
  • --shell PATH — shell used to run steps (default: $AI_SHELL or /bin/bash).
  • --no-env-snapshot — run each step as an independent subprocess; cd/export no longer carry across steps.

Caveats & trade-offs

  • Success is trusted. If a step's external effect is undone by hand (you manually removed an installed package), ai still considers it done. Use ai clean or ai run --no-cache to rebuild.
  • #ai: always steps re-run, but their text is unchanged, so their cache key (and downstream keys) don't change — downstream steps may still be served from cache. Use always for effects that don't gate later steps (logging, banners).
  • Env snapshots touch disk. They can contain exported secrets; the cache dir is created 0700. Use --no-env-snapshot if you'd rather not persist them.
  • A standalone step whose final command is a failing &&/|| list (e.g. grep x file with no match) is treated as a failure — append || true if that's intentional.

Not yet (planned extensions)

Parallel steps, remote/container backends, Windows/PowerShell, manifest include and variable templating. The parser/executor are layered to make these additive.

Contributing

Contributions are welcome! Please read CONTRIBUTING.md to get set up, and note the Code of Conduct. For questions see SUPPORT.md; to report a vulnerability see SECURITY.md. Release notes live in CHANGELOG.md.

License

MIT © OpenGHz — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

anchored_install-0.1.0.tar.gz (25.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

anchored_install-0.1.0-py3-none-any.whl (17.5 kB view details)

Uploaded Python 3

File details

Details for the file anchored_install-0.1.0.tar.gz.

File metadata

  • Download URL: anchored_install-0.1.0.tar.gz
  • Upload date:
  • Size: 25.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.18

File hashes

Hashes for anchored_install-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d40b94aaa4ad8c13742f4380fd07fa3edfc18ec4a60366b0a6261afbf1ccfd8c
MD5 ca87c1197f22df714396bdbeab8de30d
BLAKE2b-256 12bb32061c43b4d8df85fbf8af6bdeb78669196398c3b6e27cfb005b76fc312a

See more details on using hashes here.

File details

Details for the file anchored_install-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for anchored_install-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9e05a9c7d155b6746b1bccef50b68e8d78a120bc54ea1e3e0a8ccf0c241dc6af
MD5 8d54f37b8100c09e881e05617b4b922b
BLAKE2b-256 3c63afdd7b33e0ea3c6a3071bcbfdc47dd851229a1406001ae4c305f16977b2a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page