Skip to content

Releases: ArchiveBox/abxpkg

v1.10.5

14 Apr 23:47
df70e87

Choose a tag to compare

Highlights

  • Fixed provider cache ownership so dependency cache entries no longer masquerade as installed binaries. This makes update / upgrade pick real owning providers again, e.g. brew can upgrade node even when other providers cache node as an upstream dependency.
  • Added shared BinProvider.depends_on_binaries() and BinProvider.installed_binaries() APIs and switched provider sections in abxpkg version to use them directly.
  • Tightened update verification so normal post-update checks reuse cached installer dependencies when appropriate, while explicit --no-cache still forces a fully fresh path.
  • Cleaned up CLI output: provider binary rows in abxpkg version now use a fixed-width version column, non-debug progress logs no longer inherit misleading deep indentation, and shared subprocess stderr/stdout formatting is more consistent.

Docs

  • Updated the README and generated docs to match current defaults and flag behavior, especially around None handling for postinstall_scripts / min_release_age, managed ABXPKG_LIB_DIR install roots, and the current visible CLI surface.

v1.10.4

14 Apr 22:53
4d78ca7

Choose a tag to compare

abxpkg v1.10.4

✨ Highlights

  • Added richer CLI inspection commands with abxpkg version and abxpkg list, including per-provider runtime state, installer provenance, dependency binaries, and installed binary caches.
  • Tightened provider dependency provenance so wrapper providers now record the upstream runtimes they actually depend on (node, python, ruby, installer binaries) instead of flattening everything into the active provider.
  • Improved run --script option merging so same-name script dependencies now contribute defaults to the final run binary without overriding an explicit --binproviders / ABXPKG_BINPROVIDERS selection.
  • Hardened the base provider action flow so nullable security options are resolved to real provider/action defaults before handlers run, instead of leaking None into provider-specific install/update code.

🧭 Quick Examples

abxpkg version
abxpkg version yt-dlp
abxpkg list
abxpkg list env playwright chromium
abxpkg --binproviders=env,uv,pip run yt-dlp --version
abx --global yt-dlp --version
#!/usr/bin/env -S abxpkg run --script node
// /// script
// dependencies = [
//   {name = "node", binproviders = ["env", "brew"], min_version = "22.0.0"},
//   {name = "playwright", binproviders = ["playwright", "pnpm", "npm", "yarn"]},
// ]
// ///

🛠 What Changed

  • Added documented abxpkg version / abxpkg list flows and refreshed the generated docs/site output to match the current provider/runtime model.
  • Refined cache handling so provider-local derived.env entries preserve stable absolute paths, create missing cache directories lazily, and de-duplicate repeated installer/binary lines in global listings.
  • Fixed Binary._binprovider_order() so cached providers are preferred without dropping uncached fallback providers during update/uninstall flows.
  • Made no-op providers like env and bash still resolve and validate binaries during install() / update(), including enforcing min_version on the final loaded binary instead of silently accepting a mismatch.
  • Resolved nullable postinstall_scripts / min_release_age in the base BinProvider.install() / update() / uninstall() path using provider/action defaults, while preserving warnings for unsupported strict values.
  • Tightened installer provenance so INSTALLER_BINARY() now preserves the real upstream provider that loaded the installer binary, instead of re-wrapping everything as if it came from the active provider.
  • Ensured explicit --binproviders / ABXPKG_BINPROVIDERS remain an exact provider allowlist/order during installer and dependency resolution, instead of silently widening back to defaults.
  • Added explicit upstream dependency tracking for wrapper providers that really depend on another runtime binary:
    • npm, pnpm, yarn, playwright, and puppeteer now cache node
    • pip, ansible, and pyinfra now cache python
    • gem now caches ruby
  • Fixed GoGetProvider installer resolution so go is loaded through a proper go version override instead of relying on generic --version probing.
  • Tightened BrewProvider behavior so postinstall_scripts=False is only claimed for brew install, not brew upgrade, which has no equivalent --skip-post-install flag.
  • Improved script-mode dependency merging so same-name dependencies (for example node in run --script node) merge their defaults into the final run binary generically instead of only special-casing min_version.
  • Updated provider summaries and list/version output so installer binaries, upstream dependency binaries, and installed binaries are reported more accurately and with less duplication.

