From ef5210b46831d1af1b16c2075aae62ab51f0fc60 Mon Sep 17 00:00:00 2001 From: Vinicius Moreira Date: Mon, 2 Dec 2019 11:36:05 -0300 Subject: [PATCH 01/13] [fix][aur] not finding some dependencies declared as files instead of the package names --- CHANGELOG.md | 6 ++++++ README.md | 2 +- bauh/__init__.py | 2 +- bauh/gems/arch/confirmation.py | 2 +- bauh/gems/arch/controller.py | 26 ++++++++++++-------------- bauh/gems/arch/pacman.py | 22 +++++++++++++++++++++- bauh/gems/arch/resources/locale/ca | 3 ++- bauh/gems/arch/resources/locale/de | 3 ++- bauh/gems/arch/resources/locale/en | 3 ++- bauh/gems/arch/resources/locale/es | 3 ++- bauh/gems/arch/resources/locale/it | 3 ++- bauh/gems/arch/resources/locale/pt | 3 ++- 12 files changed, 54 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d7145b3..c51e57c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.7.4] 2019-12 +### Fixes +- AUR: + - not finding some dependencies declared as files instead of the package names (e.g: dolphin-emu-git ) + + ## [0.7.3] 2019-11-29 ### Improvements - Not breaking the application when a i18n (translation) key was not found diff --git a/README.md b/README.md index 3f151152..09dadc67 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ will be pre-downloaded faster ( it does **NOT** modify your **pacman** settings b) same as previous, but related to **COMPRESSXZ** definition ( if '--threads=0' is not defined ) Obs: this feature can be disabled through the environment variable **BAUH_ARCH_OPTIMIZE=0** - ( For more information about these optimizations, have a look at [Makepkg](https://wiki.archlinux.org/index.php/Makepkg) + ( For more information about these optimizations, have a look at [Makepkg](https://wiki.archlinux.org/index.php/Makepkg) ) - Arch package memory-indexer running every 20 minutes. This memory index is used when AUR Api cannot handle the amount of results found for a given search. It can be disabled via the environment variable **BAUH_ARCH_AUR_INDEX_UPDATER=0**. - If some of your installed packages are not categorized, send an e-mail to **bauh4linux@gmail.com** informing their names and categories in the following format: ```name=category1[,category2,category3,...]``` diff --git a/bauh/__init__.py b/bauh/__init__.py index 932ff985..d3a4efa3 100644 --- a/bauh/__init__.py +++ b/bauh/__init__.py @@ -1,4 +1,4 @@ -__version__ = '0.7.3' +__version__ = '0.7.4' __app_name__ = 'bauh' import os diff --git a/bauh/gems/arch/confirmation.py b/bauh/gems/arch/confirmation.py index b1526e23..054acdeb 100644 --- a/bauh/gems/arch/confirmation.py +++ b/bauh/gems/arch/confirmation.py @@ -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='

{}

'.format(i18n['arch.install.optdeps.request.body'].format(bold(pkgname)) + ':'), + body='

{}.

{}.

