fix: handle permissionerror during walking over tree

Previously it tried to look into 700 directories (e.g. .gnupg) which
breaks running as non-ahriman user
This commit is contained in:
2026-02-02 17:13:30 +02:00
parent 799dc73d8a
commit 43856b500a
3 changed files with 29 additions and 3 deletions

View File

@@ -431,6 +431,22 @@ def safe_filename(source: str) -> str:
return re.sub(r"[^A-Za-z\d\-._~:\[\]@]", "-", source)
def safe_iterdir(path: Path) -> Iterator[Path]:
"""
wrapper around :func:`pathlib.Path.iterdir`, which suppresses :exc:`PermissionError`
Args:
path(Path): path to iterate
Yields:
Path: content of the directory
"""
try:
yield from path.iterdir()
except PermissionError:
pass
def srcinfo_property(key: str, srcinfo: Mapping[str, Any], package_srcinfo: Mapping[str, Any], *,
default: Any = None) -> Any:
"""

View File

@@ -279,14 +279,16 @@ class RepositoryPaths(LazyLogging):
Note, however, that this method doesn't handle any exceptions and will eventually interrupt
if there will be any.
"""
from ahriman.core.utils import safe_iterdir
path = path or self.root
def walk(root: Path) -> Iterator[Path]:
# basically walk, but skipping some content
for child in root.iterdir():
for child in safe_iterdir(root):
yield child
if child in (self.chroot.parent,):
yield from child.iterdir() # we only yield top-level in chroot directory
yield from safe_iterdir(child) # we only yield top-level in chroot directory
elif child.is_dir():
yield from walk(child)

View File

@@ -11,7 +11,7 @@ from unittest.mock import call as MockCall
from ahriman.core.exceptions import BuildError, CalledProcessError, OptionError, UnsafeRunError
from ahriman.core.utils import check_output, check_user, dataclass_view, enum_values, extract_user, filter_json, \
full_version, minmax, package_like, parse_version, partition, pretty_datetime, pretty_interval, pretty_size, \
safe_filename, srcinfo_property, srcinfo_property_list, trim_package, utcnow, walk
safe_filename, safe_iterdir, srcinfo_property, srcinfo_property_list, trim_package, utcnow, walk
from ahriman.models.package import Package
from ahriman.models.package_source import PackageSource
from ahriman.models.repository_id import RepositoryId
@@ -426,6 +426,14 @@ def test_safe_filename() -> None:
assert safe_filename("tolua++-1.0.93-4-x86_64.pkg.tar.zst") == "tolua---1.0.93-4-x86_64.pkg.tar.zst"
def test_safe_iterdir(mocker: MockerFixture) -> None:
"""
must suppress PermissionError
"""
iterdir_mock = mocker.patch("pathlib.Path.iterdir", side_effect=PermissionError)
assert list(safe_iterdir(Path("root"))) == []
def test_srcinfo_property() -> None:
"""
must correctly extract properties