Commit graph jw-pkg/src/python/jw/pkg/lib
Author SHA1 Message Date
6e988bea21
projects-dir.mk: Add diff-projects target
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m6s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m18s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m40s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m7s
CI / Packaging test (push) Successful in 0s
The diff-all and diff targets diff all projects in the workspace
without filtering.

Add a target "diff-projects". It sets PGIT_SH_PROJECTS to the list of
projects from build-order, limiting the diff to the dependency
closure around $(PROJECTS).

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-11 16:45:14 +02:00
5d77955ed9
py-check.mk: Run isort with "make format"
If /usr/bin/isort is found, run it during "make format" to get a
defined way the imports are sorted. tool.isort in pyproject.toml is
updated to match the other fixers.

Commit the fallout of this change. Running the other fixers alone
doesn't change the formatting, so this should be safe.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-11 16:45:14 +02:00
2eeaaf9681
lib.App: Make default log values overridable
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m0s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m11s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m40s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m59s
CI / Packaging test (push) Successful in 0s
The __init__() method reads default log configuration directly
from environment variables, making it impossible for subclasses to
change defaults.

Extract the defaults into _default_log_flags(), _default_log_level(),
_default_log_file(), and _default_show_backtrace() methods, then call
them from __init__(). Subclasses can now override these methods to
customize defaults without needing to override the entire __init__()
method.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-10 20:26:40 +02:00
90e221e106
lib.App: Make default env var names overridable
Add _default_*_env() helper methods that return the environment variable
names, and use them in __init__() instead of hard-coded strings. This
allows subclasses to override the names.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-10 20:26:40 +02:00
34ca0a7a95
lib.log.log(): Convert string-based flags to Flag
Replace the set of flag strings with a Flag enum for better type
safety and bitwise operations. Add parse_flags() to convert
comma-separated strings into a LogFlag value. Update set_flags() and
set_log_flags() to accept str | LogFlag | None.

set_flags() and set_log_flags() don't return str anylonger which is a
breaking change, but shouldn't be a problem because it's not used
anywhere.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-10 20:26:40 +02:00
c784c8ecb1
lib.log.log(): Use .join() to build argument string
The argument string builder in log() previously iterated with
enumerate and checked per-iteration whether to prepend a space.
Replace the loop with ' '.join(str(a) for a in args), which is a
single C-level operation.

Move the leading-space logic after the only_printable block so the
regex transformations see the raw joined content.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-10 20:26:40 +02:00
404b05ca26
lib.log.log(): Fix superfluous message whitespace
When prefix flags (position, prio, date) are combined with message
arguments, log() would double-space the output (e.g. '<N>  Created')
or omit the separator entirely (e.g. '<N>Created'). The root cause
was that log() prepended a space to every argument, regardless of
whether the prefix already ended with one.

Fix: only prepend a space before the first argument when the prefix
doesn't already end with one. This produces exactly one separator
between prefix and content regardless of which flags are active.

Also fix log_m(): skip empty strings (the sentinel '') so it doesn't
contribute a space. And fix the early return that dropped messages
when no prefix flags were set (previous commit).

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-10 20:26:40 +02:00
5d2e4fc03c
lib.log.log(): Fix early return without flags set
When position, prio, and date are all absent from the log flags, the
msg variable is empty. The early return 'if not len(msg): return'
would then skip printing the actual message in margs.

Fix by checking both msg and margs before returning. This ensures
messages are still printed even when no prefix flags are set.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-10 20:26:40 +02:00
fd521cb2a9 lib.App: Fix misc mypy errors
Fix fallout created by enabling the "strict" option:

  lib/App.py:196: error: Class cannot subclass
     "BaseCompleter" (has type "Any") [misc]

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-09 13:02:03 +00:00
1e613a39c6 App, cmds, lib: Fix Any returns from typed functions
Add type annotations and casts to functions that were returning Any
where a specific type was declared, satisfying the new warn_return_any
mypy rule.

