Building sdists runs dependency build code on the host (RCE surface, no
sandbox), is non-hermetic/non-reproducible, needs a toolchain, and is
host-arch-only for compiled packages -- all at odds with pymage's guarantees.
Remove the builder and --build-sdists opt-in; keep sdist parsing only so the
error can explain the package is sdist-only and point at the --find-links
pre-build workflow.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
Caching (layer blobs, downloaded wheels, base interpreter detection) is now
enabled by default at the per-user cache dir (or --cache-dir / $PYMAGE_CACHE_DIR).
--no-cache disables it: layer/meta caches off and wheels downloaded into an
ephemeral temp dir that's cleaned up after the build.
- setupCaches centralizes cache wiring (one cache.Cache serves layers + meta);
--no-cache uses a temp wheel dir with cleanup
- DefaultCacheDir honors $PYMAGE_CACHE_DIR; cli tests point it at a temp dir so
the on-by-default cache doesn't touch the user's cache
- tests: setupCaches (default + --no-cache cleanup); README/config updated
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
A no-op build's ~2-3s was almost all registry I/O:
- the base index was fetched 3x (BasePlatforms + remote.Image per platform)
- the base's top layer was downloaded once per platform every build to read
/etc/apko.json for interpreter detection (Chainguard has no PYTHON_VERSION)
Changes:
- build.BaseSet resolves the base reference once and serves per-platform child
images memoized (index fetched once; verified by TestBaseSet)
- cache the detected interpreter version by base digest in a default per-user
metadata cache (cache.GetText/PutText), so repeat builds skip the apko layer
download
- lazy wheel-cache dir creation; wheelhouse.Resolve defaults to the per-user
cache dir
Tests: TestBaseSet (index fetched once + per-platform memoized), TestCachedInterpreter
(write + cache-hit short-circuit), cache text round-trip.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
- src-layout PYTHONPATH is now derived from --workdir (project exposes SrcLayout;
CLI computes <workdir>/src) instead of hard-coding /app/src
- wheelhouse.Resolve defaults to the per-user wheel cache dir so lock-based
downloads work; cache dir creation is lazy so local-only resolution is hermetic
- --max-layers error message matches the accepted range (>= 0)
- DiscoverLock error lists requirements.lock too
- tests for the workdir-derived PYTHONPATH and python-prefix
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
go-containerregistry already uploads layers (and index children) concurrently,
but only at its default of 4. Set remote.WithJobs explicitly with an auto
default that scales with CPU count (floor 4), plus a --push-concurrency flag and
[tool.pymage] push-concurrency config to tune it.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
Default --layer-strategy is now 'auto'. Adds max-layers (default 127) and
max-wheel-layers config keys/flags with validation. Documents the layer budget
and reuse-stable bin packing in README and DESIGN.
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>