'.format(i18n['arch.install.optdeps.request.body'].format(bold(pkgname)), i18n['arch.install.optdeps.request.help']), components=[view_opts], confirmation_label=i18n['install'], deny_label=i18n['cancel']) diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index e9078613..53e7bfb8 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -355,21 +355,18 @@ def get_history(self, pkg: ArchPackage) -> PackageHistory: if os.path.exists(temp_dir): shutil.rmtree(temp_dir) - def _install_deps(self, deps: Set[str], pkg_mirrors: dict, root_password: str, handler: ProcessHandler, change_progress: bool = False) -> str: + def _install_deps(self, pkg_mirrors: dict, root_password: str, handler: ProcessHandler, change_progress: bool = False) -> str: """ - :param deps: :param pkg_mirrors: :param root_password: :param handler: :return: not installed dependency """ - progress_increment = int(100 / len(deps)) + progress_increment = int(100 / len(pkg_mirrors)) progress = 0 self._update_progress(handler.watcher, 1, change_progress) - for pkgname in deps: - - mirror = pkg_mirrors[pkgname] + 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) @@ -387,7 +384,7 @@ def _install_deps(self, deps: Set[str], pkg_mirrors: dict, root_password: str, h def _map_mirrors(self, pkgnames: Set[str]) -> dict: pkg_mirrors = pacman.get_mirrors(pkgnames) # getting mirrors set - if len(pkgnames) != pkg_mirrors: # checking if any dep not found in the distro mirrors are from AUR + 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} for pkginfo in self.aur_client.get_info(nomirrors): if pkginfo.get('Name') in nomirrors: @@ -470,10 +467,11 @@ def _install_missings_deps_and_keys(self, pkgname: str, root_password: str, hand depnames = {RE_SPLIT_VERSION.split(dep)[0] for dep in check_res['missing_deps']} dep_mirrors = self._map_mirrors(depnames) - for dep in depnames: # cheking if a dependency could not be found in any mirror - if dep not in dep_mirrors: - message.show_dep_not_found(dep, self.i18n, handler.watcher) - return False + if len(depnames) != len(dep_mirrors): # cheking 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 handler.watcher.change_substatus(self.i18n['arch.missing_deps_found'].format(bold(pkgname))) @@ -481,7 +479,7 @@ def _install_missings_deps_and_keys(self, pkgname: str, root_password: str, hand handler.watcher.print(self.i18n['action.cancelled']) return False - dep_not_installed = self._install_deps(depnames, dep_mirrors, root_password, handler, change_progress=False) + dep_not_installed = self._install_deps(dep_mirrors, root_password, handler, change_progress=False) if dep_not_installed: message.show_dep_not_installed(handler.watcher, pkgname, dep_not_installed, self.i18n) @@ -525,14 +523,14 @@ def _install_optdeps(self, pkgname: str, root_password: str, handler: ProcessHan pkg_mirrors = self._map_mirrors(to_install) if pkg_mirrors: - final_optdeps = {dep: {'desc': odeps.get(dep), 'mirror': pkg_mirrors.get(dep)} for dep in to_install if dep in pkg_mirrors} + final_optdeps = {dep: {'desc': odeps.get(dep), 'mirror': pkg_mirrors.get(dep)} for dep, mirror in pkg_mirrors.items()} deps_to_install = confirmation.request_optional_deps(pkgname, final_optdeps, handler.watcher, self.i18n) if not deps_to_install: return True else: - dep_not_installed = self._install_deps(deps_to_install, pkg_mirrors, root_password, handler, change_progress=True) + dep_not_installed = self._install_deps(pkg_mirrors, root_password, handler, change_progress=True) if dep_not_installed: message.show_optdep_not_installed(dep_not_installed, handler.watcher, self.i18n) diff --git a/bauh/gems/arch/pacman.py b/bauh/gems/arch/pacman.py index 9e8e8d4d..11c551da 100644 --- a/bauh/gems/arch/pacman.py +++ b/bauh/gems/arch/pacman.py @@ -1,6 +1,6 @@ import re from threading import Thread -from typing import List, Set +from typing import List, Set, Tuple from bauh.commons.system import run_cmd, new_subprocess, new_root_subprocess, SystemProcess @@ -13,6 +13,17 @@ def is_enabled() -> bool: return res and not res.strip().startswith('which ') +def get_mirror(pkg: str) -> Tuple[str, str]: + res = run_cmd('pacman -Ss {}'.format(pkg)) + + if res: + lines = res.split('\n') + + if lines: + data = lines[0].split('/') + return data[1].split(' ')[0], data[0] + + def get_mirrors(pkgs: Set[str]) -> dict: pkgre = '|'.join(pkgs).replace('+', r'\+').replace('.', r'\.') @@ -26,6 +37,15 @@ def get_mirrors(pkgs: Set[str]) -> dict: if p in match: mirrors[p] = match.split('/')[0] + not_found = {pkg for pkg in pkgs if pkg not in mirrors} + + if not_found: # if there are any not found, try to find via the single method: + for dep in not_found: + mirror_data = get_mirror(dep) + + if mirror_data: + mirrors[mirror_data[0]] = mirror_data[1] + return mirrors diff --git a/bauh/gems/arch/resources/locale/ca b/bauh/gems/arch/resources/locale/ca index 2c408d43..4ccf68ca 100644 --- a/bauh/gems/arch/resources/locale/ca +++ b/bauh/gems/arch/resources/locale/ca @@ -79,7 +79,8 @@ arch.install.dependency.install.error=No s’ha pogut instal·lar el paquet depe arch.uninstall.required_by=No es pot desinstal·lar {} perquè és necessari per al funcionament dels paquets següents arch.uninstall.required_by.advice=Heu de desinstal·lar-los abans de desinstal·lar {} arch.install.optdeps.request.title=Dependències opcionals -arch.install.optdeps.request.body={} s’ha instal·lat correctament. Hi ha paquets opcionals associats que potser voldreu instal·lar (marqueu els que voleu) +arch.install.optdeps.request.body={} s’ha instal·lat correctament. Hi ha paquets opcionals associats que potser voldreu instal·lar +arch.install.optdeps.request.help=Marqueu els que voleu arch.install.optdep.error=No s’ha pogut instal·lar el paquet opcional {} arch.optdeps.checking=S’estan comprovant les dependències opcionals de {} arch.warning.disabled=Sembla que no s’ha instal·lat {}. No podreu gestionar paquets Arch/AUR. diff --git a/bauh/gems/arch/resources/locale/de b/bauh/gems/arch/resources/locale/de index ac71a2a5..5315ead8 100644 --- a/bauh/gems/arch/resources/locale/de +++ b/bauh/gems/arch/resources/locale/de @@ -47,7 +47,8 @@ arch.install.dependency.install.error=Paket {} konnte nicht installiert werden. arch.uninstall.required_by={} konnte nicht deinstalliert werden, da es für die folgenden Pakete benötigt wird. arch.uninstall.required_by.advice=Deinstalliere sie zuerst, bevor du {} deinstalliert arch.install.optdeps.request.title=Optionale Abhängigkeiten -arch.install.optdeps.request.body={} wurde erfolgreich installiert! Es gibt optionale zugehörige Pakete welche du vielleicht auch installieren möchtest (wähle entsprechende aus) +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.optdep.error=Optionales Paket {} konnte nicht installiert werden arch.optdeps.checking={} optionale Abhängigkeiten überprüfen arch.warning.disabled={} scheint nicht intstalliert zu sein. Die Verwaltung von Arch / AUR Pakten wird nicht möglich sein. diff --git a/bauh/gems/arch/resources/locale/en b/bauh/gems/arch/resources/locale/en index f51ffcfc..9dfa9425 100644 --- a/bauh/gems/arch/resources/locale/en +++ b/bauh/gems/arch/resources/locale/en @@ -47,7 +47,8 @@ arch.install.dependency.install.error=Could not install dependent package {}. In arch.uninstall.required_by={} cannot be uninstalled because it is necessary for these following packages to work arch.uninstall.required_by.advice=Uninstall them first before uninstalling {}. arch.install.optdeps.request.title=Optional dependencies -arch.install.optdeps.request.body={} was succesfully installed ! There are some optional associated packages that you might want to install ( check those you want ) +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.optdep.error=Could not install the optional package {} arch.optdeps.checking=Checking {} optional dependencies arch.warning.disabled={} seems not to be installed. It will not be possible to manage Arch / AUR packages. diff --git a/bauh/gems/arch/resources/locale/es b/bauh/gems/arch/resources/locale/es index 60e47c41..4a14dfc6 100644 --- a/bauh/gems/arch/resources/locale/es +++ b/bauh/gems/arch/resources/locale/es @@ -79,7 +79,8 @@ arch.install.dependency.install.error=No se pudo instalar el paquete dependiente arch.uninstall.required_by=No se puede desinstalar {} porque es necesario para que los siguientes paquetes funcionen arch.uninstall.required_by.advice=Debe desinstalarlos primero antes de desinstalar {} arch.install.optdeps.request.title=Dependencias opcionales -arch.install.optdeps.request.body=¡{} se instaló correctamente! Hay algunos paquetes opcionales asociados que es posible que desee instalar ( marque los que desee ) +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.optdep.error=No se pudo instalar el paquete opcional {} arch.optdeps.checking=Verificando las dependencias opcionales de {} arch.warning.disabled={} parece no estar instalado. No será posible administrar paquetes Arch / AUR. diff --git a/bauh/gems/arch/resources/locale/it b/bauh/gems/arch/resources/locale/it index c4acadde..483d7e53 100644 --- a/bauh/gems/arch/resources/locale/it +++ b/bauh/gems/arch/resources/locale/it @@ -47,7 +47,8 @@ arch.install.dependency.install.error=Impossibile installare il pacchetto dipend arch.uninstall.required_by={} non può essere disinstallato perché è necessario che i seguenti pacchetti funzionino arch.uninstall.required_by.advice= Uninstall them first before uninstalling {}. arch.install.optdeps.request.title=Dipendenze opzionali -arch.install.optdeps.request.body={} è stato installato con successo! Ci sono alcuni pacchetti associati opzionali che potresti voler installare (controlla quelli che vuoi) +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.optdep.error=Impossibile installare il pacchetto opzionale {} arch.optdeps.checking=Verifica di {} dipendenze opzionali arch.warning.disabled={} sembra non essere installato. Non sarà possibile gestire i pacchetti Arch/AUR. diff --git a/bauh/gems/arch/resources/locale/pt b/bauh/gems/arch/resources/locale/pt index 8315cbd4..cc952077 100644 --- a/bauh/gems/arch/resources/locale/pt +++ b/bauh/gems/arch/resources/locale/pt @@ -79,7 +79,8 @@ arch.install.dependency.install.error=Não foi possível instalar o pacote depen arch.uninstall.required_by={} não pode ser desinstalado porque ele é necessário para o funcionamento dos seguintes pacotes arch.uninstall.required_by.advice=Desinstale eles primeiro antes de desinstalar {} arch.install.optdeps.request.title=Dependências opcionais -arch.install.optdeps.request.body={} foi instalado com sucesso ! Existem alguns pacotes associados opcionais que você talvez queira instalar ( marque os desejados ) +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.optdep.error=Não foi possível instalar o pacote opcional {} arch.optdeps.checking=Verificando as dependências opcionais de {} arch.warning.disabled={} parece não estar instalado. Não será possível gerenciar pacotes Arch / AUR. From 5394a73f840a50b4383ab0b53f057aa09ec9a5bb Mon Sep 17 00:00:00 2001 From: Vinicius Moreira Date: Mon, 2 Dec 2019 11:39:08 -0300 Subject: [PATCH 02/13] [aur][pacman] improving comments --- bauh/gems/arch/pacman.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bauh/gems/arch/pacman.py b/bauh/gems/arch/pacman.py index 11c551da..06fe978f 100644 --- a/bauh/gems/arch/pacman.py +++ b/bauh/gems/arch/pacman.py @@ -39,7 +39,7 @@ def get_mirrors(pkgs: Set[str]) -> dict: not_found = {pkg for pkg in pkgs if pkg not in mirrors} - if not_found: # if there are any not found, try to find via the single method: + 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) From 4f8a709fc49336cca3c94a1d2f23fb940e7cb9c3 Mon Sep 17 00:00:00 2001 From: Vinicius Moreira Date: Mon, 2 Dec 2019 12:21:17 -0300 Subject: [PATCH 03/13] [i18n] --- bauh/view/resources/locale/ca | 3 ++- bauh/view/resources/locale/de | 3 ++- bauh/view/resources/locale/en | 1 + bauh/view/resources/locale/es | 3 ++- bauh/view/resources/locale/it | 3 ++- bauh/view/resources/locale/pt | 3 ++- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/bauh/view/resources/locale/ca b/bauh/view/resources/locale/ca index 1cbb40fb..f5ab61ba 100644 --- a/bauh/view/resources/locale/ca +++ b/bauh/view/resources/locale/ca @@ -198,4 +198,5 @@ continue=continua stable=estable close=tanca publisher.verified=verificat -mirror=mirall \ No newline at end of file +mirror=mirall +emulator=emulador \ No newline at end of file diff --git a/bauh/view/resources/locale/de b/bauh/view/resources/locale/de index 3f5b8db2..6e73d587 100644 --- a/bauh/view/resources/locale/de +++ b/bauh/view/resources/locale/de @@ -152,4 +152,5 @@ screenshots.download.no_response=Bild nicht gefunden continue=Weiter stable=Stabil close=Schließen -publisher.verified=Verifiziert \ No newline at end of file +publisher.verified=Verifiziert +emulator=emulator \ No newline at end of file diff --git a/bauh/view/resources/locale/en b/bauh/view/resources/locale/en index 2c30f3f8..09f24e74 100644 --- a/bauh/view/resources/locale/en +++ b/bauh/view/resources/locale/en @@ -154,3 +154,4 @@ stable=stable close=close publisher.verified=verified mirror=mirror +emulator=emulator diff --git a/bauh/view/resources/locale/es b/bauh/view/resources/locale/es index 1e9aa595..a54c5f76 100644 --- a/bauh/view/resources/locale/es +++ b/bauh/view/resources/locale/es @@ -197,4 +197,5 @@ continue=continuar stable=estable close=cerrar publisher.verified=verificado -mirror=espejo \ No newline at end of file +mirror=espejo +emulator=emulador \ No newline at end of file diff --git a/bauh/view/resources/locale/it b/bauh/view/resources/locale/it index 54ef7ae0..0053b289 100644 --- a/bauh/view/resources/locale/it +++ b/bauh/view/resources/locale/it @@ -153,4 +153,5 @@ continue=continua stable=stabile close=vicino publisher.verified=verificato -mirror=specchio \ No newline at end of file +mirror=specchio +emulator=emulatore \ No newline at end of file diff --git a/bauh/view/resources/locale/pt b/bauh/view/resources/locale/pt index 67469bc6..073912b6 100644 --- a/bauh/view/resources/locale/pt +++ b/bauh/view/resources/locale/pt @@ -200,4 +200,5 @@ continue=continuar stable=estável close=fechar publisher.verified=verificado -mirror=espelho \ No newline at end of file +mirror=espelho +emulator=emulador \ No newline at end of file From d0d478de999e04d5551d1f6e58eefdf9e424dddb Mon Sep 17 00:00:00 2001 From: Vinicius Moreira Date: Mon, 2 Dec 2019 12:53:48 -0300 Subject: [PATCH 04/13] [improvement][aur] optdeps dialog: 'cancel' button label changed to 'do not install' --- CHANGELOG.md | 5 ++++- bauh/gems/arch/confirmation.py | 4 ++-- bauh/gems/arch/controller.py | 2 +- bauh/view/resources/locale/ca | 3 ++- bauh/view/resources/locale/de | 3 ++- bauh/view/resources/locale/en | 1 + bauh/view/resources/locale/es | 3 ++- bauh/view/resources/locale/it | 3 ++- bauh/view/resources/locale/pt | 3 ++- 9 files changed, 18 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c51e57c4..11c22971 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [0.7.4] 2019-12 +### Improvements +- Some AUR labels have been changed to not confuse the user + ### Fixes - AUR: - not finding some dependencies declared as files instead of the package names (e.g: dolphin-emu-git ) - + ## [0.7.3] 2019-11-29 ### Improvements diff --git a/bauh/gems/arch/confirmation.py b/bauh/gems/arch/confirmation.py index 054acdeb..12b73fdf 100644 --- a/bauh/gems/arch/confirmation.py +++ b/bauh/gems/arch/confirmation.py @@ -27,8 +27,8 @@ def request_optional_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatch install = watcher.request_confirmation(title=i18n['arch.install.optdeps.request.title'], body='