Fixes:
- log.py: get_caller_pos return type via cast
- AsyncRunner.py: cast T for fut.result()
- util.py: cast for getattr result, str() for args.username
- FileContext.py: verbose_default bool annotation
- SSHClient.py: cast SSHClient for dynamic import
- lib/App.py: cast ArgumentParser, add return types to inner funcs
- pm/rpm.py, dpkg.py: cast Iterable[Package]
- App.py: cast for self.args.func(), add return types to inner funcs
- BaseCmdPkgRelations.py: cast str for args.delimiter

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-09 12:07:37 +00:00
410fd7ab5c App, lib: Add type annotations to untyped functions
Add missing type annotations to functions that are called from typed
contexts, satisfying the new disallow_untyped_calls mypy rule.

Fixes:
- Local.py: __log() with typed parameters
- lib/App.py: _add_arguments(), add_cmd_to_parser(), add_cmds_to_parser()
- pm/rpm.py, dpkg.py: meta_map() return type
- Exec.py: __init_askpass() return type
- App.py: strip_module_from_spec(), __get_project_refs_cached(),
  ResultCache.__init__ and run(), _add_arguments()
- Added Collection type for truthy-iterable compliance

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-09 11:36:04 +00:00
c16e054aaa App, lib, cmds: Remove unreachable code
Remove dead code paths detected by the new warn_unreachable mypy
rule. These include:

- Removed always-false isinstance checks (ssh/util.py, templates.py)
- Removed unreachable return statements after raise (FileContext.py)
- Removed unreachable None checks for typed variables (Result.py,
  ExecContext.py, CmdGetAuthInfo.py)
- Simplified __uri function by removing impossible None check
  (CopyContext.py)
- Changed assert False to explicit error (Cmd.py)
- Removed unreachable None case from match (App.py)
- Removed redundant outer case _: pass (pkg_relations.py)
- Restructured stdin write to avoid unreachable warning (AsyncSSH.py)

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-09 11:34:27 +00:00
55b63ded69 lib, cmds: Add exhaustive match cases
Add 'case _: pass' to match statements that are intentionally
non-exhaustive, satisfying the new exhaustive-match mypy rule.

Also replaced 'case '_':' (a string literal) with 'case _: pass' in
pkg_relations.py since it was an unreachable case (syntax is a
VersionSyntax enum, not a str).

Added 'case VersionSyntax.names_only:' to the match in pkg_relations.py
to handle the missing enum value.

Files modified:
- util.py: Two match statements for askpass env vars
- Distro.py: Three match statements for backend/os detection
- pkg_relations.py: Match on VersionSyntax enum
- CmdListRepos.py: Match on URL scheme

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-09 11:32:51 +00:00
dcbd4b1c84 lib: Change Iterable to Collection for truthy checks
Change parameter types from Iterable[str] to Collection[str] wherever
the parameter is tested for emptiness (if not names). This satisfies
the new truthy-iterable mypy rule, since bare Iterable values are
always truthy even when empty.

Affected files:
- Distro.py: install, delete, select, _select, _select_by_name
- rpm.py: query_packages
- suse/Distro.py: _select_by_name
- Cmd.py (secrets): _match_files, _list_template_files, etc.
- DistroContext.py: list_template_files, list_secret_paths, etc.

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-09 11:31:15 +00:00
fec0304543 App, AsyncSSH: Allow unused "type: ignore" comments
Some '# type: ignore' comments are needed because they complain about missing
but optional third-party packages: argcomplete, paramiko, asyncssh. The next
commit will enable warn_unused_ignores, and since nor mypy nor pyright have a
way of knowing that this is a tolerable lack of packages, this commit teaches
them in advance.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-09 11:27:00 +00:00
49bf2b2442
Distro, Cmd, AsyncSSH: Fix bare generic types
Add explicit type arguments to all generic type annotations that were
previously bare, satisfying the new disallow_any_generics mypy rule.

Fixes:
- Distro.py: Iterable[str] for expand_macros fmt parameter
- Cmd.py: Types[Any] for add_subcommands cmds parameter
- AsyncSSH.py: dict[str, Any] for _connect_kwargs return type

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-07 18:02:27 +02:00
e464daf2f3
Distro._reboot_required(): Fix comparison
The comparison ret != 0 is comparing a Result object against the
integer 0, which is always True since Result has no __eq__ defined.

This commit fixes the bug by comparing ret.status instead, which is
the actual exit code we care about. This satisfies the new
strict_equality mypy rule which enables the comparison-overlap check.

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-07 18:02:27 +02:00
044d2cb065
util: Remove redundant cast in run_curl_into
The cast to 'T' in run_curl_into was redundant: mypy already narrows
the return value of json.loads() to type T after the isinstance(ret,
expected_type) check (where expected_type: type[T]).

