Commit graph

5,044 commits

Author SHA1 Message Date
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
b2fb37a668
Release 1.0.0-250@suse-tumbleweed/x86_64
All checks were successful
CI / Packaging - Kali Linux (push) Successful in 3m58s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m25s
CI / Packaging test (push) Successful in 0s
2026-08-09 23:32:11 +00:00
0d8c833964
Release 1.0.0-250@kali-rolling/amd64
All checks were successful
CI / Packaging - Kali Linux (push) Successful in 3m52s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m29s
CI / Packaging test (push) Successful in 0s
Signed-off-by: janware DevOps <devops@janware.com>
2026-08-09 23:11:52 +00:00
55725ad0bd
Start version: 1.0.0-250
Signed-off-by: janware DevOps <devops@janware.com>
2026-08-09 23:10:47 +00:00
be46a5ebcf pyrightconfig.json: Mirror strict mypy settings
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m6s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m12s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 4m9s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m0s
CI / Packaging test (push) Successful in 0s
Follow the changes in the mypy check profile by adding additional
checks.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-08-09 13:02:03 +00:00
9bbdcf5c39 pyproject.toml: Simplify mypy config using strict mode
Remove 8 redundant mypy settings that are already enabled by strict
mode: warn_redundant_casts, strict_equality, disallow_any_generics,
warn_unused_ignores, disallow_untyped_calls, warn_return_any,
disallow_incomplete_defs, disallow_untyped_defs.

Keep warn_unreachable explicitly since it's not part of strict mode.
Also remove the duplicate exhaustive-match entry from enable_error_code.

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 13:02:03 +00: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
989b800906 pyproject.toml: Enable mypy.disallow_untyped_defs
Add disallow_untyped_defs = true to the mypy configuration. This
requires all function definitions to have complete type annotations
for both parameters and return types. Since disallow_incomplete_defs
was already satisfied (all functions have partial annotations), this
final rule validates that no function is left without any type hints.

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
88ba66c5b0 pyproject.toml: Enable mypy.disallow_incomplete_defs
Add disallow_incomplete_defs = true to the mypy configuration. This
requires all function definitions to have complete parameter and return
type annotations, catching partially-annotated function signatures.

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
bbb9a9b17e pyproject.toml: Enable mypy.warn_return_any
Add warn_return_any = true to the mypy configuration. This detects
functions that return Any from contexts where a specific return type
is declared, encouraging more precise type annotations.

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
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
b3fee32ee1 pyproject.toml: Enable mypy.disallow_untyped_calls
Add disallow_untyped_calls = true to the mypy configuration. This
requires all function calls from typed code to target typed functions,
ensuring better type safety across the codebase.

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:52 +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
75c9879f67 pyproject.toml: Enable mypy.warn_unreachable
Add warn_unreachable = true to the mypy configuration. This detects
statements that mypy proves are unreachable, such as code after
an unconditional return or assertions that can never be true.

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:35:16 +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
a1d192b048 pyproject.toml: Enable mypy.exhaustive-match
Add the exhaustive-match error code to the mypy configuration. This
requires all match statements to be exhaustive, handling all possible
values of the matched expression.

The fix is to add 'case _: pass' to each match statement that is
intended to be non-exhaustive, making the non-exhaustiveness explicit.

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:33:39 +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
a3e46121da pyproject.toml: Enable mypy.truthy-iterable
Add the truthy-iterable error code to the mypy configuration. This
detects Iterable parameters that are used in boolean contexts (if not
names, etc.) since Iterable values are always truthy.

The fix is to change Iterable[str] parameters to Collection[str] when
they are tested for emptiness, since Collection guarantees __len__.

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:03 +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
cbd6bac84c pyproject.toml: Enable mypy.warn_unused_ignores
Add warn_unused_ignores = true to the mypy configuration. This warns
when a '# type: ignore' comment has no associated error code,
ensuring all type ignores are explicit about which error they suppress.

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:30:33 +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
64edcec48c
pyproject.toml: Enable mypy.disallow_any_generics
Add disallow_any_generics = true to the mypy configuration. This
requires all generic types (dict, list, Iterable, Types, etc.) to
have explicit type arguments instead of using bare generic aliases.

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
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
7f1809d6d1
pyproject.toml: Enable mypy.strict_equality
Set mypy.strict_equality = true, forcing type-equal equality.

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
dc14aac068
pyproject.toml: Enable mypy.warn_redundant_casts
Add warn_redundant_casts = true to the mypy configuration template.
This rule detects casts that mypy proves unnecessary, helping to
clean up redundant type casts that clutter the codebase.

