[arch] improvement: allowing AUR packages to be installed as dependencies of a repository package | fix: not displaying all possible AUR providers for a given dependency

This commit is contained in:
Vinicius Moreira
2022-01-28 12:05:58 -03:00
parent f69ed7aa4a
commit ca9b3d0e51
14 changed files with 312 additions and 168 deletions

View File

@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Improvements ### Improvements
- Arch - Arch
- not rechecking sub-dependencies of an AUR dependency to be installed - not rechecking sub-dependencies of an AUR dependency to be installed
- allowing AUR packages to be installed as dependencies of a repository package
### Fixes ### Fixes
- General - General
@@ -17,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Arch - Arch
- not upgrading a package when a dependent package relies on a specific version with epoch (e.g: alsa-plugins 1:1.2.6-1 would not be upgraded to 1:1.2.6-2 because lib32-alsa-plugins relies on 1:1.2.6) - not upgrading a package when a dependent package relies on a specific version with epoch (e.g: alsa-plugins 1:1.2.6-1 would not be upgraded to 1:1.2.6-2 because lib32-alsa-plugins relies on 1:1.2.6)
- not informing all the provided packages on the transaction context to the dependency sorting algorithm (could lead to a wrong installation order) - not informing all the provided packages on the transaction context to the dependency sorting algorithm (could lead to a wrong installation order)
- not displaying all possible AUR providers for a given dependency
### UI ### UI
- new logo by [DN-debug](https://github.com/DN-debug) - new logo by [DN-debug](https://github.com/DN-debug)

View File

@@ -2,7 +2,7 @@ import logging
import os import os
import re import re
import urllib.parse import urllib.parse
from typing import Set, List, Iterable, Dict, Optional from typing import Set, List, Iterable, Dict, Optional, Generator, Tuple
import requests import requests
@@ -119,6 +119,43 @@ class AURClient:
except: except:
return [] return []
def map_provided(self, pkgname: str, pkgver: str, provided: Optional[Iterable[str]] = None, strip_epoch: bool = True) -> Set[str]:
all_provided = {pkgname, f"{pkgname}={pkgver.split('-')[0] if strip_epoch else pkgver}"}
if provided:
for provided in provided:
all_provided.add(provided)
all_provided.add(provided.split('=', 1)[0])
return all_provided
def gen_updates_data(self, names: Iterable[str]) -> Generator[Tuple[str, dict], None, None]:
for package in self.get_info(names):
pkgname, pkgver = package['Name'], package['Version'].split('-')[0]
deps = set()
for dtype in ('Depends', 'MakeDepends', 'CheckDepends'):
dep_set = package.get(dtype)
if dep_set:
deps.update(dep_set)
conflicts = set()
pkg_conflicts = package.get('Conflicts')
if pkg_conflicts:
conflicts.update(pkg_conflicts)
yield pkgname, {
'v': pkgver,
'b': package.get('PackageBase', pkgname),
'r': 'aur',
'p': self.map_provided(pkgname=pkgname, pkgver=pkgver, provided=package.get('Provides'), strip_epoch=False),
'd': deps,
'c': conflicts,
'ds': None,
's': None}
def get_src_info(self, name: str, real_name: Optional[str] = None) -> dict: def get_src_info(self, name: str, real_name: Optional[str] = None) -> dict:
srcinfo = self.srcinfo_cache.get(name) srcinfo = self.srcinfo_cache.get(name)
@@ -229,7 +266,7 @@ class AURClient:
def clean_caches(self): def clean_caches(self):
self.srcinfo_cache.clear() self.srcinfo_cache.clear()
def map_update_data(self, pkgname: str, latest_version: Optional[str], srcinfo: Optional[dict] = None) -> dict: def map_update_data(self, pkgname: str, latest_version: Optional[str] = None, srcinfo: Optional[dict] = None) -> dict:
info = self.get_src_info(pkgname) if not srcinfo else srcinfo info = self.get_src_info(pkgname) if not srcinfo else srcinfo
provided = set() provided = set()

View File

@@ -209,7 +209,7 @@ class ArchManager(SoftwareManager):
self.enabled = True self.enabled = True
self.arch_distro = context.distro == 'arch' self.arch_distro = context.distro == 'arch'
self.categories = {} self.categories = {}
self.deps_analyser = DependenciesAnalyser(self.aur_client, self.i18n) self.deps_analyser = DependenciesAnalyser(self.aur_client, self.i18n, self.logger)
self.http_client = context.http_client self.http_client = context.http_client
self._custom_actions: Optional[Dict[str, CustomSoftwareAction]] = None self._custom_actions: Optional[Dict[str, CustomSoftwareAction]] = None
self.index_aur = None self.index_aur = None
@@ -2333,7 +2333,7 @@ class ArchManager(SoftwareManager):
to_install = [] to_install = []
if context.missing_deps: if context.missing_deps:
to_install.extend((d[0] for d in context.missing_deps)) to_install.extend((d[0] for d in context.missing_deps if d[1] != 'aur'))
to_install.extend(pkgpaths) to_install.extend(pkgpaths)
@@ -2357,7 +2357,8 @@ class ArchManager(SoftwareManager):
status_handler = None status_handler = None
installed_with_same_name = self.read_installed(disk_loader=context.disk_loader, internet_available=True, names=context.get_package_names()).installed installed_with_same_name = self.read_installed(disk_loader=context.disk_loader, internet_available=True, names=context.get_package_names()).installed
context.watcher.change_substatus(self.i18n['arch.installing.package'].format(bold(context.name))) context.watcher.change_substatus(self.i18n['arch.installing.package'].format(bold(context.name))) #
installed = self._handle_install_call(context=context, to_install=to_install, status_handler=status_handler) installed = self._handle_install_call(context=context, to_install=to_install, status_handler=status_handler)
if status_handler: if status_handler:
@@ -2600,29 +2601,9 @@ class ArchManager(SoftwareManager):
return TransactionResult(success=pkg_installed, installed=installed, removed=removed) return TransactionResult(success=pkg_installed, installed=installed, removed=removed)
def _install_from_repository(self, context: TransactionContext) -> bool: def _install_from_repository(self, context: TransactionContext) -> bool:
try: if not self._handle_missing_deps(context):
missing_deps = self._list_missing_deps(context)
except PackageNotFoundException:
self.logger.error("Package '{}' was not found")
return False return False
if missing_deps is None:
return False # called off by the user
if missing_deps:
if any((dep for dep in missing_deps if dep[1] == 'aur')):
context.watcher.show_message(title=self.i18n['error'].capitalize(),
body=self.i18n['arch.install.repo_pkg.error.aur_deps'],
type_=MessageType.ERROR)
return False
context.missing_deps = missing_deps
context.watcher.change_substatus(self.i18n['arch.missing_deps_found'].format(bold(context.name)))
if not confirmation.request_install_missing_deps(context.name, missing_deps, context.watcher, self.i18n):
context.watcher.print(self.i18n['action.cancelled'])
return False
res = self._install(context) res = self._install(context)
if res and not context.skip_opt_deps: if res and not context.skip_opt_deps:

View File

@@ -1,7 +1,8 @@
import re import re
import traceback import traceback
from logging import Logger
from threading import Thread from threading import Thread
from typing import Set, List, Tuple, Dict, Iterable, Optional from typing import Set, List, Tuple, Dict, Iterable, Optional, Generator
from bauh.api.abstract.handler import ProcessWatcher from bauh.api.abstract.handler import ProcessWatcher
from bauh.gems.arch import pacman, message, sorting, confirmation from bauh.gems.arch import pacman, message, sorting, confirmation
@@ -13,10 +14,11 @@ from bauh.view.util.translation import I18n
class DependenciesAnalyser: class DependenciesAnalyser:
def __init__(self, aur_client: AURClient, i18n: I18n): def __init__(self, aur_client: AURClient, i18n: I18n, logger: Logger):
self.aur_client = aur_client self.aur_client = aur_client
self.i18n = i18n self.i18n = i18n
self.re_dep_operator = re.compile(r'([<>=]+)') self.re_dep_operator = re.compile(r'([<>=]+)')
self._log = logger
def _fill_repository(self, name: str, output: List[Tuple[str, str]]): def _fill_repository(self, name: str, output: List[Tuple[str, str]]):
@@ -40,8 +42,8 @@ class DependenciesAnalyser:
output.append((name, '')) output.append((name, ''))
def get_missing_packages(self, names: Set[str], repository: str = None, in_analysis: Set[str] = None) -> List[ def get_missing_packages(self, names: Set[str], repository: Optional[str] = None, in_analysis: Optional[Set[str]] = None) -> \
Tuple[str, str]]: List[Tuple[str, str]]:
""" """
:param names: :param names:
:param repository: :param repository:
@@ -157,7 +159,8 @@ class DependenciesAnalyser:
if missing_subdeps: if missing_subdeps:
for dep in missing_subdeps: for dep in missing_subdeps:
if not dep[1]: if not dep[1]:
message.show_dep_not_found(dep[0], self.i18n, watcher) dependents = ', '.join(deps[0]) # it is not possible to know which is the exact dependent
message.show_dep_not_found(dep[0], self.i18n, watcher, dependent=dependents)
return return
for dep in missing_subdeps: for dep in missing_subdeps:
@@ -175,25 +178,28 @@ class DependenciesAnalyser:
return sorted_deps return sorted_deps
def _fill_missing_dep(self, dep_name: str, dep_exp: str, aur_index: Iterable[str], def _find_repo_providers(self, dep_name: str, dep_exp: str, remote_provided_map: Dict[str, Set[str]],
missing_deps: Set[Tuple[str, str]], deps_data: Dict[str, dict], remote_repo_map: Dict[str, str]) -> Generator[Tuple[str, str, Optional[dict]], None, None]:
remote_provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str],
repo_deps: Set[str], aur_deps: Set[str], deps_data: Dict[str, dict], watcher: ProcessWatcher,
automatch_providers: bool):
if dep_name == dep_exp: if dep_name == dep_exp:
providers = remote_provided_map.get(dep_name) providers = remote_provided_map.get(dep_name)
if not providers: # try to find the package through the pacman's search mechanism if providers:
for pkgname in providers:
yield pkgname, remote_repo_map.get(pkgname), None
else: # try to find the package through the pacman's search mechanism
match = pacman.find_one_match(dep_name) match = pacman.find_one_match(dep_name)
if match: if match:
providers = {match} yield match, remote_repo_map.get(match), None
else: # handling cases when the dep has an expression ( e.g: xpto>=0.12 ) else: # handling cases when the dep has an expression ( e.g: xpto>=0.12 )
providers = remote_provided_map.get(dep_exp) exact_exp_providers = remote_provided_map.get(dep_exp)
if providers is None: if exact_exp_providers:
for p in exact_exp_providers:
yield p, remote_repo_map.get(p), None
else:
providers = remote_provided_map.get(dep_name) providers = remote_provided_map.get(dep_name)
if not providers: # try to find the package through the pacman's search mechanism if not providers: # try to find the package through the pacman's search mechanism
@@ -203,103 +209,177 @@ class DependenciesAnalyser:
providers = {match} providers = {match}
if providers: if providers:
no_mapped_data = {p for p in providers if providers_no_provided_data = {p for p in providers if p not in deps_data}
p not in deps_data} # checking providers with no mapped data missing_providers_data = None
if no_mapped_data: if providers_no_provided_data:
providers_data = pacman.map_updates_data(no_mapped_data) missing_providers_data = pacman.map_updates_data(providers_no_provided_data)
if not providers_data: if not missing_providers_data:
raise Exception("Could not retrieve the info from providers: {}".format(no_mapped_data)) raise Exception(f"Could not retrieve information from providers: "
f"{', '.join(providers_no_provided_data)}")
deps_data.update(providers_data) # adding missing providers data data_not_found = {p for p in providers if p not in missing_providers_data}
if data_not_found:
raise Exception(f"Could not retrieve information from providers: "
f"{', '.join(data_not_found)}")
matched_providers = set()
split_informed_dep = self.re_dep_operator.split(dep_exp) split_informed_dep = self.re_dep_operator.split(dep_exp)
try:
version_required = split_informed_dep[2]
exp_op = split_informed_dep[1] if split_informed_dep[1] != '=' else '=='
for p in providers: version_required = split_informed_dep[2]
provided = deps_data[p]['p'] exp_op = split_informed_dep[1] if split_informed_dep[1] != '=' else '=='
for provided_exp in provided: for p in providers:
split_dep = self.re_dep_operator.split(provided_exp) info = deps_data.get(p)
if len(split_dep) == 3 and split_dep[0] == dep_name: if not info and missing_providers_data:
version_provided = split_dep[2] info = missing_providers_data[p]
if match_required_version(version_provided, exp_op, version_required): for provided_exp in info['p']:
matched_providers.add(p) split_dep = self.re_dep_operator.split(provided_exp)
break
providers = matched_providers if len(split_dep) == 3 and split_dep[0] == dep_name:
except: version_provided = split_dep[2]
traceback.print_exc()
if providers: if match_required_version(version_provided, exp_op, version_required):
if len(providers) > 1: yield p, remote_repo_map.get(p), info
dep_data = None break
if automatch_providers: def _find_aur_providers(self, dep_name: str, dep_exp: str, aur_index: Iterable[str], exact_match: bool) -> Generator[Tuple[str, dict], None, None]:
exact_matches = [p for p in providers if p == dep_name] if exact_match and dep_name in aur_index:
if exact_matches:
dep_data = (exact_matches[0], remote_repo_map.get(exact_matches[0]))
if not dep_data:
dep_data = (dep_name, '__several__')
else:
real_name = providers.pop()
dep_data = (real_name, remote_repo_map.get(real_name))
repo_deps.add(dep_data[0])
missing_deps.add(dep_data)
elif aur_index and dep_name in aur_index:
if dep_name == dep_exp: if dep_name == dep_exp:
aur_deps.add(dep_name) yield from self.aur_client.gen_updates_data((dep_name,))
missing_deps.add((dep_name, 'aur')) return
else: else:
dep_info = self.aur_client.get_info({dep_name}) for _, dep_data in self.aur_client.gen_updates_data((dep_name,)):
if not dep_info:
self.__raise_dependency_not_found(dep_exp, watcher)
else:
try:
dep_version = dep_info[0]['Version']
except:
traceback.print_exc()
return self.__raise_dependency_not_found(dep_exp, watcher)
split_informed_dep = self.re_dep_operator.split(dep_exp) split_informed_dep = self.re_dep_operator.split(dep_exp)
version_required = split_informed_dep[2]
exp_op = split_informed_dep[1].strip()
if match_required_version(dep_data['v'], exp_op, version_required):
yield dep_name, dep_data
return
aur_search = self.aur_client.search(dep_name)
if aur_search:
if dep_name == dep_exp:
version_required, exp_op = None, None
else:
split_informed_dep = self.re_dep_operator.split(dep_exp)
version_required = split_informed_dep[2]
exp_op = split_informed_dep[1] if split_informed_dep[1] != '=' else '=='
for pkgname, pkgdata in self.aur_client.gen_updates_data(
(aur_res['Name'] for aur_res in aur_search['results'])):
if pkgname == dep_name or (dep_name in pkgdata['p']):
try: try:
version_required = split_informed_dep[2] if not version_required or match_required_version(pkgdata['v'], exp_op,
exp_op = split_informed_dep[1].strip() version_required):
yield pkgname, pkgdata
if match_required_version(dep_version, exp_op, version_required):
aur_deps.add(dep_name)
missing_deps.add((dep_name, 'aur'))
except: except:
self.__raise_dependency_not_found(dep_exp, watcher) self._log.warning(f"Could not compare AUR package '{pkgname}' version '{pkgdata['v']}' "
else: f"with the dependency expression '{dep_exp}'")
self.__raise_dependency_not_found(dep_exp, watcher) traceback.print_exc()
def __raise_dependency_not_found(self, dep_exp: str, watcher: Optional[ProcessWatcher]): def _fill_missing_dep(self, dep_name: str, dep_exp: str, aur_index: Iterable[str],
missing_deps: Set[Tuple[str, str]],
remote_provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str],
repo_deps: Set[str], aur_deps: Set[str], deps_data: Dict[str, dict], watcher: ProcessWatcher,
automatch_providers: bool, dependent: Optional[str] = None):
repo_matches = None
for pkgname, repo, data in self._find_repo_providers(dep_name=dep_name, dep_exp=dep_exp,
remote_repo_map=remote_repo_map,
remote_provided_map=remote_provided_map,
deps_data=deps_data):
if automatch_providers and pkgname == dep_name:
missing_deps.add((pkgname, repo))
repo_deps.add(pkgname)
if data:
deps_data[pkgname] = data
return
if repo_matches is None:
repo_matches = []
repo_matches.append((pkgname, repo, data))
aur_matches = None
if aur_index:
for pkgname, pkgdata in self._find_aur_providers(dep_name=dep_name, dep_exp=dep_exp, aur_index=aur_index,
exact_match=automatch_providers):
if automatch_providers and pkgname == dep_name:
missing_deps.add((pkgname, 'aur'))
aur_deps.add(pkgname)
deps_data[pkgname] = pkgdata
return
if aur_matches is None:
aur_matches = []
aur_matches.append((pkgname, pkgdata))
total_matches = (len(repo_matches) if repo_matches else 0) + (len(aur_matches) if aur_matches else 0)
if total_matches == 0:
self.__raise_dependency_not_found(dep_exp, watcher, dependent)
elif total_matches == 1:
if repo_matches:
repo_pkg = [*repo_matches][0]
if repo_pkg[2]:
deps_data[repo_pkg[0]] = repo_pkg[2] # already updating the deps data (if available)
match = (repo_pkg[0], repo_pkg[1])
repo_deps.add(repo_pkg[0])
else:
aur_pkg = aur_matches[0]
deps_data[aur_pkg[0]] = aur_pkg[1] # already updating the deps data (if available)
aur_deps.add(aur_pkg[0])
match = aur_pkg[0], 'aur'
missing_deps.add(match)
elif total_matches > 1:
missing_deps.add((dep_name, '__several__'))
if repo_matches:
repo_deps.add(dep_name)
if aur_matches:
aur_deps.add(dep_name)
for pkgname, _ in aur_matches:
for key in (dep_name, dep_exp):
key_provided = remote_provided_map.get(key, set())
remote_provided_map[key] = key_provided
key_provided.add(pkgname)
if pkgname not in remote_repo_map:
remote_repo_map[pkgname] = 'aur'
def __raise_dependency_not_found(self, dep_exp: str, watcher: Optional[ProcessWatcher], dependent: Optional[str] = None):
if watcher: if watcher:
message.show_dep_not_found(dep_exp, self.i18n, watcher) message.show_dep_not_found(depname=dep_exp, i18n=self.i18n, watcher=watcher, dependent=dependent)
raise PackageNotFoundException(dep_exp) raise PackageNotFoundException(dep_exp)
else: else:
raise PackageNotFoundException(dep_exp) raise PackageNotFoundException(dep_exp)
def __fill_aur_update_data(self, pkgname: str, output: dict): def _fill_aur_updates_data(self, pkgnames: Iterable[str], output_data: dict):
output[pkgname] = self.aur_client.map_update_data(pkgname, None) for pkgname, pkgdata in self.aur_client.gen_updates_data(pkgnames):
output_data[pkgname] = pkgdata
def map_missing_deps(self, pkgs_data: Dict[str, dict], provided_map: Dict[str, Set[str]], def map_missing_deps(self, pkgs_data: Dict[str, dict], provided_map: Dict[str, Set[str]],
remote_provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str], remote_provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str],
aur_index: Iterable[str], deps_checked: Set[str], deps_data: Dict[str, dict], aur_index: Iterable[str], deps_checked: Set[str], deps_data: Dict[str, dict],
sort: bool, watcher: ProcessWatcher, choose_providers: bool = True, sort: bool, watcher: ProcessWatcher, choose_providers: bool = True,
automatch_providers: bool = False) -> List[Tuple[str, str]]: automatch_providers: bool = False) -> Optional[List[Tuple[str, str]]]:
sorted_deps = [] # it will hold the proper order to install the missing dependencies sorted_deps = [] # it will hold the proper order to install the missing dependencies
missing_deps, repo_missing, aur_missing = set(), set(), set() missing_deps, repo_missing, aur_missing = set(), set(), set()
@@ -325,7 +405,8 @@ class DependenciesAnalyser:
remote_repo_map=remote_repo_map, remote_repo_map=remote_repo_map,
repo_deps=repo_missing, aur_deps=aur_missing, watcher=watcher, repo_deps=repo_missing, aur_deps=aur_missing, watcher=watcher,
deps_data=deps_data, deps_data=deps_data,
automatch_providers=automatch_providers) automatch_providers=automatch_providers,
dependent=p)
else: else:
version_pattern = '{}='.format(dep_name) version_pattern = '{}='.format(dep_name)
version_found = [p for p in provided_map if p.startswith(version_pattern)] version_found = [p for p in provided_map if p.startswith(version_pattern)]
@@ -343,7 +424,8 @@ class DependenciesAnalyser:
repo_deps=repo_missing, aur_deps=aur_missing, repo_deps=repo_missing, aur_deps=aur_missing,
watcher=watcher, watcher=watcher,
deps_data=deps_data, deps_data=deps_data,
automatch_providers=automatch_providers) automatch_providers=automatch_providers,
dependent=p)
else: else:
self._fill_missing_dep(dep_name=dep_name, dep_exp=dep, aur_index=aur_index, self._fill_missing_dep(dep_name=dep_name, dep_exp=dep, aur_index=aur_index,
missing_deps=missing_deps, missing_deps=missing_deps,
@@ -352,34 +434,11 @@ class DependenciesAnalyser:
repo_deps=repo_missing, aur_deps=aur_missing, repo_deps=repo_missing, aur_deps=aur_missing,
watcher=watcher, watcher=watcher,
deps_data=deps_data, deps_data=deps_data,
automatch_providers=automatch_providers) automatch_providers=automatch_providers,
dependent=p)
if missing_deps: if missing_deps:
if repo_missing: self._fill_single_providers_data(missing_deps, repo_missing, aur_missing, deps_data)
with_single_providers = []
for d in missing_deps:
if d[0] in repo_missing and d[0] not in deps_data:
if d[1] == '__several__':
deps_data[d[0]] = {'d': None, 'p': d[0], 'r': d[1]}
else:
with_single_providers.append(d[0])
if with_single_providers:
data = pacman.map_updates_data(with_single_providers)
if data:
deps_data.update(data)
if aur_missing:
aur_threads = []
for pkgname in aur_missing:
t = Thread(target=self.__fill_aur_update_data, args=(pkgname, deps_data), daemon=True)
t.start()
aur_threads.append(t)
for t in aur_threads:
t.join()
missing_subdeps = self.map_missing_deps(pkgs_data={**deps_data}, provided_map=provided_map, aur_index=aur_index, missing_subdeps = self.map_missing_deps(pkgs_data={**deps_data}, provided_map=provided_map, aur_index=aur_index,
deps_checked=deps_checked, sort=False, deps_data=deps_data, deps_checked=deps_checked, sort=False, deps_data=deps_data,
@@ -406,6 +465,51 @@ class DependenciesAnalyser:
return sorted_deps return sorted_deps
def _fill_single_providers_data(self, all_missing_deps: Iterable[Tuple[str, str]], repo_missing_deps: Iterable[str], aur_missing_deps: Iterable[str], deps_data: Dict[str, dict]):
"""
fills the missing data of the single dependency providers since they are already considered dependencies
(when several providers are available for given a dependency, the user must choose first)
"""
repo_providers_no_data, aur_providers_no_data = None, None
for dep_name, dep_repo in all_missing_deps:
if dep_repo == '__several__':
deps_data[dep_name] = {'d': None, 'p': {dep_name}, 'r': dep_repo}
elif dep_name not in deps_data:
if repo_missing_deps and dep_name in repo_missing_deps:
if repo_providers_no_data is None:
repo_providers_no_data = set()
repo_providers_no_data.add(dep_name)
elif aur_missing_deps and dep_name in aur_missing_deps:
if aur_providers_no_data is None:
aur_providers_no_data = set()
aur_providers_no_data.add(dep_name)
aur_data_filler, aur_providers_data = None, None
if aur_providers_no_data:
aur_providers_data = dict()
aur_data_filler = Thread(target=self._fill_aur_updates_data,
args=(aur_providers_no_data, aur_providers_data))
aur_data_filler.start()
if repo_providers_no_data:
repo_providers_data = pacman.map_updates_data(repo_providers_no_data)
if repo_providers_data:
deps_data.update(repo_providers_data)
for pkgname, pkgdata in self.aur_client.gen_updates_data(aur_providers_no_data):
deps_data[pkgname] = pkgdata
if aur_data_filler:
aur_data_filler.join()
if aur_providers_data:
deps_data.update(aur_providers_data)
def fill_providers_deps(self, missing_deps: List[Tuple[str, str]], def fill_providers_deps(self, missing_deps: List[Tuple[str, str]],
provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str], provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str],
already_checked: Set[str], remote_provided_map: Dict[str, Set[str]], already_checked: Set[str], remote_provided_map: Dict[str, Set[str]],
@@ -429,21 +533,45 @@ class DependenciesAnalyser:
remote_provided_map) remote_provided_map)
if deps_providers: if deps_providers:
all_providers = set() providers_repos = {}
repos_providers = set()
for providers in deps_providers.values(): for providers in deps_providers.values():
all_providers.update(providers) for provider in providers:
if remote_repo_map.get(provider) == 'aur':
providers_repos[provider] = 'aur'
else:
repos_providers.add(provider)
providers_repos = pacman.map_repositories(all_providers) providers_repos.update(pacman.map_repositories(repos_providers))
selected_providers = confirmation.request_providers(deps_providers, providers_repos, watcher, self.i18n) selected_providers = confirmation.request_providers(deps_providers, providers_repos, watcher, self.i18n)
if not selected_providers: if not selected_providers:
return return
else: else:
providers_data = pacman.map_updates_data( # adding the chosen providers for re-checking the missing dependencies
selected_providers) # adding the chosen providers to re-check the missing deps repo_selected, aur_selected = set(), set()
provided_map.update(pacman.map_provided(remote=True,
pkgs=selected_providers)) # adding the providers as "installed" packages for provider in selected_providers:
if provider in repos_providers:
repo_selected.add(provider)
else:
aur_selected.add(provider)
providers_data = dict()
if repo_selected:
providers_data.update(pacman.map_updates_data(repo_selected))
# adding the providers as "installed" packages
provided_map.update(pacman.map_provided(remote=True, pkgs=repo_selected))
if aur_selected:
for pkgname, pkgdata in self.aur_client.gen_updates_data(aur_selected):
providers_data[pkgname] = pkgdata
for provider in pkgdata['p']: # adding the providers as "installed" packages
currently_provided = provided_map.get(provider, set())
provided_map[provider] = currently_provided
currently_provided.add(pkgname)
providers_deps = self.map_missing_deps(pkgs_data=providers_data, providers_deps = self.map_missing_deps(pkgs_data=providers_data,
provided_map=provided_map, provided_map=provided_map,
@@ -457,6 +585,9 @@ class DependenciesAnalyser:
choose_providers=True, choose_providers=True,
automatch_providers=automatch_providers) automatch_providers=automatch_providers)
if providers_deps is None: # it means the user called off the installation process
return
# cleaning the already mapped providers deps: # cleaning the already mapped providers deps:
to_remove = [] to_remove = []