Remove the unnecessary cast and clean up the unused 'cast' import.
This satisfies the new warn_redundant_casts mypy rule.

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-07 18:02:27 +02:00
38c776e638
lib.Distro: Fix mypy.truthy-bool fallout
The _select() method in Distro.py has an assert on a PackageFilter
parameter that doesn't define __bool__ or __len__. Since the type
signature already guarantees it is not None, the assertion is
redundant and is now removed.

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-07 18:02:26 +02:00
a9bbbb9a89
lib.log: Fix mypy.possibly-undefined fallout
The log_m() function has margs conditionally assigned inside an if
block but used unconditionally afterwards. Initialize margs outside
the if to guarantee it is always defined.

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-07 18:02:26 +02:00
c939df2bd0
lib.AsyncRunner: Fix mypy.ignore-without-code fallout
Annotate the one existing bare "# type: ignore" in AsyncRunner.py
with arg-type and var-annotated codes to prepare for
mypy.ignore-without-code.

Signed-off-by: Jan Lindemann <jan@janware.com>
Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1
2026-08-07 18:02:26 +02:00
5fa008be5a
App, lib, cmds: Fix mypy.explicit-override fallout
This commit adds @override decorators to approximately 300 methods
across 76 files that inherit from base classes such as AbstractCmd,
FileContext, ExecContext, Distro, SSHClient, and others.

The decorator ensures the type checker can verify that overridden
methods have compatible signatures and prevents accidental shadowing
of inherited methods without intent.

Files modified include command classes, library modules, distro
implementations, and SSH client implementations.

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL with pi.dev v
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-07 18:02:26 +02:00
dcbe959843
lib: Fix misplaced "# export" markers
A couple of "# export" markers after function prototypes have been
pushed along with the closing parenthesis onto the wrong line by the
code formatter, fix that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:30:17 +02:00
701d8a33e7
lib.ec.ssh.Paramiko: Tolerate import-not-found
Tolera$te missing paramiko imports. jw-pkg is designed to
work with what it finds and use plain /usr/bin/ssh if need
be.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:08:28 +02:00
96409e50f7
lib.Uri: Treat paths starting with "~" specially
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 3m50s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 3m51s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m50s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m10s
CI / Packaging test (push) Successful in 0s
An Uri instance constructed from "~/some/path" returns
"file://~/some/path" as the .full property, i.e. with the "~" in the
authority part. That's not accurate and doesn't make the intended
sense in an URL context, see RFC 8089:

  Common UNIX shells such as the Bourne-Again SHell (bash) and Z
  SHell (zsh) provide a function known as "tilde expansion"
  [Bash-Tilde] or "filename expansion" [Zsh-Tilde], where a path
  that begins with a tilde character "~" can be expanded out to a
  special directory name.  No such facility exists using the file
  URI scheme; a tilde in a file URI is always just a tilde.

The "fix" introduced by this commit makes .full return the path
without file:// prepended. That's conservative. It could also chose
to expand the tilde, which is arguably cleaner. To be introduced by a
later change after this commit has seen more coverage.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-22 11:40:56 +02:00
2c38c8a144
lib.distros.suse.Distro: Fix duplicate zypper opts
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m16s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m10s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m48s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m17s
CI / Packaging test (push) Successful in 0s
In non-interactive mode, "zypper dup" runs with the options
--force-resolution and --auto-agree-with-licenses duplicated, fix
that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-22 11:06:58 +02:00
7f19432360
lib.Types: Exception log beautification
Be a bit more verbose if a broken (i.e. non-class-type) type filter
parameter gets passed.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-22 11:06:58 +02:00
00b632d1cd
lib.Distro: Fix typo instaniate to instantiate
Two error messages in Distro.__init__() contain the typo 'instaniate'
instead of 'instantiate'. Fix the spelling.

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL with pi.dev v0.80.2
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-04 07:29:11 +02:00
62803a4a1b
lib.Uri: Return 'file' scheme for local paths
The scheme property returns 'file://' for local paths instead of
'file', causing scheme_plus_authority to produce 'file://://' with a
triple slash.