{}.

{}.

'.format(i18n['arch.install.optdeps.request.body'].format(bold(pkgname)), i18n['arch.install.optdeps.request.help']), components=[view_opts], - confirmation_label=i18n['install'], - deny_label=i18n['cancel']) + confirmation_label=i18n['install'].capitalize(), + deny_label=i18n['do_not.install'].capitalize()) if install: return {o.value for o in view_opts.values} diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 53e7bfb8..445a2c47 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -467,7 +467,7 @@ def _install_missings_deps_and_keys(self, pkgname: str, root_password: str, hand depnames = {RE_SPLIT_VERSION.split(dep)[0] for dep in check_res['missing_deps']} dep_mirrors = self._map_mirrors(depnames) - if len(depnames) != len(dep_mirrors): # cheking if a dependency could not be found in any mirror + 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) diff --git a/bauh/view/resources/locale/ca b/bauh/view/resources/locale/ca index f5ab61ba..f080866b 100644 --- a/bauh/view/resources/locale/ca +++ b/bauh/view/resources/locale/ca @@ -199,4 +199,5 @@ stable=estable close=tanca publisher.verified=verificat mirror=mirall -emulator=emulador \ No newline at end of file +emulator=emulador +do_not.install=no instal·leu \ No newline at end of file diff --git a/bauh/view/resources/locale/de b/bauh/view/resources/locale/de index 6e73d587..a7b7f02f 100644 --- a/bauh/view/resources/locale/de +++ b/bauh/view/resources/locale/de @@ -153,4 +153,5 @@ continue=Weiter stable=Stabil close=Schließen publisher.verified=Verifiziert -emulator=emulator \ No newline at end of file +emulator=emulator +do_not.install=nicht installieren \ No newline at end of file diff --git a/bauh/view/resources/locale/en b/bauh/view/resources/locale/en index 09f24e74..ab040dae 100644 --- a/bauh/view/resources/locale/en +++ b/bauh/view/resources/locale/en @@ -155,3 +155,4 @@ close=close publisher.verified=verified mirror=mirror emulator=emulator +do_not.install=don't install diff --git a/bauh/view/resources/locale/es b/bauh/view/resources/locale/es index a54c5f76..8be80d9a 100644 --- a/bauh/view/resources/locale/es +++ b/bauh/view/resources/locale/es @@ -198,4 +198,5 @@ stable=estable close=cerrar publisher.verified=verificado mirror=espejo -emulator=emulador \ No newline at end of file +emulator=emulador +do_not.install=no instalar \ No newline at end of file diff --git a/bauh/view/resources/locale/it b/bauh/view/resources/locale/it index 0053b289..666f8f2c 100644 --- a/bauh/view/resources/locale/it +++ b/bauh/view/resources/locale/it @@ -154,4 +154,5 @@ stable=stabile close=vicino publisher.verified=verificato mirror=specchio -emulator=emulatore \ No newline at end of file +emulator=emulatore +do_not.install=non installare \ No newline at end of file diff --git a/bauh/view/resources/locale/pt b/bauh/view/resources/locale/pt index 073912b6..71890dff 100644 --- a/bauh/view/resources/locale/pt +++ b/bauh/view/resources/locale/pt @@ -201,4 +201,5 @@ stable=estável close=fechar publisher.verified=verificado mirror=espelho -emulator=emulador \ No newline at end of file +emulator=emulador +do_not.install=não instalar \ No newline at end of file From 5acd06a708f5b2ba80f73236a879b4c6bd9e7aa0 Mon Sep 17 00:00:00 2001 From: Vinicius Moreira Date: Mon, 2 Dec 2019 17:37:42 -0300 Subject: [PATCH 05/13] [aur] improving dialog labels --- bauh/gems/arch/confirmation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bauh/gems/arch/confirmation.py b/bauh/gems/arch/confirmation.py index 12b73fdf..8b3e29de 100644 --- a/bauh/gems/arch/confirmation.py +++ b/bauh/gems/arch/confirmation.py @@ -35,7 +35,7 @@ def request_optional_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatch def request_install_missing_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatcher, i18n: I18n) -> bool: - msg = '

{}

'.format(i18n['arch.missing_deps.body'].format(bold(pkgname)) + ':') + msg = '

{}