⚠️ Behavioral Changes

  • Explicit provider selection now stays explicit. If you pass --binproviders=... or set ABXPKG_BINPROVIDERS, dependency and installer resolution no longer silently re-add default providers behind your back.
  • install() / update() on read-only/no-op providers still behave as no-ops for mutation, but they now validate the resolved binary and enforce min_version on the result.
  • Passing nullable security fields through provider instances or provider overrides is safer now: None means “use the provider/action default”, not “let a provider handler crash on an assertion”.

v1.10.2

13 Apr 11:03
b677650

Choose a tag to compare

abxpkg v1.10.2

✨ Highlights

  • Renamed the project from abx-pkg / abx_pkg to abxpkg, including the Python package name, docs, examples, and release surface.
  • Added a much richer CLI runtime model around abxpkg run, abx, and abxpkg run --script, with consistent provider ENV/PATH merging for real subprocess execution.
  • Added provider-local derived.env caches for resolved binaries and installer binaries, including version, sha256, mtime, and euid tracking.
  • Tightened provider ownership and provenance reporting so installer binaries, upstream dependency binaries, and installed binaries are surfaced more explicitly.
  • Simplified provider state: much more work now happens lazily at setup() / first-use time instead of during import or construction.

🧭 Quick Examples

pip install abxpkg
abxpkg --global install yt-dlp
abx --binproviders=env,uv,pip,brew yt-dlp --version
abxpkg --min-version=1.2.3 --min-release-age=7 install yt-dlp
abxpkg --overrides='{"pip":{"install_args":["yt-dlp[default]"]}}' install yt-dlp
abxpkg --install-args='["black==24.2.0"]' install black
#!/usr/bin/env -S abxpkg run --script node
// /// script
// dependencies = [
//   {name = "node", binproviders = ["env", "apt", "brew"], min_version = "22.0.0"},
//   {name = "playwright", binproviders = ["pnpm", "npm"]},
// ]
// ///

🛠 What Changed

  • Reworked the core provider engine around the new abxpkg/ package layout and a much larger BinProvider / Binary runtime surface.
  • Added loaded_mtime and loaded_euid alongside loaded_abspath, loaded_version, and loaded_sha256, and threaded them through provider caches, summaries, and binary models.
  • Added provider-local derived.env metadata caching, installer caching, and dependency caching so repeated loads can skip expensive version probes when the fingerprint still matches.
  • Standardized pip and uv install-root layouts so hermetic environments live at <install_root>/venv while provider metadata stays at <install_root>.
  • Hardened install semantics so package-manager success only counts if a runnable binary is actually produced; failed installs now roll back generically in the base provider flow.
  • Split runtime dependency reporting into clearer concepts like INSTALLER_BINARY, depends_on_binaries, and installed_binaries.
  • Extended the CLI with --global as a thin alias for --lib=None, hidden upgrade aliases, richer provider/version reporting, and direct handler-style override flags such as --install-args, --version, --abspath, and --packages.
  • Improved abx so it stays a very thin wrapper over abxpkg run --install ... while still forwarding the expanded CLI surface correctly.
  • Added inline /// script dependency parsing for abxpkg run --script, including [tool.abxpkg] env injection and dependency provider ENV/PATH merging before script execution.
  • Reworked logging output and CLI rendering substantially: quieter non-debug failures, better subprocess output formatting, better method highlighting, and richer provider/version summaries.

⚠️ Behavioral Changes

  • The package/import surface is now abxpkg, not abx-pkg / abx_pkg.
  • CLI managed mode is now the default; use --global or --lib=None to force provider global mode.
  • load() / install() correctness is stricter: providers no longer get to report success unless they can resolve a runnable binary afterward.
  • Provider ownership/provenance is less hand-wavy now: upstream installer/dependency binaries are tracked separately from installed binaries.

