Changelog¶
Format based on Keep a Changelog. depkeeper follows Semantic Versioning.
Recommendation logic is a behavioural contract
A change that makes the same requirements file produce a different update plan is at minimum a minor release. Entries that alter recommendations are marked Impact so consumers gating pipelines on the output know what to re-verify.
Unreleased¶
Planned¶
- Security advisory scanning against a vulnerability database
- Configurable package index for private repositories
- A flag to override the target Python version used for compatibility filtering
- Joining backslash line continuations in the parser
0.1.1¶
Changed¶
- Impact: Duplicate declarations of the same package (e.g. the same distribution pulled in via two
-rincludes with different constraints) are now resolved independently instead of collapsing to one shared recommendation. - Impact: PEP 440 wildcard version bands (
pkg==2.*) are now parsed leniently, so a wildcard-pinned requirement participates correctly in major-boundary and update-availability checks instead of appearing unparseable. check's table output changed its status badges from Unicode symbols (✓,⬆,⚠,✗) to bracketed text labels ([OK],[OUTDATED],[CONFLICT],[INCOMP],[ERROR]), matching--format simple's existing labels. Scripts matching on the old symbols must be updated.tomliis now used unconditionally for TOML parsing, on every supported Python version, instead of preferring the standard-librarytomllibon 3.11+.- A configuration file carrying a leading byte-order mark is now decoded correctly.
Fixed¶
- A
Retry-Afterheader on a429response is now clamped to a maximum of 120 seconds, and both the delay-seconds and HTTP-date header forms are parsed correctly. - The interactive confirmation prompt's
[y/N]/[Y/n]suffix is no longer swallowed by Rich markup interpretation. _find_updatesno longer risks pairing a requirement with an unrelated package when the parsed requirements and checked packages lists fall out of step.
Full detail: CHANGELOG.md.
0.1.0¶
Initial release.
Added — commands¶
depkeeper check [FILE]— read-only analysis with--outdated-only,--format table|simple|json,--strict-version-matchingand--check-conflicts/--no-check-conflicts.depkeeper update [FILE]— in-place rewriting with--dry-run,--yes,--backup,--pin,--allow-hash-removal,--packages/-p,--strict-version-matchingand--check-conflicts/--no-check-conflicts.- Global options
--config/-c,--verbose/-v,--color/--no-color,--version,--help, with theDEPKEEPER_CONFIGandDEPKEEPER_COLORenvironment variables. - Both
depkeeperandpython -m depkeeperentry points.
Added — version recommendation¶
- Strict major-version boundary enforcement: a recommendation never crosses a major version when a current version is known.
- Python compatibility filtering using each release's
requires_python, evaluated against the interpreter running depkeeper. - Pre-release exclusion.
- Current-version inference from range specifiers (
>=,>,~=), disabled by--strict-version-matching. - Constraint preservation: only the floor of a requirement is rewritten; upper bounds, exclusions and wildcard bands are preserved verbatim and are fed back into candidate selection so an unsatisfiable line can never be produced.
--pinto opt into exact==pins.- Convergence: a target already covered by the declared floor is skipped, making repeated runs idempotent.
Added — conflict resolution¶
- Iterative cross-package resolution bounded at 100 passes, with two boundary-respecting strategies (step the source back; constrain the target) and a "revert both" fallback.
ResolutionResultwith per-packageoriginal → resolveddetails, statuses, cumulative conflict records and convergence statistics.- Invariant:
Package.recommended_versionalways equals the resolver'sresolvedvalue, so the version reported is the version written. - Advisory compatible alternatives, adopted only where a conflict is still live.
- Graceful degradation when PyPI metadata is unavailable, with a per-run negative cache to prevent retry storms.
Added — parsing¶
- PEP 440/508 requirements, extras, environment markers and inline comments.
-r/--requirementincludes with cycle detection and per-requirement provenance, so the correct file is rewritten.-c/--constraintconstraint files.-e/--editable, VCS URLs, HTTP(S) URLs,file://URIs and local paths — reported, never updated.--hash=Xand--hash Xforms.- Recognition and skipping of pip global options (
--index-url,-i,--extra-index-url,--find-links,-f,--trusted-host,--no-binary,--only-binary,--use-feature,--pre,--prefer-binary). - UTF-8 byte-order-mark handling on read and write.
- Deterministic, source-faithful specifier ordering.
Added — write safety¶
- Two-phase commit: all affected files are rendered in memory before any is written, with rollback of committed files if a later write fails.
- Atomic replacement via temporary file,
fsyncandos.replace, with mode preservation, symlink following, directoryfsyncon POSIX and bounded retries for transient Windows lock errors. - Byte-preserving line endings and per-line terminators.
- Timestamped backups of every affected file with
--backup, restored automatically on failure. - Hashed requirements refused by default to prevent silent integrity regressions.
Added — output¶
- Rich table, line-based simple and JSON output formats.
- Stream separation: machine-readable formats keep stdout exclusively for the payload, with all status output, warnings and errors on stderr, so
depkeeper -v check -f json | jqworks. --format jsonalways emits a document,[]included.- Per-stream colour detection.
Added — configuration¶
depkeeper.toml([depkeeper]) andpyproject.toml([tool.depkeeper]) support forcheck_conflictsandstrict_version_matching.- Strict validation: unknown keys and wrong types are errors.
- Precedence: defaults < configuration file < command-line flag.
Added — performance and reliability¶
- Shared
PyPIDataStoreguaranteeing at most one PyPI request per package per process, with per-key request coalescing and cancellation-safe waiters. - Async HTTP with HTTP/2, bounded concurrency, exponential backoff with jitter, and separate
429handling that honoursRetry-After. - Structured exception hierarchy with diagnostic metadata.
Known limitations¶
Documented in Known limitations. The most significant:
- Not a substitute for
pip's resolver — the transitive graph is not expanded. - Only
pypi.orgis queried. - Backslash line continuations are not parsed.
--allow-hash-removalyields a partially hashed file.- Compatibility filtering uses depkeeper's own interpreter, with no override.