Also fix the test to expect 'file' instead of 'file://'.

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL with pi.dev v0.80.2
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-04 07:21:43 +02:00
7d8994bcfe
lib.CopyContext._run(): Fix infinite recursion
The CopyContext._run() calls await self._run(), which would create
infinite recursion raising RecursionError at runtime. Make it a pure
virtual.

Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL with pi.dev v0.80.2
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-04 07:13:27 +02:00
24558f2b58
lib.ProjectConf: Add module
Introduce ProjectConf module to cleanly parse make/project.conf ini-like
configuration files. The new class supports:

  - ini-style sections with header comments
  - Key-value pairs with backslash line continuation
  - Quoted values preserving spaces and comment delimiters (#) inside
  - Inline comments outside of quotes
  - Comma-separated list values with quoted commas
  - Cached section parsing to avoid re-parsing the same section
  - .get_section() to return an entire section unparsed

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-30 12:46:36 +02:00
3b0f7727a7
lib.Cmd.AbstractCmd.aliases: Add property
Add a property aliases to AbstractCmd in prepeparation for commands
to bear multiple names / abbreviations / aliases.

The App.add_cmds_to_parser() function uses parse_known_args() to
determine which subcommand was invoked, then conditionally registers
nested subcommands. The lookup dictionary (scs) contains only
canonical names, not aliases, so add them too, otherwise using the
alias instead of the canonical name causes the lookup to fail and
nested subcommands to never be registered.

Fix: Register each alias in scs pointing to the same SubCommand
object, and deduplicate with id(sc) when iterating in all=True mode
to avoid infinite recursion on help output.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-25 09:50:19 +02:00
1e0dee5908
lib: More result log beautification
This commit adds more tweaks to shell command output in order to make
it nicer. The biggest patch is in Result.__summarize(), which makes
it more versatile, and allows removal of some code in SSHClient.

App sees some independent, minor result format beautification.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-24 21:23:22 +02:00
ffe0cfd41d
lib.App: Allow _run() without subcommands
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 3m5s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 3m11s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m8s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m17s
CI / Packaging test (push) Successful in 0s
Overriding the _run() method entirely in App subclasses is currently
only possible if the application supports a subcommand structure.
Make it possible to use it as an abstraction for a single-command
application.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-17 18:38:58 +02:00
b04c8d200a
lib.Result.strip: Rename to .strip_output
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 3m4s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 3m18s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m1s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m16s
CI / Packaging test (push) Successful in 0s
The .strip property of class Result defaults to True, and its name
isn't very clear. Rename it to .strip_output, and default it to False
to avoid surprising contents for unsuspecting callers.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-17 17:26:19 +02:00
7088e33cfe
lib.App.run(): Use pretty_cmd() for logging command line
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 3m26s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 3m25s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m10s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m5s
CI / Packaging test (push) Successful in 0s
The command line jw-pkg.py is run with is logged with level "debug",
and reconstructed with ' '.join(sys.argv). Use pretty_cmd() instead,
this adds quotes around spaces.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-17 17:12:42 +02:00
048726a1aa
lib.Result: Fill "cmd" ctor parameter
Commands executed by ExecContext and its derived classes don't
populate the "cmd" parameter of "Result"'s constructor. Fixing that
makes for nicer error messages.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-17 17:12:42 +02:00
0386c351a9
log: Use jw-python's log implementation
Use the (mostly) call-compatible log implementation from jw-python.
This buys us much nicer logs with color and source-code positon
annotations.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-17 17:12:42 +02:00
fd008b0a73
lib.Types.LoadTypes: Loosen type_filter type
In LoadTypes' constructor, allow the type_filter parameter to be of
type Sequence[type[Any]] instead of list[type[T]]. a) Sequence is
more generic than list, and b) with T instead of Any, trying to
instantiate with an abstract class has mypy complain:

  # E: Only concrete class can be given where "type[MyClass]" is
    expected  [type-abstract]

  - type_filter: list[type[T]] = [],
  + type_filter: Sequence[type[Any]] | None = None,