v1.9.30

12 Apr 19:39
b2bf7f6

Choose a tag to compare

abx-pkg v1.9.30

✨ Highlights

  • Added abx-pkg run --script, which reads inline /// script metadata blocks so scripts can declare binary dependencies and tool.abx-pkg settings right at the top of the file.
  • Unified managed providers around shared install_root / bin_dir behavior, and made ABX_PKG_LIB_DIR resolve from the live environment so CLI --lib overrides behave consistently.
  • Added first-class --no-cache and --debug CLI controls, and tightened the shared binary lifecycle so load() / install() / update() / uninstall() all speak the same cache semantics.
  • Fixed several installer-resolution and recursion edge cases, while making the real Playwright and Puppeteer test paths much faster instead of faking them.

🧭 Quick Examples

abx-pkg --lib=/tmp/abx --no-cache install yt-dlp
abx-pkg --debug --binproviders=env,npm,playwright run --script node ./capture.js
#!/usr/bin/env -S abx-pkg run --script node

// /// script
// dependencies = [
//   {name = "playwright", binproviders = ["npm", "pnpm"]},
//   {name = "chromium", binproviders = ["playwright", "puppeteer", "apt"], min_version = "131.0.0"},
// ]
// [tool.abx-pkg]
// ABX_PKG_POSTINSTALL_SCRIPTS = true
// ///

🛠 What Changed

  • parse_script_metadata() and run --script now parse comment-prefix-agnostic /// script blocks, resolve declared dependencies before execution, merge [tool.abx-pkg] settings, and preserve child exit codes/stdout/stderr cleanly.
  • The provider constructor surface now consistently prefers install_root and bin_dir, while legacy provider-specific root aliases are still accepted through validation aliases.
  • abx_pkg_install_root_default() now reads ABX_PKG_LIB_DIR from the live environment instead of a module-import snapshot, so CLI --lib and runtime env overrides propagate correctly across providers.
  • Removed load_or_install from the public API / CLI in favor of install(), and promoted no_cache into the shared lifecycle surface for Binary and BinProvider.
  • Hardened installer resolution across providers: fixed detect_euid() recursion, fixed dry-run version probing, corrected Go PATH / env handling, restored Yarn Berry --force behavior for no_cache, and normalized installer-binary abspath handling.
  • Playwright and Puppeteer now share the cleaned install_root / bin_dir model, bootstrap their installer binaries more predictably, and reuse seeded real browser installs in tests to cut redundant downloads.
  • CI now provisions both Yarn classic and Yarn Berry explicitly, pins pnpm to 10.19.0, and uses workflow concurrency cancellation plus job timeouts to prevent stale runs from piling up.
  • README and generated docs were refreshed to match the new CLI, lifecycle, and managed-root behavior.

⚠️ Behavioral Changes

  • Use Binary.install() / abx-pkg install instead of load_or_install.
  • CLI logging now defaults to INFO; enable debug output explicitly with --debug or ABX_PKG_DEBUG=1.
  • --no-cache / ABX_PKG_NO_CACHE=1 now apply consistently across load(), install(), update(), uninstall(), and run.

🧪 Verification

  • uv run prek run --all-files passed on the release commit.
  • Focused real-provider coverage was exercised for Playwright, Puppeteer, Bun, pnpm, Yarn classic, Yarn Berry, and GoGet lifecycle paths.

Thanks to everyone pushing on the install-root cleanup, browser provider edge cases, and CLI ergonomics. 🛠️

v1.9.29

10 Apr 06:31
20cf82c

Choose a tag to compare

abx-pkg v1.9.29

✨ Highlights

  • Added abx-pkg run, a direct exec path that resolves a binary through the configured providers and then hands off execution cleanly.
  • Added abx, a thin abx-pkg --install run ... alias that behaves like a cross-provider npx / uvx / pipx run.
  • Unified provider install-root defaults around ABX_PKG_LIB_DIR, provider-specific ABX_PKG_<NAME>_ROOT overrides, and a platform-aware default lib dir.
  • Added a generated GitHub Pages landing page with a docs build pipeline and a much more structured README.
  • Made provider behavior more explicit by removing silent uv / pnpm auto-switching from PipProvider and NpmProvider.

