mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 02:24:16 +02:00
[improvement][arch] able to handle upgrade scenarios when a package wants to overwrite files of another installed package
This commit is contained in:
@@ -21,7 +21,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
|
||||
ViewComponent, PanelComponent, MultipleSelectComponent, TextInputComponent, TextComponent
|
||||
from bauh.api.constants import TEMP_DIR
|
||||
from bauh.commons import user
|
||||
from bauh.commons.category import CategoriesDownloader
|
||||
@@ -189,6 +189,7 @@ class ArchManager(SoftwareManager):
|
||||
manager=self)
|
||||
}
|
||||
self.index_aur = None
|
||||
self.re_file_conflict = re.compile(r'[\w\d\-_.]+:')
|
||||
|
||||
@staticmethod
|
||||
def get_semantic_search_map() -> Dict[str, str]:
|
||||
@@ -690,6 +691,66 @@ class ArchManager(SoftwareManager):
|
||||
|
||||
return False
|
||||
|
||||
def _map_conflicting_file(self, output: str) -> List[TextComponent]:
|
||||
error_idx = None
|
||||
lines = output.split('\n')
|
||||
for idx, l in enumerate(lines):
|
||||
if l and l.strip().lower().startswith('error: failed to commit transaction (conflicting files)'):
|
||||
error_idx = idx
|
||||
break
|
||||
|
||||
files = []
|
||||
|
||||
if error_idx and error_idx + 1 < len(lines):
|
||||
for idx in range(error_idx + 1, len(lines)):
|
||||
line = lines[idx].strip()
|
||||
|
||||
if line and self.re_file_conflict.match(line):
|
||||
files.append(TextComponent(' - {}'.format(line)))
|
||||
|
||||
return files
|
||||
|
||||
def _upgrade_repo_pkgs(self, pkgs: List[str], handler: ProcessHandler, root_password: str, overwrite_files: bool = False) -> bool:
|
||||
try:
|
||||
output_handler = TransactionStatusHandler(handler.watcher, self.i18n, len(pkgs), self.logger)
|
||||
output_handler.start()
|
||||
success, upgrade_output = handler.handle_simple(pacman.upgrade_several(pkgnames=pkgs,
|
||||
root_password=root_password,
|
||||
overwrite_conflicting_files=overwrite_files),
|
||||
output_handler=output_handler.handle,)
|
||||
output_handler.stop_working()
|
||||
output_handler.join()
|
||||
|
||||
handler.watcher.change_substatus('')
|
||||
|
||||
if success:
|
||||
handler.watcher.print("Repository packages successfully upgraded")
|
||||
handler.watcher.change_substatus(self.i18n['arch.upgrade.caching_pkgs_data'])
|
||||
repo_map = pacman.map_repositories(pkgs)
|
||||
disk.save_several(pkgs, repo_map=repo_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):
|
||||
|
||||
return self._upgrade_repo_pkgs(pkgs=pkgs, handler=handler, root_password=root_password, overwrite_files=True)
|
||||
else:
|
||||
handler.watcher.print("Aborted by the user")
|
||||
return False
|
||||
else:
|
||||
self.logger.error("'pacman' returned an unexpected response or error phrase after upgrading the repository packages")
|
||||
return False
|
||||
except:
|
||||
handler.watcher.change_substatus('')
|
||||
handler.watcher.print("An error occurred while upgrading repository packages")
|
||||
self.logger.error("An error occurred while upgrading repository packages")
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def upgrade(self, requirements: UpgradeRequirements, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
self.aur_client.clean_caches()
|
||||
watcher.change_status("{}...".format(self.i18n['manage_window.status.upgrading']))
|
||||
@@ -733,29 +794,7 @@ class ArchManager(SoftwareManager):
|
||||
self.logger.info("Upgrading {} repository packages: {}".format(len(repo_pkgs_names),
|
||||
', '.join(repo_pkgs_names)))
|
||||
|
||||
try:
|
||||
output_handler = TransactionStatusHandler(watcher, self.i18n, len(repo_pkgs_names), self.logger)
|
||||
output_handler.start()
|
||||
success, _ = handler.handle_simple(pacman.upgrade_several(repo_pkgs_names, root_password), output_handler=output_handler.handle)
|
||||
output_handler.stop_working()
|
||||
output_handler.join()
|
||||
|
||||
watcher.change_substatus('')
|
||||
|
||||
if success:
|
||||
watcher.print("Repository packages successfully upgraded")
|
||||
watcher.change_substatus(self.i18n['arch.upgrade.caching_pkgs_data'])
|
||||
repo_map = pacman.map_repositories(repo_pkgs_names)
|
||||
disk.save_several(repo_pkgs_names, repo_map=repo_map, overwrite=True, maintainer=None)
|
||||
|
||||
else:
|
||||
self.logger.error("'pacman' returned an unexpected response or error phrase after upgrading the repository packages")
|
||||
return False
|
||||
except:
|
||||
watcher.change_substatus('')
|
||||
watcher.print("An error occurred while upgrading repository packages")
|
||||
self.logger.error("An error occurred while upgrading repository packages")
|
||||
traceback.print_exc()
|
||||
if not self._upgrade_repo_pkgs(pkgs=repo_pkgs_names, handler=handler, root_password=root_password):
|
||||
return False
|
||||
|
||||
watcher.change_status('{}...'.format(self.i18n['arch.upgrade.upgrade_aur_pkgs']))
|
||||
|
||||
@@ -144,7 +144,7 @@ def install_as_process(pkgpaths: Iterable[str], root_password: str, file: bool,
|
||||
return SimpleProcess(cmd=cmd,
|
||||
root_password=root_password,
|
||||
cwd=pkgdir,
|
||||
error_phrases={"error: failed to prepare transaction", 'error: failed to commit transaction'})
|
||||
error_phrases={"error: failed to prepare transaction", 'error: failed to commit transaction', 'error: target not found'})
|
||||
|
||||
|
||||
def list_desktop_entries(pkgnames: Set[str]) -> List[str]:
|
||||
@@ -693,10 +693,15 @@ def list_installed_names() -> Set[str]:
|
||||
return {p for p in run_cmd('pacman -Qq').split('\n') if p}
|
||||
|
||||
|
||||
def upgrade_several(pkgnames: Iterable[str], root_password: str) -> SimpleProcess:
|
||||
return SimpleProcess(cmd=['pacman', '-S', *pkgnames, '--noconfirm'],
|
||||
def upgrade_several(pkgnames: Iterable[str], root_password: str, overwrite_conflicting_files: bool = False) -> SimpleProcess:
|
||||
cmd = ['pacman', '-S', *pkgnames, '--noconfirm']
|
||||
|
||||
if overwrite_conflicting_files:
|
||||
cmd.append('--overwrite=*')
|
||||
|
||||
return SimpleProcess(cmd=cmd,
|
||||
root_password=root_password,
|
||||
error_phrases={'error: failed to prepare transaction', 'error: failed to commit transaction'})
|
||||
error_phrases={'error: failed to prepare transaction', 'error: failed to commit transaction', 'error: target not found'})
|
||||
|
||||
|
||||
def remove_several(pkgnames: Iterable[str], root_password: str) -> SystemProcess:
|
||||
|
||||
@@ -188,6 +188,9 @@ arch.update_summary.to_install.dep_conflict=Conflict between the dependencies {}
|
||||
arch.update_summary.to_update.conflicts_dep=Conflicts with the dependency {} of {}
|
||||
arch.update_summary.to_update.dep_conflicts=Dependency {} conflicts with {}
|
||||
arch.upgrade.caching_pkgs_data=Caching upgrades data
|
||||
arch.upgrade.error.conflicting_files=Some of the packages being upgraded want to overwrite files of another installed packages
|
||||
arch.upgrade.conflicting_files.proceed=Allow and continue
|
||||
arch.upgrade.conflicting_files.stop=Cancel upgrading
|
||||
arch.upgrade.fail=Package {} upgrade failed
|
||||
arch.upgrade.success=Package {} successfully upgraded
|
||||
arch.upgrade.upgrade_aur_pkgs=Upgrading AUR packages
|
||||
|
||||
@@ -188,6 +188,9 @@ arch.update_summary.to_install.dep_conflict=Conflict between the dependencies {}
|
||||
arch.update_summary.to_update.conflicts_dep=Conflicts with the dependency {} of {}
|
||||
arch.update_summary.to_update.dep_conflicts=Dependency {} conflicts with {}
|
||||
arch.upgrade.caching_pkgs_data=Caching upgrades data
|
||||
arch.upgrade.error.conflicting_files=Some of the packages being upgraded want to overwrite files of another installed packages
|
||||
arch.upgrade.conflicting_files.proceed=Allow and continue
|
||||
arch.upgrade.conflicting_files.stop=Cancel upgrading
|
||||
arch.upgrade.fail=Package {} upgrade failed
|
||||
arch.upgrade.success=Package {} successfully upgraded
|
||||
arch.upgrade.upgrade_aur_pkgs=Upgrading AUR packages
|
||||
|
||||
@@ -188,6 +188,9 @@ arch.update_summary.to_install.dep_conflict=Conflict between the dependencies {}
|
||||
arch.update_summary.to_update.conflicts_dep=Conflicts with the dependency {} of {}
|
||||
arch.update_summary.to_update.dep_conflicts=Dependency {} conflicts with {}
|
||||
arch.upgrade.caching_pkgs_data=Caching upgrades data
|
||||
arch.upgrade.error.conflicting_files=Some of the packages being upgraded want to overwrite files of another installed packages
|
||||
arch.upgrade.conflicting_files.proceed=Allow and continue
|
||||
arch.upgrade.conflicting_files.stop=Cancel upgrading
|
||||
arch.upgrade.fail=Package {} upgrade failed
|
||||
arch.upgrade.success=Package {} successfully upgraded
|
||||
arch.upgrade.upgrade_aur_pkgs=Upgrading AUR packages
|
||||
|
||||
@@ -188,6 +188,9 @@ arch.update_summary.to_install.dep_conflict=Conflicto entre las dependencias {}
|
||||
arch.update_summary.to_update.conflicts_dep=Conflicta con la dependencia {} de {}
|
||||
arch.update_summary.to_update.dep_conflicts=La dependencia {} conflicta con {}
|
||||
arch.upgrade.caching_pkgs_data=Caching upgrades data
|
||||
arch.upgrade.error.conflicting_files=Algunos de los paquetes que se están actualizando desean sobrescribir archivos de otros paquetes instalados
|
||||
arch.upgrade.conflicting_files.proceed=Permitir y continuar
|
||||
arch.upgrade.conflicting_files.stop=Cancelar la actualización
|
||||
arch.upgrade.fail=Falló la actualización del paquete {}
|
||||
arch.upgrade.success=Paquete {} actualizado con éxito
|
||||
arch.upgrade.upgrade_aur_pkgs=Actualizando paquetes de AUR
|
||||
|
||||
@@ -188,6 +188,9 @@ arch.update_summary.to_install.dep_conflict=Conflict between the dependencies {}
|
||||
arch.update_summary.to_update.conflicts_dep=Conflicts with the dependency {} of {}
|
||||
arch.update_summary.to_update.dep_conflicts=Dependency {} conflicts with {}
|
||||
arch.upgrade.caching_pkgs_data=Caching upgrades data
|
||||
arch.upgrade.error.conflicting_files=Some of the packages being upgraded want to overwrite files of another installed packages
|
||||
arch.upgrade.conflicting_files.proceed=Allow and continue
|
||||
arch.upgrade.conflicting_files.stop=Cancel upgrading
|
||||
arch.upgrade.fail=Package {} upgrade failed
|
||||
arch.upgrade.success=Package {} successfully upgraded
|
||||
arch.upgrade.upgrade_aur_pkgs=Upgrading AUR packages
|
||||
|
||||
@@ -188,6 +188,9 @@ arch.update_summary.to_install.dep_conflict=Conflito entre as dependências {} e
|
||||
arch.update_summary.to_update.conflicts_dep=Conflita com a dependência {} de {}
|
||||
arch.update_summary.to_update.dep_conflicts=A dependência {} conflita com {}
|
||||
arch.upgrade.caching_pkgs_data=Armazenando dados das atualizações
|
||||
arch.upgrade.error.conflicting_files=Alguns dos pacotes que estão sendo atualizados querem sobrepor arquivos de outros pacotes instalados
|
||||
arch.upgrade.conflicting_files.proceed=Permitir e continuar
|
||||
arch.upgrade.conflicting_files.stop=Cancelar atualização
|
||||
arch.upgrade.fail=Atualização do pacote {} falhou
|
||||
arch.upgrade.success=Pacote {} atualizado com sucesso
|
||||
arch.upgrade.upgrade_aur_pkgs=Atualizando pacotes do AUR
|
||||
|
||||
@@ -188,6 +188,9 @@ arch.update_summary.to_install.dep_conflict=Конфликт между зави
|
||||
arch.update_summary.to_update.conflicts_dep=Конфликты с зависимостью {} от {}
|
||||
arch.update_summary.to_update.dep_conflicts=Зависимость {} конфликтует с {}
|
||||
arch.upgrade.caching_pkgs_data=Caching upgrades data
|
||||
arch.upgrade.error.conflicting_files=Some of the packages being upgraded want to overwrite files of another installed packages
|
||||
arch.upgrade.conflicting_files.proceed=Allow and continue
|
||||
arch.upgrade.conflicting_files.stop=Cancel upgrading
|
||||
arch.upgrade.fail=Package {} upgrade failed
|
||||
arch.upgrade.success=Package {} successfully upgraded
|
||||
arch.upgrade.upgrade_aur_pkgs=Upgrading AUR packages
|
||||
|
||||
@@ -188,6 +188,9 @@ arch.update_summary.to_install.dep_conflict={} ve {} bağımlılıkları arasın
|
||||
arch.update_summary.to_update.conflicts_dep={} / {} bağımlılığıyla ilgili çakışmalar
|
||||
arch.update_summary.to_update.dep_conflicts=Bağımlılık {} ile {} çakışıyor
|
||||
arch.upgrade.caching_pkgs_data=Yükseltme verileri önbelleğe alınıyor
|
||||
arch.upgrade.error.conflicting_files=Some of the packages being upgraded want to overwrite files of another installed packages
|
||||
arch.upgrade.conflicting_files.proceed=Allow and continue
|
||||
arch.upgrade.conflicting_files.stop=Cancel upgrading
|
||||
arch.upgrade.fail={} paketi yükseltilemedi
|
||||
arch.upgrade.success={} paketi başarıyla yükseltildi
|
||||
arch.upgrade.upgrade_aur_pkgs=AUR paketleri yükseltiliyor
|
||||
|
||||
Reference in New Issue
Block a user