'.format(i18n['arch.missing_deps.body'].format(bold(pkgname))) opts = [] for p, m in pkg_mirrors.items(): @@ -46,4 +46,4 @@ def request_install_missing_deps(pkgname: str, pkg_mirrors: dict, watcher: Proce comp = MultipleSelectComponent(label='', options=opts, default_options=set(opts)) - return watcher.request_confirmation(i18n['arch.missing_deps.title'], msg, [comp], confirmation_label=i18n['continue'].capitalize()) + return watcher.request_confirmation(i18n['arch.missing_deps.title'], msg, [comp], confirmation_label=i18n['continue'].capitalize(), deny_label=i18n['cancel'].capitalize()) From 2aec03586a81e3b03bb499589c8d649f063baec1 Mon Sep 17 00:00:00 2001 From: Vinicius Moreira Date: Mon, 2 Dec 2019 18:02:07 -0300 Subject: [PATCH 06/13] [fix][aur] replaces the wrong term 'mirror' by 'repository' --- CHANGELOG.md | 1 + bauh/gems/arch/confirmation.py | 4 ++-- bauh/gems/arch/controller.py | 6 +++--- bauh/view/resources/locale/ca | 3 ++- bauh/view/resources/locale/de | 3 ++- bauh/view/resources/locale/en | 1 + bauh/view/resources/locale/es | 3 ++- bauh/view/resources/locale/it | 3 ++- bauh/view/resources/locale/pt | 3 ++- 9 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11c22971..04de7d18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixes - AUR: - not finding some dependencies declared as files instead of the package names (e.g: dolphin-emu-git ) + - replaces the wrong term **mirror** by **repository** ## [0.7.3] 2019-11-29 diff --git a/bauh/gems/arch/confirmation.py b/bauh/gems/arch/confirmation.py index 8b3e29de..15838e93 100644 --- a/bauh/gems/arch/confirmation.py +++ b/bauh/gems/arch/confirmation.py @@ -16,7 +16,7 @@ def request_optional_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatch opts = [] for p, d in pkg_mirrors.items(): - op = InputOption('{}{} ( {}: {} )'.format(p, ': ' + d['desc'] if d['desc'] else '', i18n['mirror'], d['mirror'].upper()), p) + op = InputOption('{}{} ( {}: {} )'.format(p, ': ' + d['desc'] if d['desc'] else '', i18n['repository'], d['mirror'].upper()), p) op.icon_path = _get_mirror_icon(d['mirror']) opts.append(op) @@ -39,7 +39,7 @@ def request_install_missing_deps(pkgname: str, pkg_mirrors: dict, watcher: Proce opts = [] for p, m in pkg_mirrors.items(): - op = InputOption('{} ( {}: {} )'.format(p, i18n['mirror'], m.upper()), p) + op = InputOption('{} ( {}: {} )'.format(p, i18n['repository'], m.upper()), p) op.read_only = True op.icon_path = _get_mirror_icon(m) opts.append(op) diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 445a2c47..0612fc57 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -428,7 +428,7 @@ def _make_pkg(self, pkgname: str, maintainer: str, root_password: str, handler: self._pre_download_source(pkgname, project_dir, handler.watcher) self._update_progress(handler.watcher, 50, change_progress) - if not self._install_missings_deps_and_keys(pkgname, root_password, handler, project_dir): + if not self._check_deps(pkgname, root_password, handler, project_dir): return False # building main package @@ -458,7 +458,7 @@ def _make_pkg(self, pkgname: str, maintainer: str, root_password: str, handler: return False - def _install_missings_deps_and_keys(self, pkgname: str, root_password: str, handler: ProcessHandler, pkgdir: str) -> bool: + def _check_deps(self, pkgname: str, root_password: str, handler: ProcessHandler, pkgdir: str) -> bool: handler.watcher.change_substatus(self.i18n['arch.checking.deps'].format(bold(pkgname))) check_res = makepkg.check(pkgdir, handler) @@ -486,7 +486,7 @@ def _install_missings_deps_and_keys(self, pkgname: str, root_password: str, hand return False # it is necessary to re-check because missing PGP keys are only notified when there are none missing - return self._install_missings_deps_and_keys(pkgname, root_password, handler, pkgdir) + return self._check_deps(pkgname, root_password, handler, pkgdir) if check_res.get('gpg_key'): if handler.watcher.request_confirmation(title=self.i18n['arch.aur.install.unknown_key.title'], diff --git a/bauh/view/resources/locale/ca b/bauh/view/resources/locale/ca index f080866b..6f557128 100644 --- a/bauh/view/resources/locale/ca +++ b/bauh/view/resources/locale/ca @@ -200,4 +200,5 @@ close=tanca publisher.verified=verificat mirror=mirall emulator=emulador -do_not.install=no instal·leu \ No newline at end of file +do_not.install=no instal·leu +repository=dipòsit \ No newline at end of file diff --git a/bauh/view/resources/locale/de b/bauh/view/resources/locale/de index a7b7f02f..06f1a45f 100644 --- a/bauh/view/resources/locale/de +++ b/bauh/view/resources/locale/de @@ -154,4 +154,5 @@ stable=Stabil close=Schließen publisher.verified=Verifiziert emulator=emulator -do_not.install=nicht installieren \ No newline at end of file +do_not.install=nicht installieren +repository=repository \ No newline at end of file diff --git a/bauh/view/resources/locale/en b/bauh/view/resources/locale/en index ab040dae..72a26c48 100644 --- a/bauh/view/resources/locale/en +++ b/bauh/view/resources/locale/en @@ -156,3 +156,4 @@ publisher.verified=verified mirror=mirror emulator=emulator do_not.install=don't install +repository=repository diff --git a/bauh/view/resources/locale/es b/bauh/view/resources/locale/es index 8be80d9a..c3324dc0 100644 --- a/bauh/view/resources/locale/es +++ b/bauh/view/resources/locale/es @@ -199,4 +199,5 @@ close=cerrar publisher.verified=verificado mirror=espejo emulator=emulador -do_not.install=no instalar \ No newline at end of file +do_not.install=no instalar +repository=repositorio \ No newline at end of file diff --git a/bauh/view/resources/locale/it b/bauh/view/resources/locale/it index 666f8f2c..8a3043e6 100644 --- a/bauh/view/resources/locale/it +++ b/bauh/view/resources/locale/it @@ -155,4 +155,5 @@ close=vicino publisher.verified=verificato mirror=specchio emulator=emulatore -do_not.install=non installare \ No newline at end of file +do_not.install=non installare +repository=deposito \ No newline at end of file diff --git a/bauh/view/resources/locale/pt b/bauh/view/resources/locale/pt index 71890dff..7a3afc7f 100644 --- a/bauh/view/resources/locale/pt +++ b/bauh/view/resources/locale/pt @@ -202,4 +202,5 @@ close=fechar publisher.verified=verificado mirror=espelho emulator=emulador -do_not.install=não instalar \ No newline at end of file +do_not.install=não instalar +repository=repositório \ No newline at end of file From e01249f49c0d7e994da28441977455adc5015bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Wed, 4 Dec 2019 12:47:10 -0300 Subject: [PATCH 07/13] [improvement][aur] retrieving and displaying all transitive required dependencies --- CHANGELOG.md | 6 +- README.md | 3 +- bauh/gems/arch/aur.py | 15 +++ bauh/gems/arch/confirmation.py | 14 +-- bauh/gems/arch/controller.py | 125 ++++++++++++++++-------- bauh/gems/arch/depedencies.py | 95 ++++++++++++++++++ bauh/gems/arch/exceptions.py | 5 + bauh/gems/arch/pacman.py | 148 ++++++++++++++++++++++++++++- bauh/gems/arch/resources/locale/ca | 8 +- bauh/gems/arch/resources/locale/de | 8 +- bauh/gems/arch/resources/locale/en | 8 +- bauh/gems/arch/resources/locale/es | 8 +- bauh/gems/arch/resources/locale/it | 8 +- bauh/gems/arch/resources/locale/pt | 8 +- bauh/gems/snap/controller.py | 5 +- bauh/gems/snap/resources/locale/ca | 3 +- bauh/gems/snap/resources/locale/de | 3 +- bauh/gems/snap/resources/locale/en | 3 +- bauh/gems/snap/resources/locale/es | 3 +- bauh/gems/snap/resources/locale/it | 3 +- bauh/gems/snap/resources/locale/pt | 3 +- bauh/view/qt/confirmation.py | 24 ++++- bauh/view/qt/window.py | 3 +- 23 files changed, 428 insertions(+), 81 deletions(-) create mode 100644 bauh/gems/arch/depedencies.py create mode 100644 bauh/gems/arch/exceptions.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 04de7d18..c4339b03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [0.7.4] 2019-12 ### Improvements -- Some AUR labels have been changed to not confuse the user +- AUR: + - retrieving and displaying all transitive required dependencies ( it can be disabled via the new environment variable **BAUH_ARCH_CHECK_SUBDEPS=0** ) + - displaying **makedepends** and **checkdepends** in the info window + - Some AUR labels have been changed to not confuse the user +- Minor UI improvements ### Fixes - AUR: diff --git a/README.md b/README.md index 09dadc67..102ad4fe 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,8 @@ will be pre-downloaded faster ( it does **NOT** modify your **pacman** settings ( For more information about these optimizations, have a look at [Makepkg](https://wiki.archlinux.org/index.php/Makepkg) ) - Arch package memory-indexer running every 20 minutes. This memory index is used when AUR Api cannot handle the amount of results found for a given search. It can be disabled via the environment variable **BAUH_ARCH_AUR_INDEX_UPDATER=0**. - If some of your installed packages are not categorized, send an e-mail to **bauh4linux@gmail.com** informing their names and categories in the following format: ```name=category1[,category2,category3,...]``` - +- Transitive dependencies checking can be disabled through the environment variable **BAUH_ARCH_CHECK_SUBDEPS=0**. The dependency checking process will be +faster, but the application will ask for a new confirmation every time a not installed dependency is detected. ### General settings You can change some application settings via environment variables or arguments (type ```bauh --help``` to get more information). diff --git a/bauh/gems/arch/aur.py b/bauh/gems/arch/aur.py index 857c4be2..6c464ca7 100644 --- a/bauh/gems/arch/aur.py +++ b/bauh/gems/arch/aur.py @@ -4,6 +4,8 @@ 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 @@ def get_src_info(self, name: str) -> dict: 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)]) diff --git a/bauh/gems/arch/confirmation.py b/bauh/gems/arch/confirmation.py index 15838e93..bec6e10a 100644 --- a/bauh/gems/arch/confirmation.py +++ b/bauh/gems/arch/confirmation.py @@ -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='

{}.

{}.

'.format(i18n['arch.install.optdeps.request.body'].format(bold(pkgname)), i18n['arch.install.optdeps.request.help']), + body='

{}.

{}:

'.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 = '

{}

'.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 = '

{}

