cmds.pkg.CmdVerify: Add command
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m24s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m43s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 4m48s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m38s
CI / Packaging test (push) Successful in 0s
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m24s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m43s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 4m48s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m38s
CI / Packaging test (push) Successful in 0s
Add the "packages verify" command: it runs Distro.verify() with the app's package filter and prints one line per flagged file. Signed-off-by: Jan Lindemann <jan@janware.com> Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v1.2.0
This commit is contained in:
parent
cae983479c
commit
8106d4a7b0
4 changed files with 173 additions and 1 deletions
|
|
@ -66,6 +66,8 @@ Available subcommands of packages:
|
|||
reboot-required Check whether the machine needs rebooting
|
||||
refresh Refresh the distribution's notion of available packages
|
||||
select Select packages by filter
|
||||
verify Verify the integrity of installed packages: report files
|
||||
modified or deleted outside of the package manager
|
||||
============= Running: jw-pkg.py -t ../../../.. --log-level info packages delete --help
|
||||
usage: jw-pkg.py packages delete [-h] [names ...]
|
||||
|
||||
|
|
@ -140,6 +142,14 @@ Select packages by filter
|
|||
positional arguments:
|
||||
filter Package filter string
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
============= Running: jw-pkg.py -t ../../../.. --log-level info packages verify --help
|
||||
usage: jw-pkg.py packages verify [-h]
|
||||
|
||||
Verify the integrity of installed packages: report files modified or deleted
|
||||
outside of the package manager
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
============= Running: jw-pkg.py -t ../../../.. --log-level info platform --help
|
||||
|
|
|
|||
7
test/unit/python/jw/pkg/lib/pm/dpkg/Makefile
Normal file
7
test/unit/python/jw/pkg/lib/pm/dpkg/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
TOPDIR = ../../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-run.mk
|
||||
|
||||
all:
|
||||
test: run
|
||||
81
test/unit/python/jw/pkg/lib/pm/dpkg/test.py
Normal file
81
test/unit/python/jw/pkg/lib/pm/dpkg/test.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
from typing import override
|
||||
|
||||
from jw.pkg.lib.ec.Local import Local
|
||||
from jw.pkg.lib.pm.dpkg import list_files
|
||||
from jw.pkg.lib.Result import Result
|
||||
|
||||
class CannedLocal(Local):
|
||||
|
||||
def __init__(self, stdout: str) -> None:
|
||||
super().__init__('local')
|
||||
self.stdout = stdout
|
||||
self.cmds: list[list[str]] = []
|
||||
|
||||
@override
|
||||
async def _run(
|
||||
self,
|
||||
cmd: list[str],
|
||||
wd: str | None,
|
||||
verbose: bool,
|
||||
cmd_input: bytes | None,
|
||||
mod_env: dict[str, str] | None,
|
||||
interactive: bool,
|
||||
log_prefix: str,
|
||||
) -> Result:
|
||||
self.cmds.append(cmd)
|
||||
return Result(stdout = self.stdout.encode(), status = 0)
|
||||
|
||||
# -- One listing over several packages
|
||||
cl = CannedLocal('/usr/bin/b\n/etc/b/b.conf.jw-tmpl\n')
|
||||
assert asyncio.run(list_files(['a', 'b'], ec = cl)) == \
|
||||
['/usr/bin/b', '/etc/b/b.conf.jw-tmpl']
|
||||
assert cl.cmds[-1] == [
|
||||
'/usr/bin/dpkg',
|
||||
'-L',
|
||||
'a',
|
||||
'b',
|
||||
]
|
||||
|
||||
# -- The unfiltered selection is the standard interface, two
|
||||
# queries: select the installed packages, then list their files
|
||||
# in one command; the list output carries a package-name header
|
||||
# and a blank line per package, both dropped
|
||||
class CannedTwoStage(Local):
|
||||
|
||||
def __init__(self, query: str, listing: str) -> None:
|
||||
super().__init__('local')
|
||||
self.query = query
|
||||
self.listing = listing
|
||||
self.cmds: list[list[str]] = []
|
||||
|
||||
@override
|
||||
async def _run(
|
||||
self,
|
||||
cmd: list[str],
|
||||
wd: str | None,
|
||||
verbose: bool,
|
||||
cmd_input: bytes | None,
|
||||
mod_env: dict[str, str] | None,
|
||||
interactive: bool,
|
||||
log_prefix: str,
|
||||
) -> Result:
|
||||
self.cmds.append(cmd)
|
||||
out = self.query if '-W' in cmd else self.listing
|
||||
return Result(stdout = out.encode(), status = 0)
|
||||
|
||||
cl2 = CannedTwoStage('a\nb\n', 'a:\n/usr/bin/a\n\nb:\n/etc/b/b.conf.jw-tmpl\n')
|
||||
assert asyncio.run(list_files(None, ec = cl2)) == \
|
||||
['/usr/bin/a', '/etc/b/b.conf.jw-tmpl']
|
||||
assert cl2.cmds == [
|
||||
['/usr/bin/dpkg-query', '-W', '-f=${?installed:binary:Package}\n'],
|
||||
['/usr/bin/dpkg-query', '-L', 'a', 'b'],
|
||||
]
|
||||
|
||||
# -- An empty selection lists nothing and runs no query
|
||||
cl3 = CannedTwoStage('', '')
|
||||
assert asyncio.run(list_files([], ec = cl3)) == []
|
||||
assert cl3.cmds == []
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
from typing import override
|
||||
|
||||
from jw.pkg.lib.ec.Local import Local
|
||||
from jw.pkg.lib.FlaggedFile import FlaggedFile
|
||||
from jw.pkg.lib.pm.rpm import _parse_verify_output
|
||||
from jw.pkg.lib.pm.rpm import _parse_verify_output, list_files
|
||||
from jw.pkg.lib.Result import Result
|
||||
|
||||
# -- _parse_verify_output --
|
||||
|
||||
|
|
@ -56,3 +62,42 @@ f = FlaggedFile('pkg', '/etc/foo', 'SM5....T.')
|
|||
assert repr(f) == 'pkg /etc/foo SM5....T.'
|
||||
|
||||
print('All rpm pm tests passed')
|
||||
|
||||
# -- list_files --
|
||||
|
||||
class CannedLocal(Local):
|
||||
|
||||
def __init__(self, stdout: str) -> None:
|
||||
super().__init__('local')
|
||||
self.stdout = stdout
|
||||
self.cmds: list[list[str]] = []
|
||||
|
||||
@override
|
||||
async def _run(
|
||||
self,
|
||||
cmd: list[str],
|
||||
wd: str | None,
|
||||
verbose: bool,
|
||||
cmd_input: bytes | None,
|
||||
mod_env: dict[str, str] | None,
|
||||
interactive: bool,
|
||||
log_prefix: str,
|
||||
) -> Result:
|
||||
self.cmds.append(cmd)
|
||||
return Result(stdout = self.stdout.encode(), status = 0)
|
||||
|
||||
# -- One query over several packages, the output split into lines
|
||||
cl = CannedLocal('/usr/bin/a\n/etc/a/a.conf.jw-tmpl\n')
|
||||
assert asyncio.run(list_files(['a', 'b'], ec = cl)) == \
|
||||
['/usr/bin/a', '/etc/a/a.conf.jw-tmpl']
|
||||
assert cl.cmds[-1] == ['/usr/bin/rpm', '-ql', 'a', 'b']
|
||||
|
||||
# -- The unfiltered selection is one query without package names
|
||||
cl = CannedLocal('/usr/bin/a\n/etc/a/a.conf.jw-tmpl\n')
|
||||
assert asyncio.run(list_files(None, ec = cl)) == ['/usr/bin/a', '/etc/a/a.conf.jw-tmpl']
|
||||
assert cl.cmds[-1] == ['/usr/bin/rpm', '-qal']
|
||||
|
||||
# -- An empty selection lists nothing and runs no query
|
||||
cl = CannedLocal('')
|
||||
assert asyncio.run(list_files([], ec = cl)) == []
|
||||
assert cl.cmds == []
|
||||
|
|
|
|||
Loading…
Reference in a new issue