🧭 Quick Examples

abx yt-dlp --help
abx --binproviders=env,uv,pip,brew yt-dlp --version
abx-pkg --binproviders=pip --install run black --version
export ABX_PKG_LIB_DIR=~/.config/abx/lib
export ABX_PKG_PIP_ROOT=~/.cache/abx/pip

abx-pkg --binproviders=pip,uv install black
abx-pkg --postinstall-scripts=False --min-release-age=7 install yt-dlp

🛠 What Changed

  • Exposed the full Binary / BinProvider configuration surface on the CLI, including install roots, timeouts, release-age controls, postinstall-script policy, and overrides.
  • Hardened the new run / abx command path for macOS, -- handling, bare boolean flags, and child-arg forwarding.
  • Switched the centralized default lib dir to platformdirs, while keeping explicit kwargs and provider-specific env vars highest priority.
  • Landed a GitHub Pages deployment workflow, docs renderer, and generated landing page for the provider matrix and API surface.
  • Propagated security flags to Playwright bootstrap installs and tightened several provider-specific install-root edge cases.
  • Expanded test coverage heavily, especially around the CLI, install-root precedence, and real subprocess execution.

⚠️ Behavioral Changes

  • PipProvider no longer silently falls through to uv; choose UvProvider explicitly when you want uv semantics.
  • NpmProvider no longer silently falls through to pnpm; choose PnpmProvider explicitly when you want pnpm semantics.
  • Providers with isolated install roots now follow one clear precedence order: explicit kwargs > ABX_PKG_<NAME>_ROOT > ABX_PKG_LIB_DIR/<name> > provider default.

🧪 Verification

  • GitHub Actions passed on main for the release line before the version bump.
  • Local checks passed with uv run pyright and focused uv run pytest slices covering the new CLI/install-root work.

Thanks to everyone pushing on the provider edge cases and CLI ergonomics. 🚀

v1.9.28

09 Apr 09:52
9e6374e

Choose a tag to compare

abx-pkg v1.9.28

✨ Highlights

  • Added dedicated providers for uv, pnpm, yarn, bun, deno, and Playwright browser installs, and exported them from the public abx_pkg API.
  • Added a real abx-pkg CLI built with rich-click, including version, install, update, uninstall, load, and load_or_install, plus --lib, --binproviders, and --dry-run.
  • Added centralized install-root defaults via ABX_PKG_LIB_DIR, with per-provider ABX_PKG_<NAME>_ROOT overrides across providers that manage their own install roots.

🧰 What Changed

  • UvProvider now stands on its own instead of piggybacking on PipProvider, with support for both hermetic venv installs and uv tool mode.
  • PnpmProvider, YarnProvider, BunProvider, and DenoProvider each got dedicated implementations with their own install/update/uninstall logic, managed prefixes, and provider-specific security flag handling.
  • Added PlaywrightProvider for browser artifact installs, alongside follow-up improvements to browser-provider path handling and install/load coverage.
  • Provider defaults now honor ABX_PKG_LIB_DIR and provider-specific root env vars consistently, and the repo now includes end-to-end tests covering precedence and on-disk install locations.
  • The generic version probe now skips non-zero --version exits instead of misreading their stderr, and PipProvider now falls back to package metadata when a console script refuses version flags.
  • Ansible and Pyinfra package-install paths were hardened for real-world privilege boundaries, including better interpreter selection for apt-backed Ansible runs and safer brew drop-privilege handling.
  • Packaging metadata was refreshed to ship the console script cleanly and include the new CLI dependency and build layout changes.

