Skip to content

punix store

Content-addressed store queries.

Subcommands

punix store path FILE MODULE              # predicted path (no build)
punix store info [--store-root R]         # store root, artifact count, total size
punix store gc [--deployments-root D]     # GC; honours every generation

punix store path

Print the content-addressed store path a package module would produce, without building it. Uses RealiseDryRun — runs the full parse/check/lower/canonicalise/hash pipeline, stops short of any sandbox/network/IO.

$ punix store path stack.pcl Hello
/Users/you/.punix/store/a1b2c3d4...e9f0-hello-1.0

Exit codes:

  • 0 — success; path printed to stdout.
  • 1 — located [E#] (parse/type/build-closure).
  • 2 — usage (FILE missing, MODULE not a package).

Useful for IDE integration, scripted "did this commit change anything?" checks, and the dev-loop "let's see if the cache will hit before paying the build."

punix store info

Print store statistics (notes/03-specs.md §15): the store root, the number of content-addressed artifacts, and the total size in bytes.

$ punix store info
store: /Users/you/.punix/store
artifacts: 168
size: 5304221184 bytes

Takes no positional arguments; reads --store-root (default ~/.punix/store, override with $PUNIX_STORE_DIR).

punix store gc

Garbage-collect the store. The keep-set is the union of every generation's store_paths across every stack — so any path pinned by any live or rollback-reachable deploy survives.

$ punix store gc --deployments-root /var/lib/punix/deployments
 scanning store: /Users/you/.punix/store
 scanning deployments: /var/lib/punix/deployments
 keep-set: 47 paths (from 2 stacks × 3 generations each)
 would collect: 8 paths (orphans / older trims)
removed: 8 paths, freed ~2.3 GiB

Default flags:

  • --store-root PATH — store to GC. Default ~/.punix/store.
  • --deployments-root PATH — where to look for gen-NNN.json files. Default ~/.punix/deployments.
  • --dry-run — print what would be collected, change nothing.

The keep-set is computed by generation_roots(transport, deployments_root):

def generation_roots(transport, deployments_root):
    keep = set()
    for stack_dir in transport.list_dir(deployments_root):
        for gen_file in transport.list_dir(stack_dir):
            if gen_file.startswith("gen-") and gen_file.endswith(".json"):
                gen = read_generation(transport, gen_file)
                keep.update(gen.store_paths)
    return keep

Conformance: GC never collects a path that's pinned by any gen. If you force-clean the store some other way (rm -rf $store/foo*) and then try to roll back, you get [E12] — see Rollback.

Examples

# Dry-run GC to see what would be removed
punix store gc --dry-run

# Real GC with explicit roots
sudo punix store gc \
  --store-root /var/lib/punix/store \
  --deployments-root /var/lib/punix/deployments

# Predicted store path — no build
punix store path stack.pcl Curl