[arch] fix -> not handling conflicting files errors during the installation process

This commit is contained in:
Vinicius Moreira
2020-08-27 11:14:00 -03:00
parent 60836643aa
commit 4d526e5488
11 changed files with 59 additions and 12 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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,

View File

@@ -166,6 +166,9 @@ arch.install.dep_not_found.body.l3=Sha cancel·lat la instal·lació.
arch.install.dep_not_found.title=No sha trobat la dependència
arch.install.dependency.install=Sestà 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={} sha instal·lat correctament. Hi ha paquets opcionals associats que potser voldreu instal·lar
arch.install.optdeps.request.help=Marqueu els que voleu

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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=Отметьте те, которые вы хотите установить

View File

@@ -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