diff --git a/CHANGELOG.md b/CHANGELOG.md index 3737e3e8..3ef7aad0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - not displaying all packages that must be uninstalled - displaying "required size" for packages that must be uninstalled - some conflict resolution scenarios when upgrading several packages + - not handling conflicting files errors during the installation process - AUR - info dialog of installed packages displays the latest PKGBUILD file instead of the one used for installation/upgrade/downgrade (the fix will only work for new installed packages) - multi-threaded download: not retrieving correctly some source files URLs (e.g: linux-xanmod-lts) diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 15555b09..167178dd 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -22,7 +22,7 @@ from bauh.api.abstract.handler import ProcessWatcher, TaskManager from bauh.api.abstract.model import PackageUpdate, PackageHistory, SoftwarePackage, PackageSuggestion, PackageStatus, \ SuggestionPriority, CustomSoftwareAction from bauh.api.abstract.view import MessageType, FormComponent, InputOption, SingleSelectComponent, SelectViewType, \ - ViewComponent, PanelComponent, MultipleSelectComponent, TextInputComponent, TextComponent, TextInputType, \ + ViewComponent, PanelComponent, MultipleSelectComponent, TextInputComponent, TextInputType, \ FileChooserComponent from bauh.api.constants import TEMP_DIR from bauh.commons import user, internet, system @@ -767,7 +767,7 @@ class ArchManager(SoftwareManager): return False - def _map_conflicting_file(self, output: str) -> List[TextComponent]: + def _map_conflicting_file(self, output: str) -> List[MultipleSelectComponent]: error_idx = None lines = output.split('\n') for idx, l in enumerate(lines): @@ -782,9 +782,9 @@ class ArchManager(SoftwareManager): line = lines[idx].strip() if line and self.re_file_conflict.match(line): - files.append(TextComponent(' - {}'.format(line))) + files.append(InputOption(label=line, value=idx, read_only=True)) - return files + return [MultipleSelectComponent(options=files, default_options={*files}, label='')] def list_related(self, pkgs: Iterable[str], all_pkgs: Iterable[str], data: Dict[str, dict], related: Set[str], provided_map: Dict[str, Set[str]]) -> Set[str]: related.update(pkgs) @@ -896,12 +896,11 @@ class ArchManager(SoftwareManager): disk.write_several(pkgs=pkg_map, overwrite=True, maintainer=None) return True elif 'conflicting files' in upgrade_output: - files = self._map_conflicting_file(upgrade_output) if not handler.watcher.request_confirmation(title=self.i18n['warning'].capitalize(), body=self.i18n['arch.upgrade.error.conflicting_files'] + ':', deny_label=self.i18n['arch.upgrade.conflicting_files.proceed'], confirmation_label=self.i18n['arch.upgrade.conflicting_files.stop'], - components=files): + components=self._map_conflicting_file(upgrade_output)): return self._upgrade_repo_pkgs(to_upgrade=to_upgrade_remaining, handler=handler, @@ -2030,11 +2029,8 @@ class ArchManager(SoftwareManager): installed_with_same_name = self.read_installed(disk_loader=context.disk_loader, internet_available=True, names={context.name}).installed context.watcher.change_substatus(self.i18n['arch.installing.package'].format(bold(context.name))) - installed, _ = context.handler.handle_simple(pacman.install_as_process(pkgpaths=to_install, - root_password=context.root_password, - file=context.has_install_file(), - pkgdir=context.project_dir), - output_handler=status_handler.handle if status_handler else None) + installed = self._handle_install_call(context=context, to_install=to_install, status_handler=status_handler) + if status_handler: status_handler.stop_working() status_handler.join() @@ -2092,6 +2088,29 @@ class ArchManager(SoftwareManager): return installed + def _call_pacman_install(self, context: TransactionContext, to_install: List[str], overwrite_files: bool, status_handler: Optional[object] = None) -> Tuple[bool, str]: + return context.handler.handle_simple(pacman.install_as_process(pkgpaths=to_install, + root_password=context.root_password, + file=context.has_install_file(), + pkgdir=context.project_dir, + overwrite_conflicting_files=overwrite_files), + output_handler=status_handler.handle if status_handler else None) + + def _handle_install_call(self, context: TransactionContext, to_install: List[str], status_handler) -> bool: + installed, output = self._call_pacman_install(context=context, to_install=to_install, + overwrite_files=False, status_handler=status_handler) + + if not installed and 'conflicting files' in output: + if not context.handler.watcher.request_confirmation(title=self.i18n['warning'].capitalize(), + body=self.i18n['arch.install.error.conflicting_files'].format(bold(context.name)) + ':', + deny_label=self.i18n['arch.install.error.conflicting_files.proceed'], + confirmation_label=self.i18n['arch.install.error.conflicting_files.stop'], + components=self._map_conflicting_file(output)): + installed, output = self._call_pacman_install(context=context, to_install=to_install, + overwrite_files=True, status_handler=status_handler) + + return installed + def _update_progress(self, context: TransactionContext, val: int): if context.change_progress: context.watcher.change_progress(val) diff --git a/bauh/gems/arch/pacman.py b/bauh/gems/arch/pacman.py index 8c5e46ec..bc247590 100644 --- a/bauh/gems/arch/pacman.py +++ b/bauh/gems/arch/pacman.py @@ -141,12 +141,15 @@ def map_installed(names: Iterable[str] = None) -> dict: # returns a dict with w return pkgs -def install_as_process(pkgpaths: Iterable[str], root_password: str, file: bool, pkgdir: str = '.') -> SimpleProcess: +def install_as_process(pkgpaths: Iterable[str], root_password: str, file: bool, pkgdir: str = '.', overwrite_conflicting_files: bool = False) -> SimpleProcess: if file: cmd = ['pacman', '-U', *pkgpaths, '--noconfirm'] # pkgpath = install file path else: cmd = ['pacman', '-S', *pkgpaths, '--noconfirm'] # pkgpath = pkgname + if overwrite_conflicting_files: + cmd.append('--overwrite=*') + return SimpleProcess(cmd=cmd, root_password=root_password, cwd=pkgdir, diff --git a/bauh/gems/arch/resources/locale/ca b/bauh/gems/arch/resources/locale/ca index af2a376d..8ac03378 100644 --- a/bauh/gems/arch/resources/locale/ca +++ b/bauh/gems/arch/resources/locale/ca @@ -166,6 +166,9 @@ arch.install.dep_not_found.body.l3=S’ha cancel·lat la instal·lació. arch.install.dep_not_found.title=No s’ha trobat la dependència arch.install.dependency.install=S’està instal·lant el paquet depenent {} arch.install.dependency.install.error=Could not install the dependent packages: {}. Installation of {} aborted. +arch.install.error.conflicting_files=The package {} wants to overwrite files from other installed packages +arch.install.error.conflicting_files.proceed=Allow +arch.install.error.conflicting_files.stop=Cancel installation arch.install.optdep.error=Could not install the optional packages: {} 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 diff --git a/bauh/gems/arch/resources/locale/de b/bauh/gems/arch/resources/locale/de index 1c7f7d6a..f9a0a0d5 100644 --- a/bauh/gems/arch/resources/locale/de +++ b/bauh/gems/arch/resources/locale/de @@ -166,6 +166,9 @@ arch.install.dep_not_found.body.l3=Installation abgebrochen. arch.install.dep_not_found.title=Abhängigkeit nicht gefunden arch.install.dependency.install=Abhängigket {} wird installiert arch.install.dependency.install.error=Could not install the dependent packages: {}. Installation of {} aborted. +arch.install.error.conflicting_files=The package {} wants to overwrite files from other installed packages +arch.install.error.conflicting_files.proceed=Allow +arch.install.error.conflicting_files.stop=Cancel installation arch.install.optdep.error=Could not install the optional packages: {} arch.install.optdeps.request.body={} wurde erfolgreich installiert! Es gibt optionale zugehörige Pakete welche du vielleicht auch installieren möchtest arch.install.optdeps.request.help=Wähle entsprechende aus diff --git a/bauh/gems/arch/resources/locale/en b/bauh/gems/arch/resources/locale/en index 6568b0d3..64d76b21 100644 --- a/bauh/gems/arch/resources/locale/en +++ b/bauh/gems/arch/resources/locale/en @@ -167,6 +167,9 @@ arch.install.dep_not_found.body.l3=Installation cancelled. arch.install.dep_not_found.title=Dependency not found arch.install.dependency.install=Installing package dependency {} arch.install.dependency.install.error=Could not install the dependent packages: {}. Installation of {} aborted. +arch.install.error.conflicting_files=The package {} wants to overwrite files from other installed packages +arch.install.error.conflicting_files.proceed=Allow +arch.install.error.conflicting_files.stop=Cancel installation arch.install.optdep.error=Could not install the optional packages: {} arch.install.optdeps.request.body={} was succesfully installed ! There are some optional associated packages that you might want to install arch.install.optdeps.request.help=Check those you want diff --git a/bauh/gems/arch/resources/locale/es b/bauh/gems/arch/resources/locale/es index 7b992848..99d6f2bb 100644 --- a/bauh/gems/arch/resources/locale/es +++ b/bauh/gems/arch/resources/locale/es @@ -166,6 +166,9 @@ arch.install.dep_not_found.body.l3=Instalación cancelada. arch.install.dep_not_found.title=Dependencia no encontrada arch.install.dependency.install=Instalando el paquete dependiente {} arch.install.dependency.install.error=No se pudo instalar los paquetes dependientes: {}. Instalación de {} abortada. +arch.install.error.conflicting_files=El paquete {} quiere sobrescribir archivos de otros paquetes instalados +arch.install.error.conflicting_files.proceed=Permitir +arch.install.error.conflicting_files.stop=Cancelar instalación arch.install.optdep.error=No se pudo instalar los paquetes opcionales: {} arch.install.optdeps.request.body=¡{} se instaló correctamente! Hay algunos paquetes opcionales asociados que es posible que desee instalar arch.install.optdeps.request.help=Marque los que desee diff --git a/bauh/gems/arch/resources/locale/it b/bauh/gems/arch/resources/locale/it index 7378f0c2..b17e9707 100644 --- a/bauh/gems/arch/resources/locale/it +++ b/bauh/gems/arch/resources/locale/it @@ -166,6 +166,9 @@ arch.install.dep_not_found.body.l3=Installazione annullata. arch.install.dep_not_found.title=Dipendenza non trovata arch.install.dependency.install=Installazione della dipendenza pacchetto {} arch.install.dependency.install.error=Could not install the dependent packages: {}. Installation of {} aborted. +arch.install.error.conflicting_files=The package {} wants to overwrite files from other installed packages +arch.install.error.conflicting_files.proceed=Allow +arch.install.error.conflicting_files.stop=Cancel installation arch.install.optdep.error=Could not install the optional packages: {} arch.install.optdeps.request.body={} è stato installato con successo! Ci sono alcuni pacchetti associati opzionali che potresti voler installare arch.install.optdeps.request.help=Controlla quelli che vuoi diff --git a/bauh/gems/arch/resources/locale/pt b/bauh/gems/arch/resources/locale/pt index 6d63b838..ea9b24e2 100644 --- a/bauh/gems/arch/resources/locale/pt +++ b/bauh/gems/arch/resources/locale/pt @@ -166,6 +166,9 @@ arch.install.dep_not_found.body.l3=Instalação cancelada. arch.install.dep_not_found.title=Dependência não encontrada arch.install.dependency.install=Instalando o pacote dependente {} arch.install.dependency.install.error=Não foi possível instalar os pacotes dependentes: {}. Instalação de {} abortada. +arch.install.error.conflicting_files=O pacote {} quer sobrepor alguns arquivos de outros pacotes instalados +arch.install.error.conflicting_files.proceed=Permitir +arch.install.error.conflicting_files.stop=Cancelar instalação arch.install.optdep.error=Não foi possível instalar os pacotes opcionais: {} arch.install.optdeps.request.body={} foi instalado com sucesso ! Existem alguns pacotes opcionais associados que você talvez queira instalar arch.install.optdeps.request.help=Marque os desejados diff --git a/bauh/gems/arch/resources/locale/ru b/bauh/gems/arch/resources/locale/ru index a4dbd93c..05d256e1 100644 --- a/bauh/gems/arch/resources/locale/ru +++ b/bauh/gems/arch/resources/locale/ru @@ -166,6 +166,9 @@ arch.install.dep_not_found.body.l3=Установка отменена. arch.install.dep_not_found.title=Зависимость не найдена arch.install.dependency.install=Установка зависимостей пакета {} arch.install.dependency.install.error=Could not install the dependent packages: {}. Installation of {} aborted. +arch.install.error.conflicting_files=The package {} wants to overwrite files from other installed packages +arch.install.error.conflicting_files.proceed=Allow +arch.install.error.conflicting_files.stop=Cancel installation arch.install.optdep.error=Could not install the optional packages: {} arch.install.optdeps.request.body={} успешно установлен ! Есть некоторые дополнительные связанные пакеты, которые вы можете установить arch.install.optdeps.request.help=Отметьте те, которые вы хотите установить diff --git a/bauh/gems/arch/resources/locale/tr b/bauh/gems/arch/resources/locale/tr index 86e41eff..5b52a195 100644 --- a/bauh/gems/arch/resources/locale/tr +++ b/bauh/gems/arch/resources/locale/tr @@ -166,6 +166,9 @@ arch.install.dep_not_found.body.l3=Yükleme iptal edildi. arch.install.dep_not_found.title=Bağımlılık bulunamadı arch.install.dependency.install=Paket bağımlılığını yükleniyor {} arch.install.dependency.install.error=Bağımlı paketler yüklenemedi: {}. {} Kurulumu iptal edildi. +arch.install.error.conflicting_files=The package {} wants to overwrite files from other installed packages +arch.install.error.conflicting_files.proceed=Allow +arch.install.error.conflicting_files.stop=Cancel installation arch.install.optdep.error=Tercihe bağlı paketler yüklenemedi: {} arch.install.optdeps.request.body={} başarıyla yüklendi! Yüklemek isteyebileceğiniz bazı tercihe bağlı bağımlılıklar vardır arch.install.optdeps.request.help=İstediklerinizi kontrol edin