Not that this makes mypy complain that it needs an annotation at the
places where LoadTypes is used.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-17 17:12:42 +02:00
a3279a3b00
lib.Types.LoadTypes: Beautify logging code
Shorten redundant occurences of .format(mod_name, member_name).

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-17 17:12:42 +02:00
bfad94c196
lib.distros.suse.Distro._install_local_files(): Use rpm
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 3m2s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 3m8s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m5s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m40s
CI / Packaging test (push) Successful in 0s
OpenSUSE leaves installing local packages to the default
implementation in lib.Distro._install_local_files(), which passes the
package path to the package manager, i.e. zypper in OpenSUSE's case.
That has advantages, namely automatic installation of dependencies,
but also disadvantages, namely the attempt to install dependencies
even if the package manager is disfunctional, possibly because an
installed package containing installation sources is broken.

That could lead to a deadlock when trying to install a fixed package.
I see two ways out: Support an additional flag to jw-pkg's install
command which selects whether or not dependencies shall be resolved
along, or just use rpm directly for all local install attempts.

The latter is the less fancy way to handle this, so as a first step
make it the default by overriding suse.Distro._install_local_files().

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-15 08:18:40 +02:00
a739eb0763
lib.Result: Initialize with status = None
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 3m9s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 3m4s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m3s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m10s
CI / Packaging test (push) Successful in 0s
Define default parameter values for Result's constructor, namely None
for exit status, stdout and stderr.

Instantiating a Result object without parameters signifies "this
object doesn't contain data from a real process's exit event". Up to
now, similar meaning has been hand-crafted by ExecContext's run() and
friends by using an error exit status (1) to make sure it wasn't
mistaken for success. This commit formalizes that into the Result
structure itself, but uses None instead for the exit status.

Controlling default values in Result itself also means that the
Result class gets better awareness of what it contains, and its log
messages and stdin / stdout can be more fitting:

 - If a real process failed, make stdout return at least b''
 - If a real process succeeded, make stdout return at least b''

Returning something from .stdout on success fixes a real bug: An
attempt to access what "rpm -U somepackage.rpm" returns, namely
nothing, raises a bogus exception, because stdout is None.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-15 07:56:51 +02:00
658a87fde0
lib.ExecContext.CallContext.log_delim: Beautify
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 3m10s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 3m16s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m16s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m9s
CI / Packaging test (push) Successful in 0s
Fix commit 238cc05d which promised to beautify .log_delim but didn't.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-12 09:59:47 +02:00
238cc05d3b
lib.ExecContext.CallContext.log_delim: Beautify
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 3m18s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 3m24s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m17s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m21s
CI / Packaging test (push) Successful in 0s
Make the log delimiter look more consistent: Whether a CallContext
was constructed with a title parameter or without, prefix its
.log_delimiter property with a "----".

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-11 14:09:58 +02:00
422f09a0b4
lib.ExecContext._put(): Fix forgotten input
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 3m12s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 3m22s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m10s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m22s
CI / Packaging test (push) Successful in 0s
_put() doesn't put: An empty stdin is passed to tee, a regression
introduced with 6db73873e7, fix that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-10 12:56:05 +02:00
cd1716ff6f
lib.ExecContext._put(): Clean up temporary file
_put() can leave temporary files behind if one of its shell commands
fails, fix that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-10 12:55:58 +02:00
4a6c8ab1d1
lib.ExecContext|.Distro: Ignore stdout_str newline
Ignore newline at the end of Result.stdout_str if only one line of
output is wanted from an executed shell command. The output of both
uname and mktemp are used wrongly in that regard.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-10 12:55:39 +02:00
9732b48788
lib.Result.__repr__(): Fix binary stdout exception
__repr__() tries to decode binary stdout as string and fails without
a backup. Fix that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-10 12:55:31 +02:00
812ddaa1b0
lib.Result.__repr__() Fix missing f-qualifier
__repr__() tries to format a variable in an f-string without "f". Fix
that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-10 12:55:20 +02:00
3dc452d9b4
lib.init.detect_modules(): Renovate signature
- Remove package_name and package_path from the prototype of
    detect_modules(). They can and should be deduced from
    namespace['__name__'] and namespace['__path__'], respectively.

  - Make prefix default to None, which signifies "Don't filter by
    prefix".

  - Add an optional extend_namespace parameter, which will make the
    function append the module's __name__ to its __path__. This
    defaults to True, thereby adding a side effect to the function.
    Which is always wanted in the case for all callers of this
    function.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-06-06 23:08:28 +00:00