🧪 Quality & Docs

  • CI now provisions Yarn 4 via corepack, Bun, Deno, Go, and richer environment diagnostics so the expanded provider matrix is exercised more realistically.
  • Added broad new provider and CLI test coverage, including dedicated suites for uv, pnpm, yarn, bun, deno, playwright, and ABX_PKG_LIB_DIR.
  • README docs were expanded to cover the new providers, environment-variable install-root behavior, and the new CLI, with the Django-specific guidance folded into a single collapsible section.

Thanks to everyone stress-testing the edge cases that made this release sharper. 🛠️

v1.9.25: Rename CustomProvider to BashProvider

03 Apr 06:58
f98fb88

Choose a tag to compare

Highlights

  • Renamed the shell-command provider from CustomProvider / custom to BashProvider / bash.
  • Renamed the provider module to abx_pkg.binprovider_bash, updated lazy exports/imports, and switched the managed-root config from ABX_PKG_CUSTOM_ROOT to ABX_PKG_BASH_ROOT.
  • Renamed provider-specific fields and exported shell env vars to bash_root, bash_bin_dir, BASH_INSTALL_ROOT, and BASH_BIN_DIR.

Behavior

  • Preserved the existing shell-command install/update/uninstall model while keeping install_root and bin_dir aliases working for the renamed provider.
  • Updated the provider lifecycle and security-control tests to exercise the renamed bash provider end to end.
  • Fixed Puppeteer's internal installer binary naming to puppeteer-browsers so the documented/provider-facing name matches the actual binary being bootstrapped.

Documentation

  • Refreshed the README provider list and binprovider sections so the security-option docs match the current implementation.
  • Added and corrected documentation for bash, chromewebstore, and puppeteer, including provider defaults, env-backed security controls, and unsupported-option warning behavior.

Upgrade notes

  • Replace CustomProvider imports with BashProvider.
  • Replace provider name custom with bash in Binary.overrides and any serialized config.
  • Replace custom_root / custom_bin_dir with bash_root / bash_bin_dir.
  • Replace ABX_PKG_CUSTOM_ROOT with ABX_PKG_BASH_ROOT.

v1.9.24

03 Apr 06:43
6096e43

Choose a tag to compare

Highlights

  • Added three new first-class providers: ChromeWebstoreProvider, PuppeteerProvider, and CustomProvider.
  • Packaged the Chrome/extension JS runtime directly inside abx-pkg, so Chrome Web Store installs now work without depending on a sibling abx-plugins checkout.
  • Reworked provider option precedence so per-call args override Binary(...), and Binary(...) overrides provider defaults, with cleaner handling for dry_run, postinstall_scripts, and min_release_age.
  • Improved privilege escalation and subprocess error reporting across providers, including preserving failed sudo output when a fallback attempt also fails.
  • Parallelized CI to run one test file per job with auto-discovered live lifecycle coverage.

New Providers

ChromeWebstoreProvider

  • Added a dedicated Chrome Web Store provider in abx_pkg/binprovider_chromewebstore.py.
  • Supports install_root / bin_dir via extensions_root / extensions_dir.
  • Installs extensions into a managed cache and resolves the installed binary to the unpacked manifest.json.
  • Ships the required JS runtime and config files inside the package:
    • abx_pkg/js/base/config.json
    • abx_pkg/js/base/utils.js
    • abx_pkg/js/chrome/config.json
    • abx_pkg/js/chrome/chrome_utils.js
  • Includes real lifecycle tests covering provider and Binary(...) flows.

PuppeteerProvider

  • Added a dedicated Puppeteer/browser provider in abx_pkg/binprovider_puppeteer.py.
  • Supports provider-managed install roots and bin dirs for @puppeteer/browsers installs.
  • Handles generic browser install args instead of forcing a Chrome-only abstraction.
  • Fixed installed-browser resolution to use semantic version ordering rather than lexicographic string sorting.
  • Includes real lifecycle tests plus regression coverage for version ordering.

