[gems.arch] fix: not considering some conflict expressions when retrieving upgrade requirements

This commit is contained in:
Vinicius Moreira
2022-11-05 14:19:28 -03:00
parent de8b143273
commit ffa32a85b7
3 changed files with 38 additions and 15 deletions

View File

@@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- some desktop entries not being displayed on the desktop environment menu (requires the AppImage to be reinstalled) [#287](https://github.com/vinifmor/bauh/issues/287)
- Arch
- not detecting some package replacements when upgrading due to conflict information having logic operators (e.g: `at-spi2-core: 2.44.1 -> 2.46.0` should replace the installed `at-spi2-atk: 2.38`)
- not considering some conflict expressions when retrieving upgrade requirements (it could lead to a system breakage depending on the conflict)
- Debian
- not properly handling packages with names ending with `:i386` [#298](https://github.com/vinifmor/bauh/issues/298)
- Packaging

View File

@@ -5,7 +5,7 @@ import shutil
import traceback
from io import StringIO
from threading import Thread
from typing import List, Set, Tuple, Dict, Iterable, Optional, Any, Pattern
from typing import List, Set, Tuple, Dict, Iterable, Optional, Any, Pattern, Collection
from colorama import Fore
@@ -1081,3 +1081,18 @@ def map_available_packages() -> Optional[Dict[str, Any]]:
'r': package_data[0].strip(),
'i': len(package_data) == 4 and 'installed' in package_data[3]}
return res
def map_installed(pkgs: Optional[Collection[str]] = None) -> Optional[Dict[str, str]]:
output = run_cmd(f"pacman -Q {' '.join({*pkgs} if pkgs else '')}".strip(), print_error=False)
if output:
res = dict()
for raw_line in output.split("\n"):
line = raw_line.strip()
if line:
pkg_version = line.split(" ")
if len(pkg_version) == 2:
res[pkg_version[0]] = pkg_version[1]
return res

View File

@@ -22,7 +22,7 @@ class UpdateRequirementsContext:
aur_to_update: Dict[str, ArchPackage], repo_to_install: Dict[str, ArchPackage],
aur_to_install: Dict[str, ArchPackage], to_install: Dict[str, ArchPackage],
pkgs_data: Dict[str, dict], cannot_upgrade: Dict[str, UpgradeRequirement],
to_remove: Dict[str, UpgradeRequirement], installed_names: Set[str], provided_map: Dict[str, Set[str]],
to_remove: Dict[str, UpgradeRequirement], installed_names: Dict[str, str], provided_map: Dict[str, Set[str]],
aur_index: Set[str], arch_config: dict, remote_provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str],
root_password: Optional[str], aur_supported: bool):
self.to_update = to_update
@@ -33,7 +33,7 @@ class UpdateRequirementsContext:
self.pkgs_data = pkgs_data
self.cannot_upgrade = cannot_upgrade
self.root_password = root_password
self.installed_names = installed_names
self.installed = installed_names
self.provided_map = provided_map
self.to_remove = to_remove
self.to_install = to_install
@@ -150,13 +150,20 @@ class UpdatesSummarizer:
if data['c']:
for c in data['c']:
if c:
pkg_name = DependenciesAnalyser.re_dep_operator().split(c)[0]
if pkg_name != p and pkg_name in context.installed_names:
# source = provided_map[c]
root_conflict[pkg_name] = p
name_op_exp = DependenciesAnalyser.re_dep_operator().split(c)
conflict_name = name_op_exp[0]
if (p, pkg_name) in root_conflict.items():
mutual_conflicts[pkg_name] = p
if conflict_name != p:
conflict_version = context.installed.get(conflict_name)
if conflict_version:
if len(name_op_exp) == 1 or match_required_version(conflict_version,
name_op_exp[1],
name_op_exp[2]):
root_conflict[conflict_name] = p
if (p, conflict_name) in root_conflict.items():
mutual_conflicts[conflict_name] = p
if mutual_conflicts:
for pkg1, pkg2 in mutual_conflicts.items():
@@ -280,8 +287,8 @@ class UpdatesSummarizer:
ti = time.time()
self.logger.info("Filling provided names")
if not context.installed_names:
context.installed_names = pacman.list_installed_names()
if not context.installed:
context.installed = pacman.map_installed()
installed_to_ignore = set()
@@ -307,8 +314,8 @@ class UpdatesSummarizer:
if len(split_provided) > 1 and split_provided[0] != p:
pacman.fill_provided_map(split_provided[0], pkgname, context.provided_map)
if installed_to_ignore: # filling the provided names of the installed
installed_to_query = context.installed_names.difference(installed_to_ignore)
if context.installed and installed_to_ignore: # filling the provided names of the installed
installed_to_query = {*context.installed}.difference(installed_to_ignore)
if installed_to_query:
context.provided_map.update(pacman.map_provided(remote=False, pkgs=installed_to_query))
@@ -376,7 +383,7 @@ class UpdatesSummarizer:
remote_repo_map = pacman.map_repositories()
context = UpdateRequirementsContext(to_update={}, repo_to_update={}, aur_to_update={}, repo_to_install={},
aur_to_install={}, to_install={}, pkgs_data={}, cannot_upgrade={},
to_remove={}, installed_names=set(), provided_map={}, aur_index=set(),
to_remove={}, installed_names=dict(), provided_map={}, aur_index=set(),
arch_config=arch_config, root_password=root_password,
remote_provided_map=remote_provided_map, remote_repo_map=remote_repo_map,
aur_supported=self.aur_supported)
@@ -606,7 +613,7 @@ class UpdatesSummarizer:
for r in reqs:
if r in transaction_pkgs:
reqs_in_transaction.add(r)
elif r in context.installed_names:
elif r in context.installed:
reqs_not_in_transaction.add(r)
if not reqs_not_in_transaction and not reqs_in_transaction: