mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-07-14 14:35:47 +00:00
handle dependencies recursively
This commit is contained in:
@ -346,6 +346,8 @@ def _set_repo_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
parser = root.add_parser("repo-rebuild", aliases=["rebuild"], help="rebuild repository",
|
||||
description="force rebuild whole repository", formatter_class=_formatter)
|
||||
parser.add_argument("--depends-on", help="only rebuild packages that depend on specified package", action="append")
|
||||
parser.add_argument("--dry-run", help="just perform check for packages without rebuild process itself",
|
||||
action="store_true")
|
||||
parser.set_defaults(handler=handlers.Rebuild)
|
||||
return parser
|
||||
|
||||
|
@ -22,6 +22,7 @@ import argparse
|
||||
from typing import Type
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.formatters.update_printer import UpdatePrinter
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
|
||||
@ -44,9 +45,10 @@ class Rebuild(Handler):
|
||||
depends_on = set(args.depends_on) if args.depends_on else None
|
||||
|
||||
application = Application(architecture, configuration, no_report)
|
||||
packages = [
|
||||
package
|
||||
for package in application.repository.packages()
|
||||
if depends_on is None or depends_on.intersection(package.depends)
|
||||
] # we have to use explicit list here for testing purpose
|
||||
application.update(packages)
|
||||
updates = application.repository.packages_depends_on(depends_on)
|
||||
if args.dry_run:
|
||||
for package in updates:
|
||||
UpdatePrinter(package, package.version).print(verbose=True)
|
||||
return
|
||||
|
||||
application.update(updates)
|
||||
|
@ -18,7 +18,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from pathlib import Path
|
||||
from typing import Dict, Iterable, List
|
||||
from typing import Dict, Iterable, List, Optional
|
||||
|
||||
from ahriman.core.repository.executor import Executor
|
||||
from ahriman.core.repository.update_handler import UpdateHandler
|
||||
@ -68,3 +68,20 @@ class Repository(Executor, UpdateHandler):
|
||||
:return: list of filenames from the directory
|
||||
"""
|
||||
return list(filter(package_like, self.paths.packages.iterdir()))
|
||||
|
||||
def packages_depends_on(self, depends_on: Optional[Iterable[str]]) -> List[Package]:
|
||||
"""
|
||||
extract list of packages which depends on specified package
|
||||
:param: depends_on: dependencies of the packages
|
||||
:return: list of repository packages which depend on specified packages
|
||||
"""
|
||||
packages = self.packages()
|
||||
if depends_on is None:
|
||||
return packages # no list provided extract everything by default
|
||||
depends_on = set(depends_on)
|
||||
|
||||
return [
|
||||
package
|
||||
for package in packages
|
||||
if depends_on is None or depends_on.intersection(package.full_depends(self.pacman, packages))
|
||||
]
|
||||
|
@ -20,13 +20,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import aur # type: ignore
|
||||
import copy
|
||||
import logging
|
||||
|
||||
from dataclasses import asdict, dataclass
|
||||
from pathlib import Path
|
||||
from pyalpm import vercmp # type: ignore
|
||||
from srcinfo.parse import parse_srcinfo # type: ignore
|
||||
from typing import Any, Dict, List, Optional, Set, Type
|
||||
from typing import Any, Dict, Iterable, List, Optional, Set, Type
|
||||
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.exceptions import InvalidPackageInfo
|
||||
@ -257,6 +258,36 @@ class Package:
|
||||
|
||||
return self.version
|
||||
|
||||
def full_depends(self, pacman: Pacman, packages: Iterable[Package]) -> List[str]:
|
||||
"""
|
||||
generate full dependencies list including transitive dependencies
|
||||
:param pacman: alpm wrapper instance
|
||||
:param packages: repository package list
|
||||
:return: all dependencies of the package
|
||||
"""
|
||||
dependencies = {}
|
||||
# load own package dependencies
|
||||
for package_base in packages:
|
||||
for name, repo_package in package_base.packages.items():
|
||||
dependencies[name] = repo_package.depends
|
||||
for provides in repo_package.provides:
|
||||
dependencies[provides] = repo_package.depends
|
||||
# load repository dependencies
|
||||
for database in pacman.handle.get_syncdbs():
|
||||
for pacman_package in database.pkgcache:
|
||||
dependencies[pacman_package.name] = pacman_package.depends
|
||||
for provides in pacman_package.provides:
|
||||
dependencies[provides] = pacman_package.depends
|
||||
|
||||
result = set(self.depends)
|
||||
current_depends: Set[str] = set()
|
||||
while result != current_depends:
|
||||
current_depends = copy.deepcopy(result)
|
||||
for package in current_depends:
|
||||
result.update(dependencies.get(package, []))
|
||||
|
||||
return sorted(result)
|
||||
|
||||
def is_outdated(self, remote: Package, paths: RepositoryPaths, calculate_version: bool = True) -> bool:
|
||||
"""
|
||||
check if package is out-of-dated
|
||||
|
Reference in New Issue
Block a user