CustomProvider

  • Added a dedicated CustomProvider built on top of EnvProvider for shell-command installs.
  • Supports install_root / bin_dir via custom_root / custom_bin_dir.
  • Uses literal per-binary shell overrides for install/update/uninstall while still participating in the standard Binary/BinProvider lifecycle.
  • Includes real lifecycle coverage for direct provider and Binary(...) usage.

Core Behavior Changes

Provider and Binary option precedence

  • Added consistent per-call dry_run support to install(), update(), uninstall(), and load_or_install().
  • Standardized precedence so:
    • explicit action args win
    • Binary(...) defaults come next
    • provider defaults come last
  • Exposed env-backed defaults for:
    • ABX_PKG_INSTALL_TIMEOUT
    • ABX_PKG_VERSION_TIMEOUT
    • ABX_PKG_DRY_RUN (preferred over DRY_RUN when both are set)

Security controls

  • Provider-wide defaults for min_release_age / postinstall_scripts now only hydrate from env vars on providers that actually support those controls.
  • Unsupported providers no longer fail closed by default when these options are present.
  • Instead, unsupported explicit values now warn and continue.
  • EnvProvider no longer claims support for install-only security controls it cannot enforce.
  • pip and npm install-arg merging now preserves explicitly supplied conflicting flags instead of blindly overriding them.

API cleanup

  • binproviders is now the canonical field name used throughout docs/examples instead of binproviders_supported.
  • Module API normalization now handles both provider classes and provider instances consistently.
  • Unavailable-provider errors now use the generic wording:
    • XProvider is disabled because <installer> is not available on this host

Subprocess and Privilege Handling

  • Centralized subprocess error logging in the shared _raise_proc_error(...) path.
  • Reworked older providers to use shared subprocess error handling instead of open-coded log+raise branches.
  • Updated shared exec() behavior to attempt privilege escalation when the provider needs a different EUID, while still falling back to the unprivileged path when escalation is unavailable.
  • When both a sudo attempt and a fallback attempt fail, the final error now includes both outputs.
  • Fixed ansible/pyinfra tempdir cleanup when privileged subprocesses leave root-owned files behind.

Provider-specific Improvements

  • AptProvider, BrewProvider, CargoProvider, GemProvider, GoGetProvider, NixProvider, PipProvider, NpmProvider, PyinfraProvider, AnsibleProvider, and DockerProvider now rely more consistently on shared subprocess/error handling.
  • PipProvider and NpmProvider now merge security controls with explicit install args more rigorously.
  • BrewProvider respects explicit --skip-post-install args when present.
  • PipProvider and NpmProvider gained stronger tests around provider defaults vs per-call overrides.

Packaging and Tooling

  • Added wheel/sdist inclusion rules for packaged JS assets in pyproject.toml.
  • Added bin/setup_monorepo.sh for local monorepo setup.
  • Updated the README to document the new providers, env vars, canonical binproviders field name, and current provider behavior.

CI and Test Coverage

  • Switched the main test workflow to one-job-per-file parallelization.
  • Live lifecycle tests are now auto-discovered from the actual test files instead of being hard-coded.
  • Reduced the standard matrix to:
    • Linux: Python 3.11, 3.14
    • macOS: Python 3.13
  • Added new provider integration suites for:
    • chromewebstore
    • custom
    • puppeteer
  • Expanded coverage for:
    • module API normalization
    • env-backed security defaults
    • unsupported security option warning behavior
    • provider-vs-action override precedence

v1.9.23

02 Apr 16:38
9826e04

Choose a tag to compare

abx-pkg v1.9.23

Highlights

  • 🧪 Replaced the old single-file tests.py runner with a real pytest suite under tests/, with live lifecycle coverage across apt, brew, pip, npm, cargo, gem, goget, nix, docker, pyinfra, and ansible.
uv run pytest -m "not root_required and not docker_required"
  • 🧭 Standardized isolated install layout across providers with shared install_root / bin_dir aliases, while still supporting provider-specific knobs like pip_venv, npm_prefix, cargo_root, gem_home, gopath, nix_profile, and docker_shim_dir.
from pathlib import Path
from abx_pkg import PipProvider