This is one of the boolean-flag rules being gradually adopted from
the stricter mypy profile in /tmp/pyproject.toml. It produces just
1 error during initial rollout.

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
f689d083d7
pyproject.toml: Enable mypy.truthy-bool
Add the truthy-bool error code to the mypy configuration. This
detects conditions and expressions that are always truthy because
the type has no __bool__ or __len__ method.

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
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
7e7341bf1b
pyproject.toml: Enable mypy.possibly-undefined
Add the possibly-undefined error code to the mypy configuration.
This detects variables that may not be defined on all execution
paths, catching a class of NameError bugs at type-check time.

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
5f6559dbe0
pyproject.toml: Enable mypy.ignore-without-code
Add the ignore-without-code error code to the mypy configuration.
This requires all # type: ignore comments to include a specific error
code, improving the precision and maintainability of type ignore
annotations.

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
df5785cefd
pyproject.toml, pyrightconfig.json: Require @override
Add mypy's explicit-override error code and pyrightconfig's
reportImplicitOverride "error" directive. This requires all methods
that override base class methods to be decorated with @override from
typing. The change complements the previous commit, which added
exactly that decorator to all relevant methods.

Signed-off-by: Jan Lindemann <jan@janware.com>
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
30a00df5c7
Release 1.0.0-249@suse-tumbleweed/x86_64
All checks were successful
CI / Packaging - Kali Linux (push) Successful in 3m59s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m20s
CI / Packaging test (push) Successful in 0s
2026-07-27 23:27:12 +00:00
0f03e10290
Release 1.0.0-249@kali-rolling/amd64
All checks were successful
CI / Packaging - Kali Linux (push) Successful in 4m41s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m19s
CI / Packaging test (push) Successful in 0s
Signed-off-by: janware DevOps <devops@janware.com>
2026-07-26 23:11:51 +00:00
f7710bacf8
Start version: 1.0.0-249
Signed-off-by: janware DevOps <devops@janware.com>
2026-07-26 23:10:45 +00:00
a4306ad0c5
install-files.mk: Add missing target "test"
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m11s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m12s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 3m45s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m53s
CI / Packaging test (push) Successful in 0s
install-files.mk lacks a "test" target, so this commit adds a stub.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:39:22 +02:00
d306e8cbdc
projects-dir.mk: Support check targets
Add support for the targets "check" and "check-post" to
projects-dir.mk to make them usable from inside the projects
directory.

Note that "check-pre" is intentionally left out: Running "make check"
in a project before its prerequisite projects have built their
__init__.py files will fail due to broken import resolution.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:38:04 +02:00
e1ccbc1115
projects-dir.mk: Add target test
projects-dir.mk lacks a "test" target, fix that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:36:46 +02:00
41ca202142
cmds.projects.CmdBuild: Support --dep-flavours
CmdBuild supports the targets all, clean and pkg-*. It uses builtin
dependency flavours matching those targets to resolve build order. To
make it more flexible in general, and allow it to support more
targets, e.g. "check" and "test", this commit adds a --dep-flavours
option.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:35:27 +02:00
b7431e5bc6
rules.mk / defs.mk: Disable BUILD_MAKEDIR
BUILD_MAKEDIR is a variable which exists for consistency's sake. On
the other hand, nor jw-pkg nor any downstream package ever copies
makefile snippets during build time. The rule introduced by
BUILD_MAKEDIR is quite costly in terms of performance and makes
caching harder to understand. This commit disables the variable.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:34:08 +02:00
79edaff1dd
py-path.mk: Add target py-path
Add target py-path to py-path.mk. At this point, it's mostly
introduced for documentation purposes, giving people and machines a
defined, easily accessible and omni-present way to determine how
Python imports should be resolved.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:32:51 +02:00
4bf6445412
py-check.mk: Add target py-check-bad-patterns
Add target py-check-bad-patterns, which currently looks for leftover
breakpoints and orphaned "export" comments on the closing line of a
function prototype.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:31:34 +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
eea3e5f14b
py-check.mk: Add file
Add py-check.mk and use it from py-topdir.mk and py-rules.mk. This
removes redundant check definitions, making sure that that checks run
from a repo's subdirectory match the checks run from its toplevel
directory.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:28:59 +02:00
c63b3cc06f
py-defs.mk: Allow inclusion without defs.mk
py-defs.mk uses the variables ECHO and SED defined in defs.mk. The
complexity this introduces doesn't justify the reduced redundancy,
though, so this commit defines them redundantly in py-defs.mk and to
allow inclusion without prior defs.mk.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:27:43 +02:00
6743808000
py-run.mk: Remove dead code
Remove disabled included statements which are not going to be enabled
anymore.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-07-24 13:26:26 +02:00