View File

@@ -1,4 +1,4 @@
from typing import Iterable from typing import Iterable, Optional
from bauh.api.abstract.handler import ProcessWatcher from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.view import MessageType from bauh.api.abstract.view import MessageType
@@ -13,11 +13,13 @@ def show_deps_not_installed(watcher: ProcessWatcher, pkgname: str, depnames: Ite
type_=MessageType.ERROR) type_=MessageType.ERROR)
def show_dep_not_found(depname: str, i18n: I18n, watcher: ProcessWatcher): def show_dep_not_found(depname: str, i18n: I18n, watcher: ProcessWatcher, dependent: Optional[str] = None):
body = '<p>{}</p><p>{}</p><p></p><p>{}</p>'.format(i18n['arch.install.dep_not_found.body.l1'].format(bold(depname)), source = f" {bold('(' + dependent + ')')}" if dependent else ''
i18n['arch.install.dep_not_found.body.l2'],
i18n['arch.install.dep_not_found.body.l3']) body = f"<p>{i18n['arch.install.dep_not_found.body.l1'].format(dep=bold(depname), source=source)}</p>" \
f"<p><{i18n['arch.install.dep_not_found.body.l2']}</p>" \
f"<p>{i18n['arch.install.dep_not_found.body.l3']}</p>"
watcher.show_message(title=i18n['arch.install.dep_not_found.title'].capitalize(), watcher.show_message(title=i18n['arch.install.dep_not_found.title'].capitalize(),
body=body, body=body,

View File

@@ -195,7 +195,7 @@ arch.install.aur.unknown_key.title=Clau pública necessària
arch.install.aur.unknown_key.body=Per a continuar amb la instal·lació de {} cal confiar en la clau pública següent {} arch.install.aur.unknown_key.body=Per a continuar amb la instal·lació de {} cal confiar en la clau pública següent {}
arch.install.conflict.popup.body=Les aplicacions {} estan en conflicte. Heu de desinstal·lar una per a instal·lar laltra. Voleu continuar? arch.install.conflict.popup.body=Les aplicacions {} estan en conflicte. Heu de desinstal·lar una per a instal·lar laltra. Voleu continuar?
arch.install.conflict.popup.title=Sha detectat un conflicte arch.install.conflict.popup.title=Sha detectat un conflicte
arch.install.dep_not_found.body.l1=No sha trobat la dependència requerida {} a lAUR ni als dipòsits arch.install.dep_not_found.body.l1=No sha trobat la dependència requerida {dep}{source} a lAUR ni als dipòsits
arch.install.dep_not_found.body.l2=It might be a package database synchronization problem. arch.install.dep_not_found.body.l2=It might be a package database synchronization problem.
arch.install.dep_not_found.body.l3=Operation cancelled. arch.install.dep_not_found.body.l3=Operation cancelled.
arch.install.dep_not_found.title=No sha trobat la dependència arch.install.dep_not_found.title=No sha trobat la dependència
@@ -208,7 +208,6 @@ arch.install.optdep.error=Could not install the optional packages: {}
arch.install.optdeps.request.body={} sha instal·lat correctament. Hi ha paquets opcionals associats que potser voldreu instal·lar arch.install.optdeps.request.body={} sha instal·lat correctament. Hi ha paquets opcionals associats que potser voldreu instal·lar
arch.install.optdeps.request.help=Marqueu els que voleu arch.install.optdeps.request.help=Marqueu els que voleu
arch.install.optdeps.request.title=Dependències opcionals arch.install.optdeps.request.title=Dependències opcionals
arch.install.repo_pkg.error.aur_deps=It is not possible to install an AUR package as dependency of a repository package
arch.installing.package=Sestà instal·lant el paquet {} arch.installing.package=Sestà instal·lant el paquet {}
arch.checking_unnecessary_deps=Checking if there are packages no longer needed arch.checking_unnecessary_deps=Checking if there are packages no longer needed
arch.makepkg.optimizing=Optimitzant la recopilació arch.makepkg.optimizing=Optimitzant la recopilació

View File

@@ -195,7 +195,7 @@ arch.install.aur.unknown_key.body=Um mit der Installation von {} fortzufahren is
arch.install.aur.unknown_key.title=Öffentlicher Schlüssel nötig arch.install.aur.unknown_key.title=Öffentlicher Schlüssel nötig
arch.install.conflict.popup.body=Die Anwendungen {} können nicht gleichzeitig installiert sein. Du musst eine deinstallieren um die andere zu installieren. Fortfahren? arch.install.conflict.popup.body=Die Anwendungen {} können nicht gleichzeitig installiert sein. Du musst eine deinstallieren um die andere zu installieren. Fortfahren?
arch.install.conflict.popup.title=Konflikt entdeckt arch.install.conflict.popup.title=Konflikt entdeckt
arch.install.dep_not_found.body.l1=Nötige Abhängigkeit {} wurde weder im AUR noch in den standard Spiegelservern gefunden arch.install.dep_not_found.body.l1=Nötige Abhängigkeit {dep}{source} wurde weder im AUR noch in den standard Spiegelservern gefunden
arch.install.dep_not_found.body.l2=It might be a package database synchronization problem. arch.install.dep_not_found.body.l2=It might be a package database synchronization problem.
arch.install.dep_not_found.body.l3=Operation cancelled. arch.install.dep_not_found.body.l3=Operation cancelled.
arch.install.dep_not_found.title=Abhängigkeit nicht gefunden arch.install.dep_not_found.title=Abhängigkeit nicht gefunden
@@ -208,7 +208,6 @@ arch.install.optdep.error=Could not install the optional packages: {}
arch.install.optdeps.request.body={} wurde erfolgreich installiert! Es gibt optionale zugehörige Pakete welche du vielleicht auch installieren möchtest arch.install.optdeps.request.body={} wurde erfolgreich installiert! Es gibt optionale zugehörige Pakete welche du vielleicht auch installieren möchtest
arch.install.optdeps.request.help=Wähle entsprechende aus arch.install.optdeps.request.help=Wähle entsprechende aus
arch.install.optdeps.request.title=Optionale Abhängigkeiten arch.install.optdeps.request.title=Optionale Abhängigkeiten
arch.install.repo_pkg.error.aur_deps=It is not possible to install an AUR package as dependency of a repository package
arch.installing.package=Paket {} installieren arch.installing.package=Paket {} installieren
arch.checking_unnecessary_deps=Checking if there are packages no longer needed arch.checking_unnecessary_deps=Checking if there are packages no longer needed
arch.makepkg.optimizing=Optimiert die Zusammenstellung arch.makepkg.optimizing=Optimiert die Zusammenstellung

View File

@@ -195,7 +195,7 @@ arch.install.aur.unknown_key.body=To continue {} installation is necessary to tr
arch.install.aur.unknown_key.title=Public key required arch.install.aur.unknown_key.title=Public key required
arch.install.conflict.popup.body=The applications {} are in conflict. You must uninstall one to install the other. Continue ? arch.install.conflict.popup.body=The applications {} are in conflict. You must uninstall one to install the other. Continue ?
arch.install.conflict.popup.title=Conflict detected arch.install.conflict.popup.title=Conflict detected
arch.install.dep_not_found.body.l1=Required dependency {} was not found in AUR nor in the repositories. arch.install.dep_not_found.body.l1=Required dependency {dep}{source} was not found on the repositories nor AUR.
arch.install.dep_not_found.body.l2=It might be a package database synchronization problem. arch.install.dep_not_found.body.l2=It might be a package database synchronization problem.
arch.install.dep_not_found.body.l3=Operation cancelled. arch.install.dep_not_found.body.l3=Operation cancelled.
arch.install.dep_not_found.title=Dependency not found arch.install.dep_not_found.title=Dependency not found
@@ -208,7 +208,6 @@ arch.install.optdep.error=Could not install the optional packages: {}
arch.install.optdeps.request.body={} was succesfully installed ! There are some optional associated packages that you might want to install arch.install.optdeps.request.body={} was succesfully installed ! There are some optional associated packages that you might want to install
arch.install.optdeps.request.help=Check those you want arch.install.optdeps.request.help=Check those you want
arch.install.optdeps.request.title=Optional dependencies arch.install.optdeps.request.title=Optional dependencies
arch.install.repo_pkg.error.aur_deps=It is not possible to install an AUR package as dependency of a repository package
arch.installing.package=Installing {} package arch.installing.package=Installing {} package
arch.checking_unnecessary_deps=Checking if there are packages no longer needed arch.checking_unnecessary_deps=Checking if there are packages no longer needed
arch.makepkg.optimizing=Optimizing the compilation arch.makepkg.optimizing=Optimizing the compilation

View File

@@ -195,7 +195,7 @@ arch.install.aur.unknown_key.body=Para continuar la instalación de {} es necesa
arch.install.aur.unknown_key.title=Clave pública necesaria arch.install.aur.unknown_key.title=Clave pública necesaria
arch.install.conflict.popup.body=Los aplicativos {} estan en conflicto. Debe desinstalar uno para instalar el otro. ¿Continuar? arch.install.conflict.popup.body=Los aplicativos {} estan en conflicto. Debe desinstalar uno para instalar el otro. ¿Continuar?
arch.install.conflict.popup.title=Conflicto detectado arch.install.conflict.popup.title=Conflicto detectado
arch.install.dep_not_found.body.l1=No se encontró la dependencia requerida {} en AUR ni en los repositorios. arch.install.dep_not_found.body.l1=No se encontró la dependencia requerida {dep}{source} en AUR ni en los repositorios.
arch.install.dep_not_found.body.l2=Puede ser un problema de sincronización de la base de paquetes. arch.install.dep_not_found.body.l2=Puede ser un problema de sincronización de la base de paquetes.
arch.install.dep_not_found.body.l3=Operación cancelada. arch.install.dep_not_found.body.l3=Operación cancelada.
arch.install.dep_not_found.title=Dependencia no encontrada arch.install.dep_not_found.title=Dependencia no encontrada
@@ -208,7 +208,6 @@ arch.install.optdep.error=No se pudo instalar los paquetes opcionales: {}
arch.install.optdeps.request.body=¡{} se instaló correctamente! Hay algunos paquetes opcionales asociados que es posible que desee instalar arch.install.optdeps.request.body=¡{} se instaló correctamente! Hay algunos paquetes opcionales asociados que es posible que desee instalar
arch.install.optdeps.request.help=Marque los que desee arch.install.optdeps.request.help=Marque los que desee
arch.install.optdeps.request.title=Dependencias opcionales arch.install.optdeps.request.title=Dependencias opcionales
arch.install.repo_pkg.error.aur_deps=It is not possible to install an AUR package as dependency of a repository package
arch.installing.package=Instalando el paquete {} arch.installing.package=Instalando el paquete {}
arch.checking_unnecessary_deps=Verificando se hay paquetes innecesarios arch.checking_unnecessary_deps=Verificando se hay paquetes innecesarios
arch.makepkg.optimizing=Optimizing the compilation arch.makepkg.optimizing=Optimizing the compilation

View File

@@ -195,7 +195,7 @@ arch.install.aur.unknown_key.body=Pour continuer à installer {} il faut faire c
arch.install.aur.unknown_key.title=Clé publique requise arch.install.aur.unknown_key.title=Clé publique requise
arch.install.conflict.popup.body=Les applications {} sont en conflit. Il faut en désinstaller une pour installer l'autre. Continuer ? arch.install.conflict.popup.body=Les applications {} sont en conflit. Il faut en désinstaller une pour installer l'autre. Continuer ?
arch.install.conflict.popup.title=Conflit détecté arch.install.conflict.popup.title=Conflit détecté
arch.install.dep_not_found.body.l1=Dépendance requise {} absente d AUR ou des dépôts. arch.install.dep_not_found.body.l1=Dépendance requise {dep}{source} absente d AUR ou des dépôts.
arch.install.dep_not_found.body.l2=Sans doute un problème de synchronisation de base de données. arch.install.dep_not_found.body.l2=Sans doute un problème de synchronisation de base de données.
arch.install.dep_not_found.body.l3=Operation annulée. arch.install.dep_not_found.body.l3=Operation annulée.
arch.install.dep_not_found.title=Dependance non trouvée arch.install.dep_not_found.title=Dependance non trouvée
@@ -208,7 +208,6 @@ arch.install.optdep.error=Impossible d'installer les paquets optionnels: {}
arch.install.optdeps.request.body={} installé avec succès ! Il y a des paquets optionnels que vous pouvez installer arch.install.optdeps.request.body={} installé avec succès ! Il y a des paquets optionnels que vous pouvez installer
arch.install.optdeps.request.help=Cochez ceux que vous désirez arch.install.optdeps.request.help=Cochez ceux que vous désirez
arch.install.optdeps.request.title=Dépendances optionnelles arch.install.optdeps.request.title=Dépendances optionnelles
arch.install.repo_pkg.error.aur_deps=Impossible d'installer un paquet AUR comme une dépendance d'un paquet venant d'un dépôt
arch.installing.package=Installation du paquet {} arch.installing.package=Installation du paquet {}
arch.checking_unnecessary_deps=Calcul des paquets devenus inutiles arch.checking_unnecessary_deps=Calcul des paquets devenus inutiles
arch.makepkg.optimizing=Optimisation de la compilation arch.makepkg.optimizing=Optimisation de la compilation

View File

@@ -195,7 +195,7 @@ arch.install.aur.unknown_key.body=Per continuare {} l'installazione è necessari
arch.install.aur.unknown_key.title=Chiave pubblica richiesta arch.install.aur.unknown_key.title=Chiave pubblica richiesta
arch.install.conflict.popup.body=Le applicazioni {} sono in conflitto. È necessario disinstallarne una per installare l'altra. Continua ? arch.install.conflict.popup.body=Le applicazioni {} sono in conflitto. È necessario disinstallarne una per installare l'altra. Continua ?
arch.install.conflict.popup.title=Conflitto rilevato arch.install.conflict.popup.title=Conflitto rilevato
arch.install.dep_not_found.body.l1=La dipendenza richiesta {} non è stata trovata in AUR né nei depositos. arch.install.dep_not_found.body.l1=La dipendenza richiesta {dep}{source} non è stata trovata in AUR né nei depositos.
arch.install.dep_not_found.body.l2=It might be a package database synchronization problem. arch.install.dep_not_found.body.l2=It might be a package database synchronization problem.
arch.install.dep_not_found.body.l3=Operation cancelled. arch.install.dep_not_found.body.l3=Operation cancelled.
arch.install.dep_not_found.title=Dipendenza non trovata arch.install.dep_not_found.title=Dipendenza non trovata
@@ -208,7 +208,6 @@ arch.install.optdep.error=Could not install the optional packages: {}
arch.install.optdeps.request.body={} è stato installato con successo! Ci sono alcuni pacchetti associati opzionali che potresti voler installare arch.install.optdeps.request.body={} è stato installato con successo! Ci sono alcuni pacchetti associati opzionali che potresti voler installare
arch.install.optdeps.request.help=Controlla quelli che vuoi arch.install.optdeps.request.help=Controlla quelli che vuoi
arch.install.optdeps.request.title=Dipendenze opzionali arch.install.optdeps.request.title=Dipendenze opzionali
arch.install.repo_pkg.error.aur_deps=It is not possible to install an AUR package as dependency of a repository package
arch.installing.package=Installazione del pacchetto {} arch.installing.package=Installazione del pacchetto {}
arch.checking_unnecessary_deps=Checking if there are packages no longer needed arch.checking_unnecessary_deps=Checking if there are packages no longer needed
arch.makepkg.optimizing=Ottimizzando la compilazione arch.makepkg.optimizing=Ottimizzando la compilazione

View File

@@ -194,7 +194,7 @@ arch.install.aur.unknown_key.body=Para continuar a instalação de {} é ncessá
arch.install.aur.unknown_key.title=Chave pública necessária arch.install.aur.unknown_key.title=Chave pública necessária
arch.install.conflict.popup.body=Os aplicativos {} estão em conflito. Você precisa desinstalar um para instalar o outro. Continuar ? arch.install.conflict.popup.body=Os aplicativos {} estão em conflito. Você precisa desinstalar um para instalar o outro. Continuar ?
arch.install.conflict.popup.title=Conflito detectado arch.install.conflict.popup.title=Conflito detectado
arch.install.dep_not_found.body.l1=A dependência {} não foi encontrado no AUR nem nos repositórios. arch.install.dep_not_found.body.l1=A dependência {dep}{source} não foi encontrado no AUR nem nos repositórios.
arch.install.dep_not_found.body.l2=Pode ser um problema de sincronização das bases de pacotes. arch.install.dep_not_found.body.l2=Pode ser um problema de sincronização das bases de pacotes.
arch.install.dep_not_found.body.l3=Operação cancelada. arch.install.dep_not_found.body.l3=Operação cancelada.
arch.install.dep_not_found.title=Dependência não encontrada arch.install.dep_not_found.title=Dependência não encontrada
@@ -207,7 +207,6 @@ arch.install.optdep.error=Não foi possível instalar os pacotes opcionais: {}
arch.install.optdeps.request.body={} foi instalado com sucesso ! Existem alguns pacotes opcionais associados que você talvez queira instalar arch.install.optdeps.request.body={} foi instalado com sucesso ! Existem alguns pacotes opcionais associados que você talvez queira instalar
arch.install.optdeps.request.help=Marque os desejados arch.install.optdeps.request.help=Marque os desejados
arch.install.optdeps.request.title=Dependências opcionais arch.install.optdeps.request.title=Dependências opcionais
arch.install.repo_pkg.error.aur_deps=Não é possível instalar um pacote do AUR como dependência de um pacote de repositório
arch.installing.package=Instalando o pacote {} arch.installing.package=Instalando o pacote {}
arch.checking_unnecessary_deps=Verificando se há pacotes não mais necessários arch.checking_unnecessary_deps=Verificando se há pacotes não mais necessários
arch.makepkg.optimizing=Otimizando a compilação arch.makepkg.optimizing=Otimizando a compilação

View File

@@ -195,7 +195,7 @@ arch.install.aur.unknown_key.body=Для продолжения установк
arch.install.aur.unknown_key.title=Требуется открытый ключ arch.install.aur.unknown_key.title=Требуется открытый ключ
arch.install.conflict.popup.body=Приложения {} находятся в конфликте. Вы должны удалить одно, чтобы установить другоое. Продолжить ? arch.install.conflict.popup.body=Приложения {} находятся в конфликте. Вы должны удалить одно, чтобы установить другоое. Продолжить ?
arch.install.conflict.popup.title=Обнаружен конфликт arch.install.conflict.popup.title=Обнаружен конфликт
arch.install.dep_not_found.body.l1=Требуемая зависимость {} не была найдена ни в AUR, ни в зеркалах по умолчанию. arch.install.dep_not_found.body.l1=Требуемая зависимость {dep}{source} не была найдена ни в AUR, ни в зеркалах по умолчанию.
arch.install.dep_not_found.body.l2=It might be a package database synchronization problem. arch.install.dep_not_found.body.l2=It might be a package database synchronization problem.
arch.install.dep_not_found.body.l3=Operation cancelled. arch.install.dep_not_found.body.l3=Operation cancelled.
arch.install.dep_not_found.title=Зависимость не найдена arch.install.dep_not_found.title=Зависимость не найдена
@@ -208,7 +208,6 @@ arch.install.optdep.error=Could not install the optional packages: {}
arch.install.optdeps.request.body={} успешно установлен ! Есть некоторые дополнительные связанные пакеты, которые вы можете установить arch.install.optdeps.request.body={} успешно установлен ! Есть некоторые дополнительные связанные пакеты, которые вы можете установить
arch.install.optdeps.request.help=Отметьте те, которые вы хотите установить arch.install.optdeps.request.help=Отметьте те, которые вы хотите установить
arch.install.optdeps.request.title=Необязательные зависимости arch.install.optdeps.request.title=Необязательные зависимости
arch.install.repo_pkg.error.aur_deps=It is not possible to install an AUR package as dependency of a repository package
arch.installing.package=Установка пакета {} arch.installing.package=Установка пакета {}
arch.checking_unnecessary_deps=Checking if there are packages no longer needed arch.checking_unnecessary_deps=Checking if there are packages no longer needed
arch.makepkg.optimizing=Оптимизация компиляции arch.makepkg.optimizing=Оптимизация компиляции

View File

@@ -195,7 +195,7 @@ arch.install.aur.unknown_key.body=Yüklemeye devam etmek için {} aşağıdaki o
arch.install.aur.unknown_key.title=Ortak anahtar gerekli arch.install.aur.unknown_key.title=Ortak anahtar gerekli
arch.install.conflict.popup.body={} Uygulamaları çakışıyor. Diğerini kurmak için birini kaldırmalısınız. Devam et ? arch.install.conflict.popup.body={} Uygulamaları çakışıyor. Diğerini kurmak için birini kaldırmalısınız. Devam et ?
arch.install.conflict.popup.title=Çakışma tespit edildi arch.install.conflict.popup.title=Çakışma tespit edildi
arch.install.dep_not_found.body.l1=Gerekli bağımlılık {} ne AUR ne de resmi depolarda bulunamadı. arch.install.dep_not_found.body.l1=Gerekli bağımlılık {dep}{source} ne AUR ne de resmi depolarda bulunamadı.
arch.install.dep_not_found.body.l2=Bir paket veritabanı senkronizasyon sorunu olabilir. arch.install.dep_not_found.body.l2=Bir paket veritabanı senkronizasyon sorunu olabilir.
arch.install.dep_not_found.body.l3=Operation cancelled. arch.install.dep_not_found.body.l3=Operation cancelled.
arch.install.dep_not_found.title=Bağımlılık bulunamadı arch.install.dep_not_found.title=Bağımlılık bulunamadı
@@ -208,7 +208,6 @@ arch.install.optdep.error=Tercihe bağlı paketler yüklenemedi: {}
arch.install.optdeps.request.body={} başarıyla yüklendi! Yüklemek isteyebileceğiniz bazı tercihe bağlı bağımlılıklar vardır arch.install.optdeps.request.body={} başarıyla yüklendi! Yüklemek isteyebileceğiniz bazı tercihe bağlı bağımlılıklar vardır
arch.install.optdeps.request.help=İstediklerinizi kontrol edin arch.install.optdeps.request.help=İstediklerinizi kontrol edin
arch.install.optdeps.request.title=İsteğe bağlı bağımlılıklar arch.install.optdeps.request.title=İsteğe bağlı bağımlılıklar
arch.install.repo_pkg.error.aur_deps=Depodaki paketin bağımlılığı olarak bir AUR paketi kurmak mümkün değildir
arch.installing.package={} Paketi yükleniyor arch.installing.package={} Paketi yükleniyor
arch.checking_unnecessary_deps=Artık gerekli olmayan paketler olup olmadığını kontrol et arch.checking_unnecessary_deps=Artık gerekli olmayan paketler olup olmadığını kontrol et
arch.makepkg.optimizing=Derlemeyi optimize et arch.makepkg.optimizing=Derlemeyi optimize et