jw-pkg packages install: Add -x/--exact option #159

Merged
Jan Lindemann merged 4 commits from jan/feature/20261028-jw-pkg-packages-install-add-x-exact-option into master 2026-10-28 21:02:52 +01:00 AGit
Owner

This PR makes dependency resolution explicit throughout the jw-pkg install path and adds a direct route for installing packages without resolving their dependencies and automatically installing them along. The commits build on each other: Package gains a version field so local files can be classified against the installed state, lib.pm.*.install_packages() installs files with rpm -U / dpkg -i (the dpkg route gated on an apt simulation, because dpkg -i leaves a half-configured package on a missing dependency), the Distro install methods take install_deps - the base class raises when a distro offers no direct route - and the command gains -x/--exact: by default local files go through the package manager with dependency resolution, --exact keeps the direct route.

lib.Package: Add and fill version field

Add a version field to the Package class and make query_packages() fill it. It's very much distribution and package dependent what shape that version has, so from Package's perspective, it's just a str-typed member.

Further improvements and fixes:

  • Make query_packages() accept throw, defaulting to the previous behaviour, so a caller that wants to be prepared for a missing package / an empty result can pass throw = False.
  • Make dpkg's _run() and run_dpkg_query() forward ec and the remaining keyword arguments on the sudo path, which dropped them before.

Add unit tests for the file type tree and its StatResult predicates.

lib.pm.*.install_packages(): Add functions

Currently, jw-pkg install is sometimes left to the high-level package manager, which is allowed to install dependencies along, and that's sometimes unwanted, but there's no backend in the low-level package manager module lib.pm to allow specifying that. This commit adds it: lib.pm.*.install_packages().

The functions install a list of local package files using the low-level package managers rpm / dpkg, bypassing the high-level package managers yum / apt / zypper.

pm.rpm runs rpm -U and pm.dpkg runs dpkg -i. Every file is classified against the installed state of its package, queried by name: a file for a package that is not installed is installed fresh, a file with another version installed is upgraded, and a file whose version is already installed is reinstalled when force is set and skipped otherwise. On rpm, plain -U refuses a package that is already installed, and --reinstall aborts the transaction when a file of the incoming package differs from the installed one, so the upgrades run before the reinstalls and the same-version files need force.

With only_update, a file for a package that is not installed raises before anything is installed.

The dpkg route is gated on an apt simulation, because dpkg -i leaves a half-configured package when a dependency is missing: the simulation runs first and the install is refused when it would install or remove anything but the given files' own packages.

lib.distros.Distro.install_*(): Add install_deps

The install methods of Distro inconsistently resolve dependencies or don't depending on the descendant's implementation. Pin that more unambigously by adding a new parameter install_deps, defaulting to True, to the following methods of lib.Distro:

_install_local_files() _install_urls() _install_urls_and_names() install()

The implementations in lib.distros.* make use of the new lib.pm.*.install_packages() method introduced by the previous commit.

Add a unit test directory per Distro descendant.

cmds.pkg: Add --exact to jw-pkg packages install

Add an additional option -x, which inhibits dependency resolution during installation of packages.

