[improvement][aur] retrieving and displaying all transitive required dependencies

This commit is contained in:
Vinícius Moreira
2019-12-04 12:47:10 -03:00
parent 2aec03586a
commit e01249f49c
23 changed files with 428 additions and 81 deletions

View File

@@ -4,6 +4,8 @@ from typing import Set, List
from bauh.api.http import HttpClient
import urllib.parse
from bauh.gems.arch.exceptions import PackageNotFoundException
URL_INFO = 'https://aur.archlinux.org/rpc/?v=5&type=info&'
URL_SRC_INFO = 'https://aur.archlinux.org/cgit/aur.git/plain/.SRCINFO?h='
URL_SEARCH = 'https://aur.archlinux.org/rpc/?v=5&type=search&arg='
@@ -46,5 +48,18 @@ class AURClient:
return info
def get_all_dependencies(self, name: str) -> Set[str]:
deps = set()
info = self.get_src_info(name)
if not info:
raise PackageNotFoundException(name)
for attr in ('makedepends', 'depends', 'checkdepends'):
if info.get(attr):
deps.update(info[attr])
return deps
def _map_names_as_queries(self, names) -> str:
return '&'.join(['arg[{}]={}'.format(i, urllib.parse.quote(n)) for i, n in enumerate(names)])

View File

@@ -1,4 +1,4 @@
from typing import Set
from typing import Set, List, Tuple
from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.view import MultipleSelectComponent, InputOption
@@ -25,7 +25,7 @@ def request_optional_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatch
default_options=None)
install = watcher.request_confirmation(title=i18n['arch.install.optdeps.request.title'],
body='<p>{}.</p><p>{}.</p>'.format(i18n['arch.install.optdeps.request.body'].format(bold(pkgname)), i18n['arch.install.optdeps.request.help']),
body='<p>{}.</p><p>{}:</p>'.format(i18n['arch.install.optdeps.request.body'].format(bold(pkgname)), i18n['arch.install.optdeps.request.help']),
components=[view_opts],
confirmation_label=i18n['install'].capitalize(),
deny_label=i18n['do_not.install'].capitalize())
@@ -34,14 +34,14 @@ def request_optional_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatch
return {o.value for o in view_opts.values}
def request_install_missing_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatcher, i18n: I18n) -> bool:
msg = '<p>{}</p>'.format(i18n['arch.missing_deps.body'].format(bold(pkgname)))
def request_install_missing_deps(pkgname: str, deps: List[Tuple[str,str]], watcher: ProcessWatcher, i18n: I18n) -> bool:
msg = '<p>{}</p>'.format(i18n['arch.missing_deps.body'].format(name=bold(pkgname), deps=bold(len(deps))))
opts = []
for p, m in pkg_mirrors.items():
op = InputOption('{} ( {}: {} )'.format(p, i18n['repository'], m.upper()), p)
for dep in deps:
op = InputOption('{} ( {}: {} )'.format(dep[0], i18n['repository'], dep[1].upper()), dep[0])
op.read_only = True
op.icon_path = _get_mirror_icon(m)
op.icon_path = _get_mirror_icon(dep[1])
opts.append(op)
comp = MultipleSelectComponent(label='', options=opts, default_options=set(opts))

View File

@@ -6,7 +6,7 @@ import subprocess
import time
from pathlib import Path
from threading import Thread
from typing import List, Set, Type
from typing import List, Set, Type, Tuple
import requests
@@ -22,6 +22,7 @@ from bauh.commons.system import SystemProcess, ProcessHandler, new_subprocess, r
from bauh.gems.arch import BUILD_DIR, aur, pacman, makepkg, pkgbuild, message, confirmation, disk, git, suggestions, \
gpg, URL_CATEGORIES_FILE, CATEGORIES_CACHE_DIR, CATEGORIES_FILE_PATH
from bauh.gems.arch.aur import AURClient
from bauh.gems.arch.depedencies import DependenciesAnalyser
from bauh.gems.arch.mapper import ArchDataMapper
from bauh.gems.arch.model import ArchPackage
from bauh.gems.arch.worker import AURIndexUpdater, ArchDiskCacheUpdater, ArchCompilationOptimizer
@@ -62,6 +63,7 @@ class ArchManager(SoftwareManager):
self.categories_mapper = CategoriesDownloader('AUR', context.http_client, context.logger, self, self.context.disk_cache,
URL_CATEGORIES_FILE, CATEGORIES_CACHE_DIR, CATEGORIES_FILE_PATH)
self.categories = {}
self.deps_analyser = DependenciesAnalyser(self.aur_client)
def _upgrade_search_result(self, apidata: dict, installed_pkgs: dict, downgrade_enabled: bool, res: SearchResult, disk_loader: DiskCacheLoader):
app = self.mapper.map_api_data(apidata, installed_pkgs['not_signed'], self.categories)
@@ -219,7 +221,7 @@ class ArchManager(SoftwareManager):
break
watcher.change_substatus(self.i18n['arch.downgrade.install_older'])
return self._make_pkg(pkg.name, pkg.maintainer, root_password, handler, app_build_dir, clone_path, dependency=False, skip_optdeps=True)
return self._build(pkg.name, pkg.maintainer, root_password, handler, app_build_dir, clone_path, dependency=False, skip_optdeps=True)
else:
watcher.show_message(title=self.i18n['arch.downgrade.error'],
body=self.i18n['arch.downgrade.impossible'].format(pkg.name),
@@ -308,11 +310,17 @@ class ArchManager(SoftwareManager):
srcinfo = self.aur_client.get_src_info(pkg.name)
if srcinfo:
if srcinfo.get('makedepends'):
info['12_makedepends'] = srcinfo['makedepends']
if srcinfo.get('depends'):
info['11_dependson'] = srcinfo['depends']
info['13_dependson'] = srcinfo['depends']
if srcinfo.get('optdepends'):
info['12_optdepends'] = srcinfo['optdepends']
info['14_optdepends'] = srcinfo['optdepends']
if srcinfo.get('checkdepends'):
info['15_checkdepends'] = srcinfo['checkdepends']
if pkg.pkgbuild:
info['00_pkg_build'] = pkg.pkgbuild
@@ -355,34 +363,34 @@ class ArchManager(SoftwareManager):
if os.path.exists(temp_dir):
shutil.rmtree(temp_dir)
def _install_deps(self, pkg_mirrors: dict, root_password: str, handler: ProcessHandler, change_progress: bool = False) -> str:
def _install_deps(self, deps: List[Tuple[str, str]], root_password: str, handler: ProcessHandler, change_progress: bool = False) -> str:
"""
:param pkg_mirrors:
:param pkgs_repos:
:param root_password:
:param handler:
:return: not installed dependency
"""
progress_increment = int(100 / len(pkg_mirrors))
progress_increment = int(100 / len(deps))
progress = 0
self._update_progress(handler.watcher, 1, change_progress)
for pkgname, mirror in pkg_mirrors.items():
handler.watcher.change_substatus(self.i18n['arch.install.dependency.install'].format(bold('{} ()'.format(pkgname, mirror))))
if mirror == 'aur':
installed = self._install_from_aur(pkgname=pkgname, maintainer=None, root_password=root_password, handler=handler, dependency=True, change_progress=False)
for dep in deps:
handler.watcher.change_substatus(self.i18n['arch.install.dependency.install'].format(bold('{} ()'.format(dep[0], dep[1]))))
if dep[1] == 'aur':
installed = self._install_from_aur(pkgname=dep[0], maintainer=None, root_password=root_password, handler=handler, dependency=True, change_progress=False)
else:
installed = self._install(pkgname=pkgname, maintainer=None, root_password=root_password, handler=handler, install_file=None, mirror=mirror, change_progress=False)
installed = self._install(pkgname=dep[0], maintainer=None, root_password=root_password, handler=handler, install_file=None, mirror=dep[1], change_progress=False)
if not installed:
return pkgname
return dep[0]
progress += progress_increment
self._update_progress(handler.watcher, progress, change_progress)
self._update_progress(handler.watcher, 100, change_progress)
def _map_mirrors(self, pkgnames: Set[str]) -> dict:
pkg_mirrors = pacman.get_mirrors(pkgnames) # getting mirrors set
def _map_repos(self, pkgnames: Set[str]) -> dict:
pkg_mirrors = pacman.get_repositories(pkgnames) # getting mirrors set
if len(pkgnames) != len(pkg_mirrors): # checking if any dep not found in the distro mirrors are from AUR
nomirrors = {p for p in pkgnames if p not in pkg_mirrors}
@@ -423,12 +431,14 @@ class ArchManager(SoftwareManager):
return True
def _make_pkg(self, pkgname: str, maintainer: str, root_password: str, handler: ProcessHandler, build_dir: str, project_dir: str, dependency: bool, skip_optdeps: bool = False, change_progress: bool = True) -> bool:
def _build(self, pkgname: str, maintainer: str, root_password: str, handler: ProcessHandler, build_dir: str, project_dir: str, dependency: bool, skip_optdeps: bool = False, change_progress: bool = True) -> bool:
self._pre_download_source(pkgname, project_dir, handler.watcher)
self._update_progress(handler.watcher, 50, change_progress)
if not self._check_deps(pkgname, root_password, handler, project_dir):
check_subdeps = bool(int(os.getenv('BAUH_ARCH_CHECK_SUBDEPS', 1)))
if not self._handle_deps_and_keys(pkgname, root_password, handler, project_dir, check_subdeps=check_subdeps):
return False
# building main package
@@ -458,35 +468,74 @@ class ArchManager(SoftwareManager):
return False
def _check_deps(self, pkgname: str, root_password: str, handler: ProcessHandler, pkgdir: str) -> bool:
def _map_missing_deps(self, deps: List[str], watcher: ProcessWatcher, check_subdeps: bool = True) -> List[Tuple[str, str]]:
depnames = {RE_SPLIT_VERSION.split(dep)[0] for dep in deps}
dep_repos = self._map_repos(depnames)
if len(depnames) != len(dep_repos): # checking if a dependency could not be found in any mirror
for dep in depnames:
if dep not in dep_repos:
message.show_dep_not_found(dep, self.i18n, watcher)
return
sorted_deps = [] # it will hold the proper order to install the missing dependencies
repo_deps, aur_deps = set(), set()
for dep, repo in dep_repos.items():
if repo == 'aur':
aur_deps.add(dep)
else:
repo_deps.add(dep)
if check_subdeps:
for deps in ((repo_deps, 'repo'), (aur_deps, 'aur')):
if deps[0]:
missing_subdeps = self.deps_analyser.get_missing_dependencies_from(deps[0], deps[1])
if missing_subdeps:
for dep in missing_subdeps:
if not dep[1]:
message.show_dep_not_found(dep[0], self.i18n, watcher)
return
for dep in missing_subdeps:
sorted_deps.append(dep)
for dep, repo in dep_repos.items():
if repo != 'aur':
sorted_deps.append((dep, repo))
for dep in aur_deps:
sorted_deps.append((dep, 'aur'))
return sorted_deps
def _handle_deps_and_keys(self, pkgname: str, root_password: str, handler: ProcessHandler, pkgdir: str, check_subdeps: bool = True) -> bool:
handler.watcher.change_substatus(self.i18n['arch.checking.deps'].format(bold(pkgname)))
check_res = makepkg.check(pkgdir, handler)
if check_res:
if check_res.get('missing_deps'):
depnames = {RE_SPLIT_VERSION.split(dep)[0] for dep in check_res['missing_deps']}
dep_mirrors = self._map_mirrors(depnames)
sorted_deps = self._map_missing_deps(check_res['missing_deps'], handler.watcher, check_subdeps=check_subdeps)
if len(depnames) != len(dep_mirrors): # checking if a dependency could not be found in any mirror
for dep in depnames:
if dep not in dep_mirrors:
message.show_dep_not_found(dep, self.i18n, handler.watcher)
return False
if sorted_deps is None:
return False
handler.watcher.change_substatus(self.i18n['arch.missing_deps_found'].format(bold(pkgname)))
if not confirmation.request_install_missing_deps(pkgname, dep_mirrors, handler.watcher, self.i18n):
if not confirmation.request_install_missing_deps(pkgname, sorted_deps, handler.watcher, self.i18n):
handler.watcher.print(self.i18n['action.cancelled'])
return False
dep_not_installed = self._install_deps(dep_mirrors, root_password, handler, change_progress=False)
dep_not_installed = self._install_deps(sorted_deps, root_password, handler, change_progress=False)
if dep_not_installed:
message.show_dep_not_installed(handler.watcher, pkgname, dep_not_installed, self.i18n)
return False
# it is necessary to re-check because missing PGP keys are only notified when there are none missing
return self._check_deps(pkgname, root_password, handler, pkgdir)
return self._handle_deps_and_keys(pkgname, root_password, handler, pkgdir, check_subdeps=False)
if check_res.get('gpg_key'):
if handler.watcher.request_confirmation(title=self.i18n['arch.aur.install.unknown_key.title'],
@@ -520,7 +569,7 @@ class ArchManager(SoftwareManager):
if not to_install:
return True
pkg_mirrors = self._map_mirrors(to_install)
pkg_mirrors = self._map_repos(to_install)
if pkg_mirrors:
final_optdeps = {dep: {'desc': odeps.get(dep), 'mirror': pkg_mirrors.get(dep)} for dep, mirror in pkg_mirrors.items()}
@@ -642,15 +691,15 @@ class ArchManager(SoftwareManager):
if uncompress:
uncompress_dir = '{}/{}'.format(app_build_dir, pkgname)
return self._make_pkg(pkgname=pkgname,
maintainer=maintainer,
root_password=root_password,
handler=handler,
build_dir=app_build_dir,
project_dir=uncompress_dir,
dependency=dependency,
skip_optdeps=skip_optdeps,
change_progress=change_progress)
return self._build(pkgname=pkgname,
maintainer=maintainer,
root_password=root_password,
handler=handler,
build_dir=app_build_dir,
project_dir=uncompress_dir,
dependency=dependency,
skip_optdeps=skip_optdeps,
change_progress=change_progress)
finally:
if os.path.exists(app_build_dir):
handler.handle(SystemProcess(new_subprocess(['rm', '-rf', app_build_dir])))

View File

@@ -0,0 +1,95 @@
from threading import Thread
from typing import Set, List, Tuple
from bauh.gems.arch import pacman
from bauh.gems.arch.aur import AURClient
class DependenciesAnalyser:
def __init__(self, aur_client: AURClient):
self.aur_client = aur_client
def _fill_mirror(self, name: str, output: List[Tuple[str, str]]):
mirror = pacman.read_repository_from_info(name)
if mirror:
output.append((name, mirror))
return
guess = pacman.guess_repository(name)
if guess:
output.append(guess)
return
aur_info = self.aur_client.get_src_info(name)
if aur_info:
output.append((name, 'aur'))
return
output.append((name, ''))
def get_missing_dependencies(self, names: Set[str], mirror: str = None) -> List[Tuple[str, str]]:
missing_names = pacman.check_missing(names)
if missing_names:
missing_root = []
threads = []
if not mirror:
for name in missing_names:
t = Thread(target=self._fill_mirror, args=(name, missing_root))
t.start()
threads.append(t)
for t in threads:
t.join()
threads.clear()
# checking if there is any unknown dependency:
for dep in missing_root:
if not dep[1]:
return missing_root
else:
for missing in missing_names:
missing_root.append((missing, mirror))
missing_sub = []
for dep in missing_root:
subdeps = self.aur_client.get_all_dependencies(dep[0]) if dep[1] == 'aur' else pacman.read_dependencies(dep[0])
if subdeps:
missing_subdeps = self.get_missing_dependencies(subdeps)
# checking if there is any unknown:
if missing_subdeps:
for subdep in missing_subdeps:
if not subdep[0]:
missing_sub.extend(missing_subdeps)
break
missing_sub.extend(missing_subdeps)
return [*missing_sub, *missing_root]
def get_missing_dependencies_from(self, names: Set[str], mirror: str) -> List[Tuple[str, str]]:
missing = []
for dep in names:
subdeps = self.aur_client.get_all_dependencies(dep) if mirror == 'aur' else pacman.read_dependencies(dep)
if subdeps:
missing_subdeps = self.get_missing_dependencies(subdeps)
if missing_subdeps:
missing.extend(missing_subdeps)
for subdep in missing_subdeps: # checking if there is any unknown:
if not subdep[0]:
return missing
return missing

View File

@@ -0,0 +1,5 @@
class PackageNotFoundException(Exception):
def __init__(self, name: str):
self.name = name

View File

@@ -3,9 +3,11 @@ from threading import Thread
from typing import List, Set, Tuple
from bauh.commons.system import run_cmd, new_subprocess, new_root_subprocess, SystemProcess
from bauh.gems.arch.exceptions import PackageNotFoundException
RE_DEPS = re.compile(r'[\w\-_]+:[\s\w_\-\.]+\s+\[\w+\]')
RE_OPTDEPS = re.compile(r'[\w\._\-]+\s*:')
RE_DEP_NOTFOUND = re.compile(r'error:.+\'(.+)\'')
def is_enabled() -> bool:
@@ -13,7 +15,7 @@ def is_enabled() -> bool:
return res and not res.strip().startswith('which ')
def get_mirror(pkg: str) -> Tuple[str, str]:
def get_configured_repository(pkg: str) -> Tuple[str, str]:
res = run_cmd('pacman -Ss {}'.format(pkg))
if res:
@@ -24,7 +26,7 @@ def get_mirror(pkg: str) -> Tuple[str, str]:
return data[1].split(' ')[0], data[0]
def get_mirrors(pkgs: Set[str]) -> dict:
def get_repositories(pkgs: Set[str]) -> dict:
pkgre = '|'.join(pkgs).replace('+', r'\+').replace('.', r'\.')
searchres = new_subprocess(['pacman', '-Ss', pkgre]).stdout
@@ -41,7 +43,7 @@ def get_mirrors(pkgs: Set[str]) -> dict:
if not_found: # if there are some packages not found, try to find via the single method:
for dep in not_found:
mirror_data = get_mirror(dep)
mirror_data = get_configured_repository(dep)
if mirror_data:
mirrors[mirror_data[0]] = mirror_data[1]
@@ -49,7 +51,7 @@ def get_mirrors(pkgs: Set[str]) -> dict:
return mirrors
def is_available_from_mirrors(pkg_name: str) -> bool:
def is_available_in_repositories(pkg_name: str) -> bool:
return bool(run_cmd('pacman -Ss ' + pkg_name))
@@ -236,3 +238,141 @@ def list_ignored_packages(config_path: str = '/etc/pacman.conf') -> Set[str]:
pacman_conf.terminate()
grep.terminate()
return ignored
def check_missing(names: Set[str]) -> Set[str]:
installed = new_subprocess(['pacman', '-Qq', *names])
not_installed = set()
for o in installed.stderr:
if o:
err_line = o.decode()
if err_line:
not_found = RE_DEP_NOTFOUND.findall(err_line)
if not_found:
not_installed.update(not_found)
return not_installed
def read_repository_from_info(name: str) -> str:
info = new_subprocess(['pacman', '-Si', name])
not_found = False
for o in info.stderr:
if o:
err_line = o.decode()
if RE_DEP_NOTFOUND.findall(err_line):
not_found = True
if not_found:
return
mirror = None
for o in new_subprocess(['grep', '-Po', "Repository\s+:\s+\K.+"], stdin=info.stdout).stdout:
if o:
line = o.decode().strip()
if line:
mirror = line
return mirror
def guess_repository(name: str) -> Tuple[str, str]:
res = run_cmd('pacman -Ss {}'.format(name.split('=')[0] if '=' in name else name))
if res:
lines = res.split('\n')
if lines:
data = lines[0].split('/')
return data[1].split(' ')[0], data[0]
def read_dependencies(name: str) -> Set[str]:
dep_info = new_subprocess(['pacman', '-Si', name])
not_found = False
for o in dep_info.stderr:
if o:
err_line = o.decode()
if err_line:
if RE_DEP_NOTFOUND.findall(err_line):
not_found = True
if not_found:
raise PackageNotFoundException(name)
depends_on = set()
for out in new_subprocess(['grep', '-Po', 'Depends\s+On\s+:\s\K(.+)'], stdin=dep_info.stdout).stdout:
if out:
line = out.decode().strip()
if line:
depends_on.update(line.split(' '))
return depends_on
"""
def check_uninstalled(names: List[str], stop_recursion_if_no_mirror: bool = True) -> Dict[str, str]:
missing = {}
installed = new_subprocess(['pacman', '-Qq', *names])
not_installed = []
for o in installed.stderr:
if o:
err_line = o.decode()
if err_line:
not_found = RE_DEP_NOTFOUND.findall(err_line)
if not_found:
not_installed.extend(not_found)
if not_installed:
missing_mirrors = False
for dep in not_installed:
pkgname = dep
not_installed_info = new_subprocess(['pacman', '-Si', dep])
mirror = None
for o in new_subprocess(['grep', '-Po', "Repository\s+:\s+\K.+"], stdin=not_installed_info.stdout).stdout:
if o:
line = o.decode().strip()
if line:
mirror = line
if not mirror:
mirror_data = get_configured_repository(dep)
if mirror_data:
pkgname = mirror_data[0]
mirror = mirror_data[1]
missing[pkgname] = mirror
if mirror is None:
missing_mirrors = True
if stop_recursion_if_no_mirror and missing_mirrors:
return missing
subdeps_mirrors = dict()
for pkg in missing:
subdeps_mirrors.update(check_uninstalled(pkg))
missing.update(subdeps_mirrors, stop_recursion_if_no_mirror=stop_recursion_if_no_mirror)
return missing
"""

View File

@@ -36,7 +36,7 @@ aur.info.conflicts with=té un conflicte amb
arch.install.conflict.popup.title=Sha detectat un conflicte
arch.install.conflict.popup.body=Les aplicacions {} estan en conflicte. Heu de desinstal·lar una per a instal·lar laltra. Voleu continuar?
arch.missing_deps.title=Dependències mancants
arch.missing_deps.body=Shan dinstal·lar les dependències següents abans de continuar amb la instal·lació de {}
arch.missing_deps.body=Shan dinstal·lar les {deps} dependències següents abans de continuar amb la instal·lació de {name}
arch.downgrade.error=Error
arch.downgrade.impossible=No sha pogut revertir la versió de {}
aur.history.1_version=versió
@@ -69,8 +69,10 @@ aur.info.09_last_modified=darrera modificació
aur.info.10_url=url de baixada
aur.info.11_pkg_build_url=url pkgbuild
aur.info.13_pkg_build=pkgbuild
aur.info.11_dependson=dependències
aur.info.12_optdepends=dependències opcionals
aur.info.12_makedepends=dependències de compilació
aur.info.13_dependson=dependències dinstal·lació
aur.info.14_optdepends=dependències opcionals
aur.info.15_checkdepends=dependències de verificació
aur.info.14_installed_files=Fitxers instal·lats
arch.install.dep_not_found.title=No sha trobat la dependència
arch.install.dep_not_found.body=No sha trobat la dependència requerida {} a lAUR ni als servidors rèplica per defecte. Sha cancel·lat la instal·lació.

View File

@@ -4,7 +4,7 @@ gem.aur.install.warning=AUR Pakete werden von einer unabhängigen Nutzergemeinsc
arch.install.conflict.popup.title=Konflikt entdeckt
arch.install.conflict.popup.body=Die Anwendungen {} können nicht gleichzeitig installiert sein. Du musst eine deinstallieren um die andere zu installieren. Fortfahren?
arch.missing_deps.title=Fehlende Abhängigkeiten
arch.missing_deps.body=Die folgenden Abhängigkeiten müssten installiert sein, bevor mit der {} Installation fortgefahren werden kann
arch.missing_deps.body=Die folgenden {deps} Abhängigkeiten müssten installiert sein, bevor mit der {name} Installation fortgefahren werden kann
arch.downgrade.error=Fehler
arch.downgrade.impossible=Downgrade von {} ist nicht möglich
aur.history.1_version=Version
@@ -37,8 +37,10 @@ aur.info.09_last_modified=Zuletzt verändert
aur.info.10_url=url zum Herunterladen
aur.info.11_pkg_build_url=url pkgbuild
aur.info.13_pkg_build=pkgbuild
aur.info.11_dependson=Abhängigkeiten
aur.info.12_optdepends=optionale Abhängigkeiten
aur.info.12_makedepends=Kompilierungsabhängigkeiten
aur.info.13_dependson=Installationsabhängigkeiten
aur.info.14_optdepends=optionale Abhängigkeiten
aur.info.15_checkdepends=Überprüfungsabhängigkeiten
aur.info.14_installed_files=Installationsdateien
arch.install.dep_not_found.title=Abhängigkeit nicht gefunden
arch.install.dep_not_found.body=Nötige Abhängigkeit {} wurde weder im AUR noch in den standard Spiegelservern gefunden. Installation abgebrochen

View File

@@ -4,7 +4,7 @@ gem.aur.install.warning=AUR packages are maintained by an independent user commu
arch.install.conflict.popup.title=Conflict detected
arch.install.conflict.popup.body=The applications {} are in conflict. You must uninstall one to install the other. Continue ?
arch.missing_deps.title=Missing dependencies
arch.missing_deps.body=The following dependencies must be installed before the {} installation continues
arch.missing_deps.body=The following {deps} dependencies must be installed before the {name} installation continues
arch.downgrade.error=Error
arch.downgrade.impossible=It is not possible to downgrade {}
aur.history.1_version=version
@@ -37,8 +37,10 @@ aur.info.09_last_modified=last modified
aur.info.10_url=url download
aur.info.11_pkg_build_url=url pkgbuild
aur.info.13_pkg_build=pkgbuild
aur.info.11_dependson=dependencies
aur.info.12_optdepends=optional dependencies
aur.info.12_makedepends=compilation dependencies
aur.info.13_dependson=installation dependencies
aur.info.14_optdepends=optional dependencies
aur.info.15_checkdepends=checking dependencies
aur.info.14_installed_files=Installed files
arch.install.dep_not_found.title=Dependency not found
arch.install.dep_not_found.body=Required dependency {} was not found in AUR nor in default mirrors. Installation cancelled.

View File

@@ -36,7 +36,7 @@ aur.info.conflicts with=conflicta
arch.install.conflict.popup.title=Conflicto detectado
arch.install.conflict.popup.body=Los aplicativos {} estan en conflicto. Debe desinstalar uno para instalar el otro. ¿Continuar?
arch.missing_deps.title=Dependencias faltantes
arch.missing_deps.body=Deben instalarse las siguientes dependencias antes de continuar la instalación de {}
arch.missing_deps.body=Deben instalarse las siguientes {deps} dependencias antes de continuar la instalación de {name}
arch.downgrade.error=Error
arch.downgrade.impossible=No es posible revertir la versión de {}
aur.history.1_version=versión
@@ -69,8 +69,10 @@ aur.info.09_last_modified=última modificación
aur.info.10_url=url download
aur.info.11_pkg_build_url=url pkgbuild
aur.info.13_pkg_build=pkgbuild
aur.info.11_dependson=dependencias
aur.info.12_optdepends=dependencias opcionales
aur.info.12_makedepends=dependencias para compilacion
aur.info.13_dependson=dependencias para instalación
aur.info.14_optdepends=dependencias opcionales
aur.info.15_checkdepends=dependencias para verificación
aur.info.14_installed_files=Archivos instalados
arch.install.dep_not_found.title=Dependencia no encontrada
arch.install.dep_not_found.body=No se encontró la dependencia requerida {} en AUR ni en los espejos predeterminados. Instalación cancelada.

View File

@@ -4,7 +4,7 @@ gem.aur.install.warning=I pacchetti AUR sono gestiti da una comunità di utenti
arch.install.conflict.popup.title=Conflitto rilevato
arch.install.conflict.popup.body=Le applicazioni {} sono in conflitto. È necessario disinstallarne una per installare l'altra. Continua ?
arch.missing_deps.title=Dipendenze mancanti
arch.missing_deps.body=Le seguenti dipendenze devono essere installate prima che l'installazione di {} continui
arch.missing_deps.body=Le seguenti {deps} dipendenze devono essere installate prima che l'installazione di {name} continui
arch.downgrade.error=Errore
arch.downgrade.impossible=Non è possibile effettuare il downgrade {}
aur.history.1_version=versione
@@ -37,8 +37,10 @@ aur.info.09_last_modified=ultima modifica
aur.info.10_url=url di download
aur.info.11_pkg_build_url=url pkgbuild
aur.info.13_pkg_build=pkgbuild
aur.info.11_dependson=dipendenze
aur.info.12_optdepends=dipendenze opzionali
aur.info.12_makedepends=dipendenze di compilazione
aur.info.13_dependson=dipendenze di installazione
aur.info.14_optdepends=dipendenze opzionali
aur.info.15_checkdepends=dipendenze di verifica
aur.info.14_installed_files=File installati
arch.install.dep_not_found.title=Dipendenza non trovata
arch.install.dep_not_found.body=La dipendenza richiesta {} non è stata trovata in AUR né nei mirror predefiniti. Installazione annullata.

View File

@@ -36,7 +36,7 @@ aur.info.conflicts with=conflita
arch.install.conflict.popup.title=Conflito detectado
arch.install.conflict.popup.body=Os aplicativos {} estão em conflito. Você precisa desinstalar um para instalar o outro. Continuar ?
arch.missing_deps.title=Dependências ausentes
arch.missing_deps.body=As seguintes dependências devem ser instaladas antes de continuar com a instalação de {}
arch.missing_deps.body=As seguintes {deps} dependências devem ser instaladas antes de continuar com a instalação de {name}
arch.downgrade.error=Erro
arch.downgrade.impossible=Não é possível reverter a versão de {}
aur.history.1_version=versão
@@ -69,8 +69,10 @@ aur.info.09_last_modified=última modificação
aur.info.10_url=url download
aur.info.11_pkg_build_url=url pkgbuild
aur.info.13_pkg_build=pkgbuild
aur.info.11_dependson=dependências
aur.info.12_optdepends=dependências opcionais
aur.info.12_makedepends=dependências para compilação
aur.info.13_dependson=dependências para instalação
aur.info.14_optdepends=dependências opcionais
aur.info.15_checkdepends=dependências para verificação
aur.info.14_installed_files=Arquivos instalados
arch.install.dep_not_found.title=Dependência não encontrada
arch.install.dep_not_found.body=A dependência {} não foi encontrado no AUR nem nos espelhos padrões. Instalação cancelada.

View File

@@ -161,8 +161,11 @@ class SnapManager(SoftwareManager):
if channels:
opts = [InputOption(label=c[0], value=c[1]) for c in channels]
channel_select = SingleSelectComponent(type_=SelectViewType.RADIO, label='', options=opts, default_option=opts[0])
body = '<p>{}.</p>'.format(self.i18n['snap.install.available_channels.message'].format(bold(self.i18n['stable']), bold(pkg.name)))
body += '<p>{}:</p>'.format(self.i18n['snap.install.available_channels.help'])
if watcher.request_confirmation(title=self.i18n['snap.install.available_channels.title'],
body=self.i18n['snap.install.available_channels.body'].format(bold(self.i18n['stable']), bold(pkg.name)) + ':',
body=body,
components=[channel_select],
confirmation_label=self.i18n['continue'],
deny_label=self.i18n['cancel']):

View File

@@ -15,4 +15,5 @@ snap.notifications.api.unavailable=Sembla que lAPI de {} no està disponible
snap.action.refresh.status=Sestà actualitzant
snap.action.refresh.label=Actualitza
snap.install.available_channels.title=Canals disponibles
snap.install.available_channels.body=No hi ha un canal {} (stable) disponible per a {}. Però més avall nhi ha els següents (seleccioneu-ne un si voleu continuar)
snap.install.available_channels.message=No hi ha un canal {} (stable) disponible per a {}. Però més avall nhi ha els següents
snap.install.available_channels.help=Seleccioneu-ne un si voleu continuar

View File

@@ -5,7 +5,8 @@ snap.notifications.api.unavailable=Es scheint als ob die {} API aktuell nicht ve
snap.action.refresh.status=Erneuern
snap.action.refresh.label=Erneuern
snap.install.available_channels.title=Verfügbare Channels
snap.install.available_channels.body=Es ist kein {} Channel verfügbar für {}. Es gibt jedoch folgende (wähle einen aus um fortzufahren)
snap.install.available_channels.message=Es ist kein {} Channel verfügbar für {}. Es gibt jedoch folgende
snap.install.available_channels.help=Wähle einen aus um fortzufahren
snap.info.commands=Kommandos
snap.info.contact=Kontakt
snap.info.description=Beschreibung

View File

@@ -5,7 +5,8 @@ snap.notifications.api.unavailable=It seems the {} API is unavailable at the mom
snap.action.refresh.status=Refreshing
snap.action.refresh.label=Refresh
snap.install.available_channels.title=Available channels
snap.install.available_channels.body=There is no {} channel available for {}. But there are these below ( select one if you want to continue )
snap.install.available_channels.message=There is no {} channel available for {}. But there are these below
snap.install.available_channels.help=Select one if you want to continue
snap.info.commands=commands
snap.info.contact=contact
snap.info.description=description

View File

@@ -15,4 +15,5 @@ snap.notifications.api.unavailable=Parece que la API de {} no está disponible e
snap.action.refresh.status=Actualizando
snap.action.refresh.label=Actualizar
snap.install.available_channels.title=Canales disponibles
snap.install.available_channels.body=No hay un canal {} ( stable ) disponible para {}. Pero hay estos otros abajo ( seleccione uno si desea continuar )
snap.install.available_channels.message=No hay un canal {} ( stable ) disponible para {}. Pero hay estos otros abajo
snap.install.available_channels.help=Seleccione uno si desea continuar

View File

@@ -5,4 +5,5 @@ snap.notifications.api.unavailable=Sembra che l'API {} non sia al momento dispon
snap.action.refresh.status=Ripristinare
snap.action.refresh.label=Ripristina
snap.install.available_channels.title=Canali disponibili
snap.install.available_channels.body=Non esiste un {} canale disponibile per {}. Ma ci sono questi sotto (selezionane uno se vuoi continuare)
snap.install.available_channels.message=Non esiste un {} canale disponibile per {}. Ma ci sono questi sotto
snap.install.available_channels.help=Selezionane uno se vuoi continuare

View File

@@ -15,4 +15,5 @@ snap.notifications.api.unavailable=Parece que a API de {} está indisponível no
snap.action.refresh.status=Atualizando
snap.action.refresh.label=Atualizar
snap.install.available_channels.title=Canais disponíveis
snap.install.available_channels.body=Não há um canal {} ( stable ) disponível para {}. Porém existem estes outros abaixo ( selecione algum se quiser continuar )
snap.install.available_channels.message=Não há um canal {} ( stable ) disponível para {}. Porém existem estes outros abaixo
snap.install.available_channels.help=Selecione algum se quiser continuar