'.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)) diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 0612fc57..9dc54b0d 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -6,7 +6,7 @@ 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.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 @@ def __init__(self, context: ApplicationContext): 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 @@ def downgrade(self, pkg: ArchPackage, root_password: str, watcher: ProcessWatche 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 @@ def get_info(self, pkg: ArchPackage) -> dict: 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 @@ def get_history(self, pkg: ArchPackage) -> PackageHistory: 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 @@ def _pre_download_source(self, pkgname: str, project_dir: str, watcher: ProcessW 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 @@ def _make_pkg(self, pkgname: str, maintainer: str, root_password: str, handler: 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 @@ def _install_optdeps(self, pkgname: str, root_password: str, handler: ProcessHan 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 @@ def _install_from_aur(self, pkgname: str, maintainer: str, root_password: str, h 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]))) diff --git a/bauh/gems/arch/depedencies.py b/bauh/gems/arch/depedencies.py new file mode 100644 index 00000000..5d3774bd --- /dev/null +++ b/bauh/gems/arch/depedencies.py @@ -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 diff --git a/bauh/gems/arch/exceptions.py b/bauh/gems/arch/exceptions.py new file mode 100644 index 00000000..d868cb15 --- /dev/null +++ b/bauh/gems/arch/exceptions.py @@ -0,0 +1,5 @@ + +class PackageNotFoundException(Exception): + + def __init__(self, name: str): + self.name = name diff --git a/bauh/gems/arch/pacman.py b/bauh/gems/arch/pacman.py index 06fe978f..5c9381ae 100644 --- a/bauh/gems/arch/pacman.py +++ b/bauh/gems/arch/pacman.py @@ -3,9 +3,11 @@ 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 +""" diff --git a/bauh/gems/arch/resources/locale/ca b/bauh/gems/arch/resources/locale/ca index 4ccf68ca..1d419dc5 100644 --- a/bauh/gems/arch/resources/locale/ca +++ b/bauh/gems/arch/resources/locale/ca @@ -36,7 +36,7 @@ aur.info.conflicts with=té un conflicte amb arch.install.conflict.popup.title=S’ha detectat un conflicte arch.install.conflict.popup.body=Les aplicacions {} estan en conflicte. Heu de desinstal·lar una per a instal·lar l’altra. Voleu continuar? arch.missing_deps.title=Dependències mancants -arch.missing_deps.body=S’han d’instal·lar les dependències següents abans de continuar amb la instal·lació de {} +arch.missing_deps.body=S’han d’instal·lar les {deps} dependències següents abans de continuar amb la instal·lació de {name} arch.downgrade.error=Error arch.downgrade.impossible=No s’ha 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 d’instal·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 s’ha trobat la dependència arch.install.dep_not_found.body=No s’ha trobat la dependència requerida {} a l’AUR ni als servidors rèplica per defecte. S’ha cancel·lat la instal·lació. diff --git a/bauh/gems/arch/resources/locale/de b/bauh/gems/arch/resources/locale/de index 5315ead8..deb95eee 100644 --- a/bauh/gems/arch/resources/locale/de +++ b/bauh/gems/arch/resources/locale/de @@ -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 diff --git a/bauh/gems/arch/resources/locale/en b/bauh/gems/arch/resources/locale/en index 9dfa9425..ad58825d 100644 --- a/bauh/gems/arch/resources/locale/en +++ b/bauh/gems/arch/resources/locale/en @@ -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. diff --git a/bauh/gems/arch/resources/locale/es b/bauh/gems/arch/resources/locale/es index 4a14dfc6..e71632e3 100644 --- a/bauh/gems/arch/resources/locale/es +++ b/bauh/gems/arch/resources/locale/es @@ -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. diff --git a/bauh/gems/arch/resources/locale/it b/bauh/gems/arch/resources/locale/it index 483d7e53..45ae9bce 100644 --- a/bauh/gems/arch/resources/locale/it +++ b/bauh/gems/arch/resources/locale/it @@ -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. diff --git a/bauh/gems/arch/resources/locale/pt b/bauh/gems/arch/resources/locale/pt index cc952077..266da512 100644 --- a/bauh/gems/arch/resources/locale/pt +++ b/bauh/gems/arch/resources/locale/pt @@ -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. diff --git a/bauh/gems/snap/controller.py b/bauh/gems/snap/controller.py index cc4a5ae3..37489422 100644 --- a/bauh/gems/snap/controller.py +++ b/bauh/gems/snap/controller.py @@ -161,8 +161,11 @@ def install(self, pkg: SnapApplication, root_password: str, watcher: ProcessWatc 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 = '

{}.

'.format(self.i18n['snap.install.available_channels.message'].format(bold(self.i18n['stable']), bold(pkg.name))) + body += '

{}:

'.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']): diff --git a/bauh/gems/snap/resources/locale/ca b/bauh/gems/snap/resources/locale/ca index 7d06be86..68bc77d6 100644 --- a/bauh/gems/snap/resources/locale/ca +++ b/bauh/gems/snap/resources/locale/ca @@ -15,4 +15,5 @@ snap.notifications.api.unavailable=Sembla que l’API de {} no està disponible snap.action.refresh.status=S’està 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 n’hi 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 n’hi ha els següents +snap.install.available_channels.help=Seleccioneu-ne un si voleu continuar diff --git a/bauh/gems/snap/resources/locale/de b/bauh/gems/snap/resources/locale/de index c71ba525..445b779e 100644 --- a/bauh/gems/snap/resources/locale/de +++ b/bauh/gems/snap/resources/locale/de @@ -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 diff --git a/bauh/gems/snap/resources/locale/en b/bauh/gems/snap/resources/locale/en index 2155e858..a6cd99a6 100644 --- a/bauh/gems/snap/resources/locale/en +++ b/bauh/gems/snap/resources/locale/en @@ -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 diff --git a/bauh/gems/snap/resources/locale/es b/bauh/gems/snap/resources/locale/es index 07e0501d..544e969b 100644 --- a/bauh/gems/snap/resources/locale/es +++ b/bauh/gems/snap/resources/locale/es @@ -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 ) \ No newline at end of file +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 \ No newline at end of file diff --git a/bauh/gems/snap/resources/locale/it b/bauh/gems/snap/resources/locale/it index 57cf629d..86b2d0dd 100644 --- a/bauh/gems/snap/resources/locale/it +++ b/bauh/gems/snap/resources/locale/it @@ -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 diff --git a/bauh/gems/snap/resources/locale/pt b/bauh/gems/snap/resources/locale/pt index 4960ddc5..bf2f66e2 100644 --- a/bauh/gems/snap/resources/locale/pt +++ b/bauh/gems/snap/resources/locale/pt @@ -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 ) \ No newline at end of file +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 \ No newline at end of file diff --git a/bauh/view/qt/confirmation.py b/bauh/view/qt/confirmation.py index ceeee6ab..b169f68d 100644 --- a/bauh/view/qt/confirmation.py +++ b/bauh/view/qt/confirmation.py @@ -1,6 +1,7 @@ from typing import List -from PyQt5.QtWidgets import QMessageBox, QVBoxLayout, QLabel, QWidget +from PyQt5.QtCore import QSize +from PyQt5.QtWidgets import QMessageBox, QVBoxLayout, QLabel, QWidget, QScrollArea, QFrame from bauh.api.abstract.view import ViewComponent, SingleSelectComponent, MultipleSelectComponent from bauh.view.qt import css @@ -10,7 +11,8 @@ class ConfirmationDialog(QMessageBox): - def __init__(self, title: str, body: str, i18n: I18n, components: List[ViewComponent] = None, confirmation_label: str = None, deny_label: str = None): + def __init__(self, title: str, body: str, i18n: I18n, screen_size: QSize, components: List[ViewComponent] = None, + confirmation_label: str = None, deny_label: str = None): super(ConfirmationDialog, self).__init__() self.setWindowTitle(title) self.setStyleSheet('QLabel { margin-right: 25px; }') @@ -26,8 +28,15 @@ def __init__(self, title: str, body: str, i18n: I18n, components: List[ViewCompo self.layout().addWidget(QLabel(body), 0, 1) if components: - comps_container = QWidget(parent=self) + scroll = QScrollArea(self) + scroll.setFrameShape(QFrame.NoFrame) + scroll.setWidgetResizable(True) + + comps_container = QWidget() comps_container.setLayout(QVBoxLayout()) + scroll.setWidget(comps_container) + + height = 0 for idx, comp in enumerate(components): if isinstance(comp, SingleSelectComponent): @@ -37,9 +46,16 @@ def __init__(self, title: str, body: str, i18n: I18n, components: List[ViewCompo else: raise Exception("Cannot render instances of " + comp.__class__.__name__) + height += inst.sizeHint().height() comps_container.layout().addWidget(inst) - self.layout().addWidget(comps_container, 1, 1) + height = height if height < screen_size.height() / 2 else height / 2 + + if height < 100: + height = 100 + + scroll.setFixedHeight(height) + self.layout().addWidget(scroll, 1, 1) self.exec_() diff --git a/bauh/view/qt/window.py b/bauh/view/qt/window.py index 33092eb9..c7a449d2 100755 --- a/bauh/view/qt/window.py +++ b/bauh/view/qt/window.py @@ -379,7 +379,8 @@ def _ask_confirmation(self, msg: dict): i18n=self.i18n, components=msg['components'], confirmation_label=msg['confirmation_label'], - deny_label=msg['deny_label']) + deny_label=msg['deny_label'], + screen_size=self.screen_size) res = diag.is_confirmed() self.thread_animate_progress.animate() self.signal_user_res.emit(res) From 86f479065d971387882b567b1a1b6f87519678b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Wed, 4 Dec 2019 14:16:33 -0300 Subject: [PATCH 08/13] [fix][aur] optional dependencies installation --- bauh/gems/arch/controller.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 9dc54b0d..9bfe23a9 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -463,7 +463,7 @@ def _build(self, pkgname: str, maintainer: str, root_password: str, handler: Pro handler.watcher.change_substatus(self.i18n['arch.optdeps.checking'].format(bold(pkgname))) - if self._install_optdeps(pkgname, root_password, handler, project_dir, change_progress=change_progress): + if self._install_optdeps(pkgname, root_password, handler, project_dir): return True return False @@ -557,7 +557,7 @@ def _handle_deps_and_keys(self, pkgname: str, root_password: str, handler: Proce return True - def _install_optdeps(self, pkgname: str, root_password: str, handler: ProcessHandler, pkgdir: str, change_progress: bool = True) -> bool: + def _install_optdeps(self, pkgname: str, root_password: str, handler: ProcessHandler, pkgdir: str) -> bool: with open('{}/.SRCINFO'.format(pkgdir)) as f: odeps = pkgbuild.read_optdeps_as_dict(f.read()) @@ -579,7 +579,17 @@ def _install_optdeps(self, pkgname: str, root_password: str, handler: ProcessHan if not deps_to_install: return True else: - dep_not_installed = self._install_deps(pkg_mirrors, root_password, handler, change_progress=True) + aur_deps, repo_deps = [], [] + + for dep in deps_to_install: + mirror = pkg_mirrors[dep] + + if mirror == 'aur': + aur_deps.append((dep, mirror)) + else: + repo_deps.append((dep, mirror)) + + dep_not_installed = self._install_deps([*repo_deps, *aur_deps], root_password, handler, change_progress=True) if dep_not_installed: message.show_optdep_not_installed(dep_not_installed, handler.watcher, self.i18n) From fab88cb995b7cdc46815f46a3d4699c34fdefbe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Fri, 6 Dec 2019 19:03:12 -0300 Subject: [PATCH 09/13] [aur] reading all transitive dependencies of the selected optional dependencies before their installation --- bauh/gems/arch/aur.py | 3 +- bauh/gems/arch/confirmation.py | 10 ++- bauh/gems/arch/controller.py | 76 +++++++++++++------ bauh/gems/arch/depedencies.py | 51 ++++++++----- bauh/gems/arch/pacman.py | 118 ++++++++++++----------------- bauh/gems/arch/resources/locale/ca | 1 + bauh/gems/arch/resources/locale/de | 1 + bauh/gems/arch/resources/locale/en | 3 +- bauh/gems/arch/resources/locale/es | 3 +- bauh/gems/arch/resources/locale/it | 1 + bauh/gems/arch/resources/locale/pt | 5 +- bauh/view/qt/confirmation.py | 5 +- 12 files changed, 151 insertions(+), 126 deletions(-) diff --git a/bauh/gems/arch/aur.py b/bauh/gems/arch/aur.py index 6c464ca7..defb1e71 100644 --- a/bauh/gems/arch/aur.py +++ b/bauh/gems/arch/aur.py @@ -4,6 +4,7 @@ from bauh.api.http import HttpClient import urllib.parse +from bauh.gems.arch import pacman from bauh.gems.arch.exceptions import PackageNotFoundException URL_INFO = 'https://aur.archlinux.org/rpc/?v=5&type=info&' @@ -57,7 +58,7 @@ def get_all_dependencies(self, name: str) -> Set[str]: for attr in ('makedepends', 'depends', 'checkdepends'): if info.get(attr): - deps.update(info[attr]) + deps.update([pacman.RE_DEP_OPERATORS.split(dep)[0] for dep in info[attr]]) return deps diff --git a/bauh/gems/arch/confirmation.py b/bauh/gems/arch/confirmation.py index bec6e10a..544c9ef3 100644 --- a/bauh/gems/arch/confirmation.py +++ b/bauh/gems/arch/confirmation.py @@ -34,11 +34,15 @@ 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, deps: List[Tuple[str,str]], watcher: ProcessWatcher, i18n: I18n) -> bool: - msg = '

{}

'.format(i18n['arch.missing_deps.body'].format(name=bold(pkgname), deps=bold(len(deps)))) +def request_install_missing_deps(pkgname: str, deps: List[Tuple[str, str]], watcher: ProcessWatcher, i18n: I18n) -> bool: + msg = '

{}

'.format(i18n['arch.missing_deps.body'].format(name=bold(pkgname) if pkgname else '', deps=bold(str(len(deps))))) opts = [] - for dep in deps: + + sorted_deps = [*deps] + sorted_deps.sort(key=lambda e: e[0]) + + for dep in sorted_deps: op = InputOption('{} ( {}: {} )'.format(dep[0], i18n['repository'], dep[1].upper()), dep[0]) op.read_only = True op.icon_path = _get_mirror_icon(dep[1]) diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 9bfe23a9..87ce01a8 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -6,7 +6,7 @@ import time from pathlib import Path from threading import Thread -from typing import List, Set, Type, Tuple +from typing import List, Set, Type, Tuple, Dict import requests @@ -431,14 +431,16 @@ def _pre_download_source(self, pkgname: str, project_dir: str, watcher: ProcessW return True + def _should_check_subdeps(self): + return bool(int(os.getenv('BAUH_ARCH_CHECK_SUBDEPS', 1))) + 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) - 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): + if not self._handle_deps_and_keys(pkgname, root_password, handler, project_dir, check_subdeps=self._should_check_subdeps()): return False # building main package @@ -468,21 +470,12 @@ def _build(self, pkgname: str, maintainer: str, root_password: str, handler: Pro return False - 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 - + def _map_known_missing_deps(self, known_deps: Dict[str, str], watcher: ProcessWatcher, check_subdeps: bool = True) -> List[Tuple[str, str]]: 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(): + for dep, repo in known_deps.items(): if repo == 'aur': aur_deps.add(dep) else: @@ -491,7 +484,7 @@ def _map_missing_deps(self, deps: List[str], watcher: ProcessWatcher, check_subd 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]) + missing_subdeps = self.deps_analyser.get_missing_subdeps_of(deps[0], deps[1]) if missing_subdeps: for dep in missing_subdeps: @@ -502,7 +495,7 @@ def _map_missing_deps(self, deps: List[str], watcher: ProcessWatcher, check_subd for dep in missing_subdeps: sorted_deps.append(dep) - for dep, repo in dep_repos.items(): + for dep, repo in known_deps.items(): if repo != 'aur': sorted_deps.append((dep, repo)) @@ -511,13 +504,26 @@ def _map_missing_deps(self, deps: List[str], watcher: ProcessWatcher, check_subd return sorted_deps + def _map_unknown_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 + + return self._map_known_missing_deps(dep_repos, watcher, check_subdeps) + 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'): - sorted_deps = self._map_missing_deps(check_res['missing_deps'], handler.watcher, check_subdeps=check_subdeps) + handler.watcher.change_substatus(self.i18n['arch.checking.missing_deps'].format(bold(pkgname))) + sorted_deps = self._map_unknown_missing_deps(check_res['missing_deps'], handler.watcher, check_subdeps=check_subdeps) if sorted_deps is None: return False @@ -579,17 +585,37 @@ def _install_optdeps(self, pkgname: str, root_password: str, handler: ProcessHan if not deps_to_install: return True else: - aur_deps, repo_deps = [], [] + sorted_deps = [] - for dep in deps_to_install: - mirror = pkg_mirrors[dep] + if self._should_check_subdeps(): + missing_deps = self._map_known_missing_deps({d: pkg_mirrors[d] for d in deps_to_install}, handler.watcher) - if mirror == 'aur': - aur_deps.append((dep, mirror)) - else: - repo_deps.append((dep, mirror)) + if missing_deps is None: + return True # because the main package installation was successful + + if missing_deps: + same_as_selected = len(deps_to_install) == len(missing_deps) and deps_to_install == {d[0] for d in missing_deps} + + if not same_as_selected and not confirmation.request_install_missing_deps(None, missing_deps, handler.watcher, self.i18n): + handler.watcher.print(self.i18n['action.cancelled']) + return True # because the main package installation was successful + + sorted_deps.extend(missing_deps) + else: + aur_deps, repo_deps = [], [] + + for dep in deps_to_install: + mirror = pkg_mirrors[dep] + + if mirror == 'aur': + aur_deps.append((dep, mirror)) + else: + repo_deps.append((dep, mirror)) + + sorted_deps.extend(repo_deps) + sorted_deps.extend(aur_deps) - dep_not_installed = self._install_deps([*repo_deps, *aur_deps], root_password, handler, change_progress=True) + dep_not_installed = self._install_deps(sorted_deps, root_password, handler, change_progress=True) if dep_not_installed: message.show_optdep_not_installed(dep_not_installed, handler.watcher, self.i18n) diff --git a/bauh/gems/arch/depedencies.py b/bauh/gems/arch/depedencies.py index 5d3774bd..5d67a7c2 100644 --- a/bauh/gems/arch/depedencies.py +++ b/bauh/gems/arch/depedencies.py @@ -32,9 +32,16 @@ def _fill_mirror(self, name: str, output: List[Tuple[str, str]]): output.append((name, '')) - def get_missing_dependencies(self, names: Set[str], mirror: str = None) -> List[Tuple[str, str]]: + def get_missing_packages(self, names: Set[str], mirror: str = None, in_analysis: Set[str] = None) -> List[Tuple[str, str]]: + """ + :param names: + :param mirror: + :param in_analysis: global set storing all names in analysis to avoid repeated recursion + :return: + """ + global_in_analysis = in_analysis if in_analysis else set() - missing_names = pacman.check_missing(names) + missing_names = pacman.check_missing({n for n in names if n not in in_analysis}) if missing_names: missing_root = [] @@ -52,44 +59,50 @@ def get_missing_dependencies(self, names: Set[str], mirror: str = None) -> List[ threads.clear() # checking if there is any unknown dependency: - for dep in missing_root: - if not dep[1]: + for rdep in missing_root: + if not rdep[1]: return missing_root + else: + global_in_analysis.add(rdep[0]) else: for missing in missing_names: missing_root.append((missing, mirror)) + global_in_analysis.add(missing) 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]) + for rdep in missing_root: + subdeps = self.aur_client.get_all_dependencies(rdep[0]) if rdep[1] == 'aur' else pacman.read_dependencies(rdep[0]) + subdeps_not_analysis = {sd for sd in subdeps if sd not in global_in_analysis} - if subdeps: - missing_subdeps = self.get_missing_dependencies(subdeps) + if subdeps_not_analysis: + missing_subdeps = self.get_missing_packages(subdeps_not_analysis, in_analysis=global_in_analysis) # 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_subdeps, *missing_root] + if subdep[0] not in missing_names: + missing_sub.append(subdep) return [*missing_sub, *missing_root] - def get_missing_dependencies_from(self, names: Set[str], mirror: str) -> List[Tuple[str, str]]: + def get_missing_subdeps_of(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) + already_added = {*names} + in_analyses = {*names} + + for name in names: + subdeps = self.aur_client.get_all_dependencies(name) if mirror == 'aur' else pacman.read_dependencies(name) if subdeps: - missing_subdeps = self.get_missing_dependencies(subdeps) + missing_subdeps = self.get_missing_packages(subdeps, in_analysis=in_analyses) if missing_subdeps: - missing.extend(missing_subdeps) - for subdep in missing_subdeps: # checking if there is any unknown: + if subdep[0] not in already_added: + missing.append(subdep) + if not subdep[0]: return missing - return missing diff --git a/bauh/gems/arch/pacman.py b/bauh/gems/arch/pacman.py index 5c9381ae..93dbb75c 100644 --- a/bauh/gems/arch/pacman.py +++ b/bauh/gems/arch/pacman.py @@ -8,6 +8,7 @@ RE_DEPS = re.compile(r'[\w\-_]+:[\s\w_\-\.]+\s+\[\w+\]') RE_OPTDEPS = re.compile(r'[\w\._\-]+\s*:') RE_DEP_NOTFOUND = re.compile(r'error:.+\'(.+)\'') +RE_DEP_OPERATORS = re.compile(r'[<>=]') def is_enabled() -> bool: @@ -15,17 +16,6 @@ def is_enabled() -> bool: return res and not res.strip().startswith('which ') -def get_configured_repository(pkg: str) -> Tuple[str, str]: - res = run_cmd('pacman -Ss {}'.format(pkg)) - - if res: - lines = res.split('\n') - - if lines: - data = lines[0].split('/') - return data[1].split(' ')[0], data[0] - - def get_repositories(pkgs: Set[str]) -> dict: pkgre = '|'.join(pkgs).replace('+', r'\+').replace('.', r'\.') @@ -39,11 +29,11 @@ def get_repositories(pkgs: Set[str]) -> dict: if p in match: mirrors[p] = match.split('/')[0] - not_found = {pkg for pkg in pkgs if pkg not in mirrors} + not_found = {pkg for pkg in pkgs if pkg and pkg not in mirrors} 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_configured_repository(dep) + mirror_data = guess_repository(dep) if mirror_data: mirrors[mirror_data[0]] = mirror_data[1] @@ -250,7 +240,7 @@ def check_missing(names: Set[str]) -> Set[str]: err_line = o.decode() if err_line: - not_found = RE_DEP_NOTFOUND.findall(err_line) + not_found = [n for n in RE_DEP_NOTFOUND.findall(err_line) if n] if not_found: not_installed.update(not_found) @@ -284,17 +274,32 @@ def read_repository_from_info(name: str) -> str: def guess_repository(name: str) -> Tuple[str, str]: - res = run_cmd('pacman -Ss {}'.format(name.split('=')[0] if '=' in name else name)) + + if not name: + raise Exception("'name' cannot be None or blank") + + only_name = RE_DEP_OPERATORS.split(name)[0] + res = run_cmd('pacman -Ss {}'.format(only_name)) if res: lines = res.split('\n') if lines: - data = lines[0].split('/') - return data[1].split(' ')[0], data[0] + for line in lines: + if line and not line.startswith(' '): + data = line.split('/') + line_name, line_repo = data[1].split(' ')[0], data[0] + provided = read_provides(line_name) -def read_dependencies(name: str) -> Set[str]: + if provided: + found = {p for p in provided if only_name == RE_DEP_OPERATORS.split(p)[0]} + + if found: + return line_name, line_repo + + +def read_provides(name: str) -> Set[str]: dep_info = new_subprocess(['pacman', '-Si', name]) not_found = False @@ -310,69 +315,42 @@ def read_dependencies(name: str) -> Set[str]: 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: + provides = None + + for out in new_subprocess(['grep', '-Po', 'Provides\s+:\s\K(.+)'], stdin=dep_info.stdout).stdout: if out: - line = out.decode().strip() + provided_names = [p.strip() for p in out.decode().strip().split(' ') if p] - if line: - depends_on.update(line.split(' ')) + if provided_names[0].lower() == 'none': + provides = {name} + else: + provides = set(provided_names) - return depends_on + return provides -""" -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 = [] +def read_dependencies(name: str) -> Set[str]: + dep_info = new_subprocess(['pacman', '-Si', name]) - for o in installed.stderr: + not_found = False + + for o in dep_info.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 + if RE_DEP_NOTFOUND.findall(err_line): + not_found = True - subdeps_mirrors = dict() + if not_found: + raise PackageNotFoundException(name) - for pkg in missing: - subdeps_mirrors.update(check_uninstalled(pkg)) + 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() - missing.update(subdeps_mirrors, stop_recursion_if_no_mirror=stop_recursion_if_no_mirror) + if line: + depends_on.update([d for d in line.split(' ') if d and d.lower() != 'none']) - return missing -""" + return depends_on diff --git a/bauh/gems/arch/resources/locale/ca b/bauh/gems/arch/resources/locale/ca index 1d419dc5..f71d1b72 100644 --- a/bauh/gems/arch/resources/locale/ca +++ b/bauh/gems/arch/resources/locale/ca @@ -45,6 +45,7 @@ aur.history.3_date=data arch.downloading.package=S’està baixant el paquet arch.uncompressing.package=S’està descomprimint el paquet arch.checking.deps=S’estan comprovant les dependències de {} +arch.checking.missing_deps=Verificació de les dependències que falten de {} arch.missing_deps_found=Dependències mancants per a {} arch.building.package=S’està compilant el paquet {} arch.checking.conflicts=S’està comprovant si hi ha conflictes amb {} diff --git a/bauh/gems/arch/resources/locale/de b/bauh/gems/arch/resources/locale/de index deb95eee..adf008ca 100644 --- a/bauh/gems/arch/resources/locale/de +++ b/bauh/gems/arch/resources/locale/de @@ -13,6 +13,7 @@ aur.history.3_date=Datum arch.downloading.package=Paket herunterladen arch.uncompressing.package=Paket entpacken arch.checking.deps={} Abhängigkeiten überprüfen +arch.checking.missing_deps=Überprüfen der fehlenden Abhängigkeiten von {} arch.missing_deps_found=Fehlende Abhängigkeiten für {} arch.building.package=Paket {} erstellen arch.checking.conflicts=Konflikte mit {} überprüfen diff --git a/bauh/gems/arch/resources/locale/en b/bauh/gems/arch/resources/locale/en index ad58825d..f2a295de 100644 --- a/bauh/gems/arch/resources/locale/en +++ b/bauh/gems/arch/resources/locale/en @@ -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 {deps} dependencies must be installed before the {name} installation continues +arch.missing_deps.body=The following {deps} dependencies must be installed so the {name} installation can continue arch.downgrade.error=Error arch.downgrade.impossible=It is not possible to downgrade {} aur.history.1_version=version @@ -14,6 +14,7 @@ arch.downloading.package=Downloading the package arch.uncompressing.package=Uncompressing the package arch.checking.deps=Checking {} dependencies arch.missing_deps_found=Missing dependencies for {} +arch.checking.missing_deps=Verifying missing dependencies of {} arch.building.package=Building package {} arch.checking.conflicts=Checking any conflicts with {} arch.installing.package=Installing {} package diff --git a/bauh/gems/arch/resources/locale/es b/bauh/gems/arch/resources/locale/es index e71632e3..711e5c48 100644 --- a/bauh/gems/arch/resources/locale/es +++ b/bauh/gems/arch/resources/locale/es @@ -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 {deps} dependencias antes de continuar la instalación de {name} +arch.missing_deps.body=Deben instalarse las siguientes {deps} dependencias para que la instalación de {name} pueda continuar arch.downgrade.error=Error arch.downgrade.impossible=No es posible revertir la versión de {} aur.history.1_version=versión @@ -45,6 +45,7 @@ aur.history.3_date=fecha arch.downloading.package=Descargando el paquete arch.uncompressing.package=Descomprimindo el paquete arch.checking.deps=Verificando las dependencias de {} +arch.checking.missing_deps=Verificando las dependencias faltantes de {} arch.missing_deps_found=Dependencias faltantes para {} arch.building.package=Construyendo el paquete {} arch.checking.conflicts=Verificando se hay conflictos con {} diff --git a/bauh/gems/arch/resources/locale/it b/bauh/gems/arch/resources/locale/it index 45ae9bce..23fd2b3e 100644 --- a/bauh/gems/arch/resources/locale/it +++ b/bauh/gems/arch/resources/locale/it @@ -13,6 +13,7 @@ aur.history.3_date=data arch.downloading.package=Download del pacchetto arch.uncompressing.package=Non comprimere il pacchetto arch.checking.deps=Verifica di {} dipendenze +arch.checking.missing_deps=Verifica delle dipendenze mancanti di {} arch.missing_deps_found=Dipendenze mancanti per {} arch.building.package=Pacchetto costruito {} arch.checking.conflicts=Verifica di eventuali conflitti con {} diff --git a/bauh/gems/arch/resources/locale/pt b/bauh/gems/arch/resources/locale/pt index 266da512..b38003fa 100644 --- a/bauh/gems/arch/resources/locale/pt +++ b/bauh/gems/arch/resources/locale/pt @@ -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 {deps} dependências devem ser instaladas antes de continuar com a instalação de {name} +arch.missing_deps.body=As seguintes {deps} dependências devem ser instaladas para que a instalação de {name} continue arch.downgrade.error=Erro arch.downgrade.impossible=Não é possível reverter a versão de {} aur.history.1_version=versão @@ -44,7 +44,8 @@ aur.history.2_release=lançamento aur.history.3_date=data arch.downloading.package=Baixando o pacote arch.uncompressing.package=Descompactando o pacote -arch.checking.deps=Checando as dependências de {} +arch.checking.deps=Verificando as dependências de {} +arch.checking.missing_deps=Verificando dependências ausentes de {} arch.missing_deps_found=Dependencias ausentes para {} arch.building.package=Construindo o pacote {} arch.checking.conflicts=Verificando se há conflitos com {} diff --git a/bauh/view/qt/confirmation.py b/bauh/view/qt/confirmation.py index b169f68d..11b2f501 100644 --- a/bauh/view/qt/confirmation.py +++ b/bauh/view/qt/confirmation.py @@ -49,10 +49,7 @@ def __init__(self, title: str, body: str, i18n: I18n, screen_size: QSize, compo height += inst.sizeHint().height() comps_container.layout().addWidget(inst) - height = height if height < screen_size.height() / 2 else height / 2 - - if height < 100: - height = 100 + height = height if height < int(screen_size.height() / 2.5) else int(screen_size.height() / 2.5) scroll.setFixedHeight(height) self.layout().addWidget(scroll, 1, 1) From cd3906c2c65e2458c4ffec87f7cb211018e471d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Mon, 9 Dec 2019 11:54:39 -0300 Subject: [PATCH 10/13] '--clean' renamed to '--reset' --- CHANGELOG.md | 1 + README.md | 5 ++++- bauh/app.py | 2 +- bauh/app_args.py | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4339b03..da68dcea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - retrieving and displaying all transitive required dependencies ( it can be disabled via the new environment variable **BAUH_ARCH_CHECK_SUBDEPS=0** ) - displaying **makedepends** and **checkdepends** in the info window - Some AUR labels have been changed to not confuse the user +- **--clean** para renamed to **--reset** - Minor UI improvements ### Fixes diff --git a/README.md b/README.md index 102ad4fe..428099c2 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,10 @@ Icon=/home/$USER/bauh_env/lib/python3.7/site-packages/bauh/view/resources/img/lo In order to autostart the application, use your Desktop Environment settings to register it as a startup application / script (**bauh --tray=1**). ### Uninstallation -Before uninstalling bauh via your package manager, consider executing `bauh --clean` to remove configuration and cache files stored in your **HOME** folder. +Before uninstalling bauh via your package manager, consider executing `bauh --reset` to remove configuration and cache files stored in your **HOME** folder. + +### Theme issues +If bauh is not starting properly after changing its style, execute `bauh --reset` to reset its configuration or just delete the **style** key from the file **~/.config/bauh/config.json**. ### Gems ( package technology support ) #### Flatpak ( flatpak ) diff --git a/bauh/app.py b/bauh/app.py index 25a5ce61..cdce29fd 100755 --- a/bauh/app.py +++ b/bauh/app.py @@ -29,7 +29,7 @@ def main(): logger = logs.new_logger(__app_name__, bool(args.logs)) app_args.validate(args, logger) - if args.clean: + if args.reset: util.clean_app_files() exit(0) diff --git a/bauh/app_args.py b/bauh/app_args.py index 8e551f1c..83d8cae3 100644 --- a/bauh/app_args.py +++ b/bauh/app_args.py @@ -36,7 +36,7 @@ def read() -> Namespace: parser.add_argument('--logs', action="store", default=int(os.getenv('BAUH_LOGS', 0)), choices=[0, 1], type=int, help='If the application logs should be displayed. Default: %(default)s') parser.add_argument('--show-panel', action="store_true", help='Shows the management panel after the app icon is attached to the tray.') parser.add_argument('-dmt', '--download-mthread', action="store", default=os.getenv('BAUH_DOWNLOAD_MULTITHREAD', 1), choices=[0, 1], type=int, help='If installation files should be downloaded using multi-threads (only possible if aria2c is installed). Not all gems support this feature. Check README.md. Default: %(default)s') - parser.add_argument('--clean', action="store_true", help='Removes all configuration and cache files') + parser.add_argument('--reset', action="store_true", help='Removes all configuration and cache files') return parser.parse_args() From b64e7996942eba2615bd23cc449d183ba808fbe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Mon, 9 Dec 2019 12:17:42 -0300 Subject: [PATCH 11/13] [improvement][info] full field text area as readonly --- bauh/view/qt/info.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bauh/view/qt/info.py b/bauh/view/qt/info.py index 1a19011a..b101df89 100644 --- a/bauh/view/qt/info.py +++ b/bauh/view/qt/info.py @@ -28,6 +28,7 @@ def __init__(self, app: dict, icon_cache: MemoryCache, i18n: I18n, screen_size: # shows complete field string self.text_field = QPlainTextEdit() + self.text_field.setReadOnly(True) self.layout().addWidget(self.text_field) self.text_field.hide() From e25eaafb13a1174cc5e5138efc823b8c923672e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Mon, 9 Dec 2019 13:01:52 -0300 Subject: [PATCH 12/13] Updating CHANGELOG and README --- CHANGELOG.md | 6 +++--- README.md | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da68dcea..ea4cfb87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,19 +4,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.7.4] 2019-12 +## [0.7.4] 2019-12-09 ### Improvements - AUR: - retrieving and displaying all transitive required dependencies ( it can be disabled via the new environment variable **BAUH_ARCH_CHECK_SUBDEPS=0** ) - displaying **makedepends** and **checkdepends** in the info window - Some AUR labels have been changed to not confuse the user -- **--clean** para renamed to **--reset** +- **--clean** para renamed to **--reset** - Minor UI improvements ### Fixes - AUR: - not finding some dependencies declared as files instead of the package names (e.g: dolphin-emu-git ) - - replaces the wrong term **mirror** by **repository** + - replaces the term **mirror** by **repository** ## [0.7.3] 2019-11-29 diff --git a/README.md b/README.md index 428099c2..073b94c0 100644 --- a/README.md +++ b/README.md @@ -129,8 +129,7 @@ will be pre-downloaded faster ( it does **NOT** modify your **pacman** settings ( For more information about these optimizations, have a look at [Makepkg](https://wiki.archlinux.org/index.php/Makepkg) ) - Arch package memory-indexer running every 20 minutes. This memory index is used when AUR Api cannot handle the amount of results found for a given search. It can be disabled via the environment variable **BAUH_ARCH_AUR_INDEX_UPDATER=0**. - If some of your installed packages are not categorized, send an e-mail to **bauh4linux@gmail.com** informing their names and categories in the following format: ```name=category1[,category2,category3,...]``` -- Transitive dependencies checking can be disabled through the environment variable **BAUH_ARCH_CHECK_SUBDEPS=0**. The dependency checking process will be -faster, but the application will ask for a new confirmation every time a not installed dependency is detected. +- Transitive dependencies checking can be disabled through the environment variable **BAUH_ARCH_CHECK_SUBDEPS=0**. The dependency checking process will be faster, but the application will ask for a confirmation every time a not installed dependency is detected. ### General settings You can change some application settings via environment variables or arguments (type ```bauh --help``` to get more information). From 5914511d9378a0eb83348f1d49b377bfca773070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Mon, 9 Dec 2019 14:11:06 -0300 Subject: [PATCH 13/13] Updating CHANGELOG.md --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea4cfb87..c1f08a6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,15 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [0.7.4] 2019-12-09 ### Improvements -- AUR: +- AUR - retrieving and displaying all transitive required dependencies ( it can be disabled via the new environment variable **BAUH_ARCH_CHECK_SUBDEPS=0** ) - displaying **makedepends** and **checkdepends** in the info window - Some AUR labels have been changed to not confuse the user -- **--clean** para renamed to **--reset** +- **--clean** param renamed to **--reset** - Minor UI improvements ### Fixes -- AUR: +- AUR - not finding some dependencies declared as files instead of the package names (e.g: dolphin-emu-git ) - replaces the term **mirror** by **repository**