Releases: ArchiveBox/abxpkg
Releases · ArchiveBox/abxpkg
v1.10.5
Highlights
- Fixed provider cache ownership so dependency cache entries no longer masquerade as installed binaries. This makes
update/upgradepick real owning providers again, e.g.brewcan upgradenodeeven when other providers cachenodeas an upstream dependency. - Added shared
BinProvider.depends_on_binaries()andBinProvider.installed_binaries()APIs and switched provider sections inabxpkg versionto use them directly. - Tightened update verification so normal post-update checks reuse cached installer dependencies when appropriate, while explicit
--no-cachestill forces a fully fresh path. - Cleaned up CLI output: provider binary rows in
abxpkg versionnow 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
Nonehandling forpostinstall_scripts/min_release_age, managedABXPKG_LIB_DIRinstall roots, and the current visible CLI surface.
v1.10.4
abxpkg v1.10.4
✨ Highlights
- Added richer CLI inspection commands with
abxpkg versionandabxpkg 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 --scriptoption merging so same-name script dependencies now contribute defaults to the final run binary without overriding an explicit--binproviders/ABXPKG_BINPROVIDERSselection. - Hardened the base provider action flow so nullable security options are resolved to real provider/action defaults before handlers run, instead of leaking
Noneinto provider-specific install/update code.
🧭 Quick Examples
abxpkg version
abxpkg version yt-dlp
abxpkg list
abxpkg list env playwright chromiumabxpkg --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 listflows and refreshed the generated docs/site output to match the current provider/runtime model. - Refined cache handling so provider-local
derived.enventries 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
envandbashstill resolve and validate binaries duringinstall()/update(), including enforcingmin_versionon the final loaded binary instead of silently accepting a mismatch. - Resolved nullable
postinstall_scripts/min_release_agein the baseBinProvider.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_BINPROVIDERSremain 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, andpuppeteernow cachenodepip,ansible, andpyinfranow cachepythongemnow cachesruby
- Fixed
GoGetProviderinstaller resolution sogois loaded through a propergo versionoverride instead of relying on generic--versionprobing. - Tightened
BrewProviderbehavior sopostinstall_scripts=Falseis only claimed forbrew install, notbrew upgrade, which has no equivalent--skip-post-installflag. - Improved script-mode dependency merging so same-name dependencies (for example
nodeinrun --script node) merge their defaults into the final run binary generically instead of only special-casingmin_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 setABXPKG_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 enforcemin_versionon the result.- Passing nullable security fields through provider instances or provider overrides is safer now:
Nonemeans “use the provider/action default”, not “let a provider handler crash on an assertion”.
v1.10.2
abxpkg v1.10.2
✨ Highlights
- Renamed the project from
abx-pkg/abx_pkgtoabxpkg, including the Python package name, docs, examples, and release surface. - Added a much richer CLI runtime model around
abxpkg run,abx, andabxpkg run --script, with consistent provider ENV/PATH merging for real subprocess execution. - Added provider-local
derived.envcaches for resolved binaries and installer binaries, includingversion,sha256,mtime, andeuidtracking. - 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 --versionabxpkg --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 largerBinProvider/Binaryruntime surface. - Added
loaded_mtimeandloaded_euidalongsideloaded_abspath,loaded_version, andloaded_sha256, and threaded them through provider caches, summaries, and binary models. - Added provider-local
derived.envmetadata caching, installer caching, and dependency caching so repeated loads can skip expensive version probes when the fingerprint still matches. - Standardized
pipanduvinstall-root layouts so hermetic environments live at<install_root>/venvwhile 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, andinstalled_binaries. - Extended the CLI with
--globalas a thin alias for--lib=None, hiddenupgradealiases, richer provider/version reporting, and direct handler-style override flags such as--install-args,--version,--abspath, and--packages. - Improved
abxso it stays a very thin wrapper overabxpkg run --install ...while still forwarding the expanded CLI surface correctly. - Added inline
/// scriptdependency parsing forabxpkg 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, notabx-pkg/abx_pkg. - CLI managed mode is now the default; use
--globalor--lib=Noneto 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
abx-pkg v1.9.30
✨ Highlights
- Added
abx-pkg run --script, which reads inline/// scriptmetadata blocks so scripts can declare binary dependencies andtool.abx-pkgsettings right at the top of the file. - Unified managed providers around shared
install_root/bin_dirbehavior, and madeABX_PKG_LIB_DIRresolve from the live environment so CLI--liboverrides behave consistently. - Added first-class
--no-cacheand--debugCLI controls, and tightened the shared binary lifecycle soload()/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()andrun --scriptnow parse comment-prefix-agnostic/// scriptblocks, 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_rootandbin_dir, while legacy provider-specific root aliases are still accepted through validation aliases. abx_pkg_install_root_default()now readsABX_PKG_LIB_DIRfrom the live environment instead of a module-import snapshot, so CLI--liband runtime env overrides propagate correctly across providers.- Removed
load_or_installfrom the public API / CLI in favor ofinstall(), and promotedno_cacheinto the shared lifecycle surface forBinaryandBinProvider. - Hardened installer resolution across providers: fixed
detect_euid()recursion, fixed dry-run version probing, corrected GoPATH/ env handling, restored Yarn Berry--forcebehavior forno_cache, and normalized installer-binary abspath handling. - Playwright and Puppeteer now share the cleaned
install_root/bin_dirmodel, 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 installinstead ofload_or_install. - CLI logging now defaults to
INFO; enable debug output explicitly with--debugorABX_PKG_DEBUG=1. --no-cache/ABX_PKG_NO_CACHE=1now apply consistently acrossload(),install(),update(),uninstall(), andrun.
🧪 Verification
uv run prek run --all-filespassed 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
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 thinabx-pkg --install run ...alias that behaves like a cross-providernpx/uvx/pipx run. - Unified provider install-root defaults around
ABX_PKG_LIB_DIR, provider-specificABX_PKG_<NAME>_ROOToverrides, 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/pnpmauto-switching fromPipProviderandNpmProvider.
🧭 Quick Examples
abx yt-dlp --help
abx --binproviders=env,uv,pip,brew yt-dlp --version
abx-pkg --binproviders=pip --install run black --versionexport 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/BinProviderconfiguration surface on the CLI, including install roots, timeouts, release-age controls, postinstall-script policy, and overrides. - Hardened the new
run/abxcommand 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
PipProviderno longer silently falls through touv; chooseUvProviderexplicitly when you wantuvsemantics.NpmProviderno longer silently falls through topnpm; choosePnpmProviderexplicitly when you wantpnpmsemantics.- 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
mainfor the release line before the version bump. - Local checks passed with
uv run pyrightand focuseduv run pytestslices covering the new CLI/install-root work.
Thanks to everyone pushing on the provider edge cases and CLI ergonomics. 🚀
v1.9.28
abx-pkg v1.9.28
✨ Highlights
- Added dedicated providers for
uv,pnpm,yarn,bun,deno, and Playwright browser installs, and exported them from the publicabx_pkgAPI. - Added a real
abx-pkgCLI built withrich-click, includingversion,install,update,uninstall,load, andload_or_install, plus--lib,--binproviders, and--dry-run. - Added centralized install-root defaults via
ABX_PKG_LIB_DIR, with per-providerABX_PKG_<NAME>_ROOToverrides across providers that manage their own install roots.
🧰 What Changed
UvProvidernow stands on its own instead of piggybacking onPipProvider, with support for both hermetic venv installs anduv toolmode.PnpmProvider,YarnProvider,BunProvider, andDenoProvidereach got dedicated implementations with their own install/update/uninstall logic, managed prefixes, and provider-specific security flag handling.- Added
PlaywrightProviderfor browser artifact installs, alongside follow-up improvements to browser-provider path handling and install/load coverage. - Provider defaults now honor
ABX_PKG_LIB_DIRand 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
--versionexits instead of misreading their stderr, andPipProvidernow 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, andABX_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
Highlights
- Renamed the shell-command provider from
CustomProvider/customtoBashProvider/bash. - Renamed the provider module to
abx_pkg.binprovider_bash, updated lazy exports/imports, and switched the managed-root config fromABX_PKG_CUSTOM_ROOTtoABX_PKG_BASH_ROOT. - Renamed provider-specific fields and exported shell env vars to
bash_root,bash_bin_dir,BASH_INSTALL_ROOT, andBASH_BIN_DIR.
Behavior
- Preserved the existing shell-command install/update/uninstall model while keeping
install_rootandbin_diraliases working for the renamed provider. - Updated the provider lifecycle and security-control tests to exercise the renamed
bashprovider end to end. - Fixed Puppeteer's internal installer binary naming to
puppeteer-browsersso 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, andpuppeteer, including provider defaults, env-backed security controls, and unsupported-option warning behavior.
Upgrade notes
- Replace
CustomProviderimports withBashProvider. - Replace provider name
customwithbashinBinary.overridesand any serialized config. - Replace
custom_root/custom_bin_dirwithbash_root/bash_bin_dir. - Replace
ABX_PKG_CUSTOM_ROOTwithABX_PKG_BASH_ROOT.
v1.9.24
Highlights
- Added three new first-class providers:
ChromeWebstoreProvider,PuppeteerProvider, andCustomProvider. - Packaged the Chrome/extension JS runtime directly inside
abx-pkg, so Chrome Web Store installs now work without depending on a siblingabx-pluginscheckout. - Reworked provider option precedence so per-call args override
Binary(...), andBinary(...)overrides provider defaults, with cleaner handling fordry_run,postinstall_scripts, andmin_release_age. - Improved privilege escalation and subprocess error reporting across providers, including preserving failed
sudooutput 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_dirviaextensions_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.jsonabx_pkg/js/base/utils.jsabx_pkg/js/chrome/config.jsonabx_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/browsersinstalls. - 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
CustomProviderbuilt on top ofEnvProviderfor shell-command installs. - Supports
install_root/bin_dirviacustom_root/custom_bin_dir. - Uses literal per-binary shell overrides for install/update/uninstall while still participating in the standard
Binary/BinProviderlifecycle. - Includes real lifecycle coverage for direct provider and
Binary(...)usage.
Core Behavior Changes
Provider and Binary option precedence
- Added consistent per-call
dry_runsupport toinstall(),update(),uninstall(), andload_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_TIMEOUTABX_PKG_VERSION_TIMEOUTABX_PKG_DRY_RUN(preferred overDRY_RUNwhen both are set)
Security controls
- Provider-wide defaults for
min_release_age/postinstall_scriptsnow 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.
EnvProviderno longer claims support for install-only security controls it cannot enforce.pipandnpminstall-arg merging now preserves explicitly supplied conflicting flags instead of blindly overriding them.
API cleanup
binprovidersis now the canonical field name used throughout docs/examples instead ofbinproviders_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
sudoattempt 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, andDockerProvidernow rely more consistently on shared subprocess/error handling.PipProviderandNpmProvidernow merge security controls with explicit install args more rigorously.BrewProviderrespects explicit--skip-post-installargs when present.PipProviderandNpmProvidergained 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.shfor local monorepo setup. - Updated the README to document the new providers, env vars, canonical
binprovidersfield 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:
chromewebstorecustompuppeteer
- Expanded coverage for:
- module API normalization
- env-backed security defaults
- unsupported security option warning behavior
- provider-vs-action override precedence
v1.9.23
abx-pkg v1.9.23
Highlights
- 🧪 Replaced the old single-file
tests.pyrunner with a realpytestsuite undertests/, with live lifecycle coverage acrossapt,brew,pip,npm,cargo,gem,goget,nix,docker,pyinfra, andansible.
uv run pytest -m "not root_required and not docker_required"- 🧭 Standardized isolated install layout across providers with shared
install_root/bin_diraliases, while still supporting provider-specific knobs likepip_venv,npm_prefix,cargo_root,gem_home,gopath,nix_profile, anddocker_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, includinginstall_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_argscan adjust effective security behavior before fail-closed checks run, especially for npm--ignore-scriptsand--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/brewhelper backends now use resolvedinstall_argscargo uninstallno longer reuses incompatible version-pinned install flagsnix uninstallpreserves other entries in the same profilegogetis now the canonical provider name throughout the package and docsBinary.abspathsis available as a backward-compatible read alias forloaded_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
✨ Highlights
-
🔒 Security defaults now propagate consistently across binaries and providers.
BinProvidernow owns defaultpostinstall_scriptsandmin_release_agevalues, andBinaryinherits 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_versionis enforced end-to-end instead of only being advisory.install()andupdate()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, andmin_versionthrough setup/install/update paths. pipandnpmexplicitly declare support for release-age and postinstall controls.brewonly 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.
- Core handler signatures now thread
-
🧪 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_ageor disabled postinstall scripts. - Added live tests for
pipminimum-version upgrades andnpmpostinstall-script overrides. - Tightened the test helper typing so
ty-checkandpyrightpass withoutcast,Any, ortype: ignoreshortcuts.
def is_install_args_sequence(value: object) -> TypeGuard[InstallArgs]: return isinstance(value, (tuple, list)) and all(isinstance(item, str) for item in value)
- Added fail-closed coverage for providers that cannot honor
-
🏷️ Release metadata
- Version bumped to
1.9.22. uv.lockrefreshed to match the new package version.
- Version bumped to