provider = PipProvider(install_root=Path("/tmp/venv"))
print(provider.install_root, provider.bin_dir)
  • ⏱️ Centralized shared provider runtime behavior in BinProvider, including install_timeout, version_timeout, PATH propagation into subprocesses, deep-copy override handling, and safer cache-dir setup.
from abx_pkg import NpmProvider

provider = NpmProvider(install_timeout=120, version_timeout=10)
binary = provider.install("zx")

Provider Fixes

  • 🔒 Fixed security override precedence so explicit install_args can adjust effective security behavior before fail-closed checks run, especially for npm --ignore-scripts and --min-release-age=....
from abx_pkg import NpmProvider

provider = NpmProvider(min_release_age=36500).get_provider_with_overrides(
    overrides={"zx": {"install_args": ["zx", "--min-release-age=0"]}},
)
  • 🐳 Improved version detection for multiline banners by teaching SemVer.parse(...) to scan up to 5 lines. This fixes wrappers and tools whose version appears after a heading line, including Docker-backed command shims.
from abx_pkg import SemVer

SemVer.parse(
    "ShellCheck - shell script analysis tool\nversion: v0.11.0-65-gcd41f79"
)
# -> SemVer("0.11.0")
  • 🧰 Tightened provider-specific behavior across the built-ins:
    • apt / brew helper backends now use resolved install_args
    • cargo uninstall no longer reuses incompatible version-pinned install flags
    • nix uninstall preserves other entries in the same profile
    • goget is now the canonical provider name throughout the package and docs
    • Binary.abspaths is available as a backward-compatible read alias for loaded_abspaths

Docs And DX

  • 📚 Refreshed the README API reference with verified provider defaults, install roots, security controls, timeout behavior, override support, and direct source/test links.
  • 🛠️ Updated the development workflow docs to match the current toolchain and test layout.
uv sync --all-extras --all-groups
uv run prek run --all-files
uv run pytest -sx tests/

v1.9.22

02 Apr 07:34
fbeef29

Choose a tag to compare

✨ Highlights

  • 🔒 Security defaults now propagate consistently across binaries and providers.

    • BinProvider now owns default postinstall_scripts and min_release_age values, and Binary inherits them automatically when you don't override them explicitly.
    • Unsupported providers now fail closed instead of silently ignoring security constraints.
    provider = EnvProvider(postinstall_scripts=True, min_release_age=4)
    binary = Binary(name="python", binproviders=[provider])
    assert binary.postinstall_scripts is True
    assert binary.min_release_age == 4
  • ⬆️ min_version is enforced end-to-end instead of only being advisory.

    • install() and update() now validate the resolved version after the package manager runs.
    • load_or_install() will upgrade an already-installed binary when it exists but does not satisfy the requested minimum version.
    binary = provider.load_or_install("black", min_version=SemVer("24.0.0"))
  • 📦 Provider install/update plumbing is more explicit and consistent.

    • Core handler signatures now thread postinstall_scripts, min_release_age, and min_version through setup/install/update paths.
    • pip and npm explicitly declare support for release-age and postinstall controls.
    • brew only uses Pyinfra/Ansible helper paths when postinstall scripts are allowed, and otherwise falls back to direct CLI invocations with the right flags.
    • Timeout settings are preserved through provider copies via model fields instead of hidden underscored state.
  • 🧪 Tests were expanded around the new behavior and cleaned up for strict type-checking.

    • Added fail-closed coverage for providers that cannot honor min_release_age or disabled postinstall scripts.
    • Added live tests for pip minimum-version upgrades and npm postinstall-script overrides.
    • Tightened the test helper typing so ty-check and pyright pass without cast, Any, or type: ignore shortcuts.
    def is_install_args_sequence(value: object) -> TypeGuard[InstallArgs]:
        return isinstance(value, (tuple, list)) and all(isinstance(item, str) for item in value)
  • 🏷️ Release metadata

    • Version bumped to 1.9.22.
    • uv.lock refreshed to match the new package version.