This PR makes dependency resolution explicit throughout the `jw-pkg` install path and adds a direct route for installing packages without resolving their dependencies and automatically installing them along. The commits build on each other: `Package` gains a version field so local files can be classified against the installed state, lib.pm.*.`install_packages()` installs files with `rpm -U` / `dpkg -i` (the dpkg route gated on an apt simulation, because `dpkg -i` leaves a half-configured package on a missing dependency), the `Distro` install methods take `install_deps` - the base class raises when a distro offers no direct route - and the command gains `-x`/`--exact`: by default local files go through the package manager with dependency resolution, `--exact` keeps the direct route. #### lib.Package: Add and fill version field Add a version field to the `Package` class and make `query_packages()` fill it. It's very much distribution and package dependent what shape that version has, so from `Package`'s perspective, it's just a str-typed member. Further improvements and fixes: - Make `query_packages()` accept throw, defaulting to the previous behaviour, so a caller that wants to be prepared for a missing package / an empty result can pass `throw = False`. - Make dpkg's `_run()` and `run_dpkg_query()` forward `ec` and the remaining keyword arguments on the sudo path, which dropped them before. Add unit tests for the file type tree and its StatResult predicates. #### lib.pm.*.install_packages(): Add functions Currently, `jw-pkg` install is sometimes left to the high-level package manager, which is allowed to install dependencies along, and that's sometimes unwanted, but there's no backend in the low-level package manager module lib.pm to allow specifying that. This commit adds it: lib.pm.*.`install_packages()`. The functions install a list of local package files using the low-level package managers `rpm` / `dpkg`, bypassing the high-level package managers `yum` / `apt` / `zypper`. pm.rpm runs `rpm -U` and pm.dpkg runs `dpkg -i`. Every file is classified against the installed state of its package, queried by name: a file for a package that is not installed is installed fresh, a file with another version installed is upgraded, and a file whose version is already installed is reinstalled when `force` is set and skipped otherwise. On `rpm`, plain `-U` refuses a package that is already installed, and `--reinstall` aborts the transaction when a file of the incoming package differs from the installed one, so the upgrades run before the reinstalls and the same-version files need force. With `only_update`, a file for a package that is not installed raises before anything is installed. The dpkg route is gated on an apt simulation, because `dpkg -i` leaves a half-configured package when a dependency is missing: the simulation runs first and the install is refused when it would install or remove anything but the given files' own packages. #### lib.distros.Distro.install_*(): Add install_deps The install methods of Distro inconsistently resolve dependencies or don't depending on the descendant's implementation. Pin that more unambigously by adding a new parameter `install_deps`, defaulting to True, to the following methods of lib.Distro: `_install_local_files()` `_install_urls()` `_install_urls_and_names()` `install()` The implementations in lib.distros.* make use of the new lib.pm.*.`install_packages()` method introduced by the previous commit. Add a unit test directory per Distro descendant. #### cmds.pkg: Add --exact to jw-pkg packages install Add an additional option `-x`, which inhibits dependency resolution during installation of packages.
Add a version field to the Package class and make query_packages() fill it.
It's very much distribution and package dependent what shape that version
has, so from Package's perspective, it's just a str-typed member.

Further improvements and fixes:

- Make query_packages() accept throw, defaulting to the previous behaviour,
  so a caller that wants to be prepared for a missing package / an empty
  result can pass throw = False.
- Make dpkg's _run() and run_dpkg_query() forward ec and the remaining
  keyword arguments on the sudo path, which dropped them before.

Add unit tests for the file type tree and its StatResult predicates.

Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v1.4.0
Signed-off-by: Jan Lindemann <jan@janware.com>
Currently, jw-pkg install is sometimes left to the high-level package
manager, which is allowed to install dependencies along, and that's
sometimes unwanted, but there's no backend in the low-level package manager
module lib.pm to allow specifying that. This commit adds it:
lib.pm.*.install_packages().

The functions install a list of local package files using the low-level
package managers rpm / dpkg, bypassing the high-level package managers yum
/ apt / zypper.

pm.rpm runs rpm -U and pm.dpkg runs dpkg -i. Every file is classified
against the installed state of its package, queried by name: a file
for a package that is not installed is installed fresh, a file with
another version installed is upgraded, and a file whose version is already
installed is reinstalled when force is set and skipped otherwise. On rpm,
plain -U refuses a package that is already installed, and --reinstall
aborts the transaction when a file of the incoming package differs from
the installed one, so the upgrades run before the reinstalls and the
same-version files need force.

With only_update, a file for a package that is not installed raises before
anything is installed.

The dpkg route is gated on an apt simulation, because dpkg -i leaves a
half-configured package when a dependency is missing: the simulation runs
first and the install is refused when it would install or remove anything
but the given files' own packages.

Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v1.4.0
Signed-off-by: Jan Lindemann <jan@janware.com>
The install methods of Distro inconsistently resolve dependencies or don't
depending on the descendant's implementation. Pin that more unambigously by
adding a new parameter install_deps, defaulting to True, to the following
methods of lib.Distro:

  _install_local_files()
  _install_urls()
  _install_urls_and_names()
  install()

The implementations in lib.distros.* make use of the new
lib.pm.*.install_packages() method introduced by the previous commit.

Add a unit test directory per Distro descendant.

Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v1.4.0
Signed-off-by: Jan Lindemann <jan@janware.com>
cmds.pkg: Add --exact to jw-pkg packages install
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 5m17s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 5m16s
CI / Packaging test (pull_request) Successful in 0s
afd3a8c40b
Add an additional option -x, which inhibits dependency resolution during
installation of packages.

Signed-off-by: Jan Lindemann <jan@janware.com>
Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v1.4.0
Jan Lindemann scheduled this pull request to auto merge when all checks succeed 2026-10-28 20:14:57 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
janware/jw-pkg!159
No description provided.