[arch] improvement -> upgrade: checking specific version requirements and marking packages as 'cannot upgrade' when these requirements are not met

This commit is contained in:
Vinicius Moreira
2020-09-01 19:36:05 -03:00
parent d7225dab3b
commit feb061efa4
18 changed files with 286 additions and 43 deletions

View File

@@ -37,9 +37,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- only removing packages after downloading the required ones - only removing packages after downloading the required ones
- summary: displaying the reason a given package must be installed - summary: displaying the reason a given package must be installed
<p align="center"> <p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/arch_install_reason.png"> <img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/arch_install_reason.png">
</p> </p>
- checking specific version requirements and marking packages as "cannot upgrade" when these requirements are not met (e.g: package A depends on version 1.0 of B. If A and B were selected to upgrade, and B would be upgrade to 2.0, then B would be excluded from the transaction. This new checking behavior can be disabled through the property (**check_dependency_breakage**):
<p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/arch_dep_break_settings.png">
</p>
- AUR - AUR
- caching the PKGBUILD file used for the package installation/upgrade/downgrade (**~/.cache/bauh/arch/installed/$pkgname/PKGBUILD**) - caching the PKGBUILD file used for the package installation/upgrade/downgrade (**~/.cache/bauh/arch/installed/$pkgname/PKGBUILD**)
- new settings property **aur_build_dir** -> it allows to define a custom build dir. - new settings property **aur_build_dir** -> it allows to define a custom build dir.
@@ -77,6 +82,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- upgrade summary - upgrade summary
- not displaying all packages that must be uninstalled - not displaying all packages that must be uninstalled
- displaying "required size" for packages that must be uninstalled - displaying "required size" for packages that must be uninstalled
- not displaying packages that cannot upgrade due to specific version requirements (e.g: package A requires version 1.0 of package B, however package B will be upgrade to version 2.0)
<p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/arch_dep_break.png">
</p>
- some conflict resolution scenarios when upgrading several packages - some conflict resolution scenarios when upgrading several packages
- not handling conflicting files errors during the installation process - not handling conflicting files errors during the installation process
- AUR - AUR

View File

@@ -197,6 +197,7 @@ edit_aur_pkgbuild: false # if the AUR PKGBUILD file should be displayed for edi
aur_build_dir: null # defines a custom build directory for AUR packages (a null value will point to /tmp/bauh/arch (non-root user) or /tmp/bauh_root/arch (root user)). Default: null. aur_build_dir: null # defines a custom build directory for AUR packages (a null value will point to /tmp/bauh/arch (non-root user) or /tmp/bauh_root/arch (root user)). Default: null.
aur_remove_build_dir: true # it defines if a package's generated build directory should be removed after the operation is finished (installation, upgrading, ...). Options: true, false (default: true). aur_remove_build_dir: true # it defines if a package's generated build directory should be removed after the operation is finished (installation, upgrading, ...). Options: true, false (default: true).
aur_build_only_chosen : true # some AUR packages have a common file definition declaring several packages to be built. When this property is 'true' only the package the user select to install will be built (unless its name is different from those declared in the PKGBUILD base). With a 'null' value a popup asking if the user wants to build all of them will be displayed. 'false' will build and install all packages. Default: true. aur_build_only_chosen : true # some AUR packages have a common file definition declaring several packages to be built. When this property is 'true' only the package the user select to install will be built (unless its name is different from those declared in the PKGBUILD base). With a 'null' value a popup asking if the user wants to build all of them will be displayed. 'false' will build and install all packages. Default: true.
check_dependency_breakage: true # If, during the verification of the update requirements, specific versions of dependencies must also be checked. Example: package A depends on version 1.0 of B. If A and B were selected to upgrade, and B would be upgrade to 2.0, then B would be excluded from the transaction. Default: true.
``` ```
- Required dependencies: - Required dependencies:
- **pacman** - **pacman**

View File

@@ -30,18 +30,24 @@ class SearchResult:
class UpgradeRequirement: class UpgradeRequirement:
def __init__(self, pkg: SoftwarePackage, reason: str = None, required_size: int = None, extra_size: int = None): def __init__(self, pkg: SoftwarePackage, reason: str = None, required_size: int = None, extra_size: int = None, sorting_priority: int = 0):
""" """
:param pkg: :param pkg:
:param reason: :param reason:
:param required_size: size in BYTES required to upgrade the package :param required_size: size in BYTES required to upgrade the package
:param extra_size: the extra size IN BYTES the upgrade will allocate in relation to the already allocated :param extra_size: the extra size IN BYTES the upgrade will allocate in relation to the already allocated
:param sorting_priority: an int representing the sorting priority (higher numbers = higher priority)
""" """
self.pkg = pkg self.pkg = pkg
self.reason = reason self.reason = reason
self.required_size = required_size self.required_size = required_size
self.extra_size = extra_size self.extra_size = extra_size
self.sorting_priority = sorting_priority
@staticmethod
def sort_by_priority(req: "UpgradeRequirement") -> Tuple[int, str]:
return -req.sorting_priority, req.pkg.name
class UpgradeRequirements: class UpgradeRequirements:

View File

@@ -18,7 +18,8 @@ def read_config(update_file: bool = False) -> dict:
'edit_aur_pkgbuild': False, 'edit_aur_pkgbuild': False,
'aur_build_dir': None, 'aur_build_dir': None,
'aur_remove_build_dir': True, 'aur_remove_build_dir': True,
'aur_build_only_chosen': True} 'aur_build_only_chosen': True,
'check_dependency_breakage': True}
return read(CONFIG_FILE, template, update_file=update_file) return read(CONFIG_FILE, template, update_file=update_file)

View File

@@ -2554,6 +2554,11 @@ class ArchManager(SoftwareManager):
tooltip_key='arch.config.automatch_providers.tip', tooltip_key='arch.config.automatch_providers.tip',
value=bool(local_config['automatch_providers']), value=bool(local_config['automatch_providers']),
max_width=max_width), max_width=max_width),
self._gen_bool_selector(id_='check_dependency_breakage',
label_key='arch.config.check_dependency_breakage',
tooltip_key='arch.config.check_dependency_breakage.tip',
value=bool(local_config['check_dependency_breakage']),
max_width=max_width),
self._gen_bool_selector(id_='mthread_download', self._gen_bool_selector(id_='mthread_download',
label_key='arch.config.pacman_mthread_download', label_key='arch.config.pacman_mthread_download',
tooltip_key='arch.config.pacman_mthread_download.tip', tooltip_key='arch.config.pacman_mthread_download.tip',
@@ -2639,6 +2644,7 @@ class ArchManager(SoftwareManager):
config['aur_remove_build_dir'] = form_install.get_component('aur_remove_build_dir').get_selected() config['aur_remove_build_dir'] = form_install.get_component('aur_remove_build_dir').get_selected()
config['aur_build_dir'] = form_install.get_component('aur_build_dir').file_path config['aur_build_dir'] = form_install.get_component('aur_build_dir').file_path
config['aur_build_only_chosen'] = form_install.get_component('aur_build_only_chosen').get_selected() config['aur_build_only_chosen'] = form_install.get_component('aur_build_only_chosen').get_selected()
config['check_dependency_breakage'] = form_install.get_component('check_dependency_breakage').get_selected()
if not config['aur_build_dir']: if not config['aur_build_dir']:
config['aur_build_dir'] = None config['aur_build_dir'] = None

View File

@@ -180,3 +180,8 @@ class ArchPackage(SoftwarePackage):
else: else:
return ACTIONS_AUR_ENABLE_PKGBUILD_EDITION return ACTIONS_AUR_ENABLE_PKGBUILD_EDITION
def __hash__(self):
if self.view_name is not None:
return hash((self.view_name, self.repository))
else:
return hash((self.name, self.repository))

View File

@@ -914,8 +914,8 @@ def get_cache_dir() -> str:
return '/var/cache/pacman/pkg' return '/var/cache/pacman/pkg'
def map_required_by(names: Iterable[str] = None) -> Dict[str, Set[str]]: def map_required_by(names: Iterable[str] = None, remote: bool = False) -> Dict[str, Set[str]]:
output = run_cmd('pacman -Qi {}'.format(' '.join(names) if names else '')) output = run_cmd('pacman -{} {}'.format('Sii' if remote else 'Qi', ' '.join(names) if names else ''), print_error=False)
if output: if output:
res = {} res = {}

View File

@@ -42,6 +42,8 @@ arch.config.aur_remove_build_dir=Remove build directory (AUR)
arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished. arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished.
arch.config.clean_cache=Elimina les versions antigues arch.config.clean_cache=Elimina les versions antigues
arch.config.clean_cache.tip=Si cal eliminar les versions antigues d'un paquet emmagatzemat al disc durant la desinstal·lació arch.config.clean_cache.tip=Si cal eliminar les versions antigues d'un paquet emmagatzemat al disc durant la desinstal·lació
arch.config.check_dependency_breakage=Check dependency version breakage
arch.config.check_dependency_breakage.tip=If, during the verification of upgrade requirements, specific versions of dependencies must also be checked. Example: package A depends on version 1.0 of B.
arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR) arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR)
arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade
arch.config.mirrors_sort_limit=Mirrors sort limit arch.config.mirrors_sort_limit=Mirrors sort limit
@@ -196,6 +198,7 @@ arch.substatus.integrity=Checking packages integrity
arch.substatus.keyring=Checking keyring arch.substatus.keyring=Checking keyring
arch.substatus.loading_files=Loading package files arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync.dep_breakage.reason={} requires {}
arch.sync_databases.substatus=Synchronizing package databases arch.sync_databases.substatus=Synchronizing package databases
arch.sync_databases.substatus.error=It was not possible to synchronize the package database arch.sync_databases.substatus.error=It was not possible to synchronize the package database
arch.task.disk_cache=Indexing packages data arch.task.disk_cache=Indexing packages data

View File

@@ -42,6 +42,8 @@ arch.config.aur_remove_build_dir=Remove build directory (AUR)
arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished. arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished.
arch.config.clean_cache=Remove old versions arch.config.clean_cache=Remove old versions
arch.config.clean_cache.tip=Whether old versions of a package stored on disk should be removed during uninstall arch.config.clean_cache.tip=Whether old versions of a package stored on disk should be removed during uninstall
arch.config.check_dependency_breakage=Check dependency version breakage
arch.config.check_dependency_breakage.tip=If, during the verification of upgrade requirements, specific versions of dependencies must also be checked. Example: package A depends on version 1.0 of B.
arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR) arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR)
arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade
arch.config.mirrors_sort_limit=Mirrors sort limit arch.config.mirrors_sort_limit=Mirrors sort limit
@@ -196,6 +198,7 @@ arch.substatus.integrity=Checking packages integrity
arch.substatus.keyring=Checking keyring arch.substatus.keyring=Checking keyring
arch.substatus.loading_files=Loading package files arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync.dep_breakage.reason={} requires {}
arch.sync_databases.substatus=Synchronizing package databases arch.sync_databases.substatus=Synchronizing package databases
arch.sync_databases.substatus.error=It was not possible to synchronize the package database arch.sync_databases.substatus.error=It was not possible to synchronize the package database
arch.task.disk_cache=Indexing packages data arch.task.disk_cache=Indexing packages data

View File

@@ -43,6 +43,8 @@ arch.config.aur_remove_build_dir=Remove build directory (AUR)
arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished. arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished.
arch.config.clean_cache=Remove old versions arch.config.clean_cache=Remove old versions
arch.config.clean_cache.tip=Whether old versions of a package stored on disk should be removed during uninstall arch.config.clean_cache.tip=Whether old versions of a package stored on disk should be removed during uninstall
arch.config.check_dependency_breakage=Check dependency version breakage
arch.config.check_dependency_breakage.tip=If, during the verification of upgrade requirements, specific versions of dependencies must also be checked. Example: package A depends on version 1.0 of B.
arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR) arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR)
arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade
arch.config.mirrors_sort_limit=Mirrors sort limit arch.config.mirrors_sort_limit=Mirrors sort limit
@@ -197,6 +199,7 @@ arch.substatus.integrity=Checking packages integrity
arch.substatus.keyring=Checking keyring arch.substatus.keyring=Checking keyring
arch.substatus.loading_files=Loading package files arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync.dep_breakage.reason={} requires {}
arch.sync_databases.substatus=Synchronizing package databases arch.sync_databases.substatus=Synchronizing package databases
arch.sync_databases.substatus.error=It was not possible to synchronize the package database arch.sync_databases.substatus.error=It was not possible to synchronize the package database
arch.task.disk_cache=Indexing packages data arch.task.disk_cache=Indexing packages data

View File

@@ -42,6 +42,8 @@ arch.config.aur_remove_build_dir=Eliminar directorio de compilación (AUR)
arch.config.aur_remove_build_dir.tip=Si el directorio de compilación generado para un paquete debe ser eliminado una vez finalizada la operación. arch.config.aur_remove_build_dir.tip=Si el directorio de compilación generado para un paquete debe ser eliminado una vez finalizada la operación.
arch.config.clean_cache=Eliminar versiones antiguas arch.config.clean_cache=Eliminar versiones antiguas
arch.config.clean_cache.tip=Si las versiones antiguas de un paquete almacenado en el disco deben ser eliminadas durante la desinstalación arch.config.clean_cache.tip=Si las versiones antiguas de un paquete almacenado en el disco deben ser eliminadas durante la desinstalación
arch.config.check_dependency_breakage=Verificar rotura de versión de dependencia
arch.config.check_dependency_breakage.tip=Si, durante la verificación de los requisitos de actualización, también se deben verificar versiones específicas de las dependencias. Ejemplo: el paquete A depende de la versión 1.0 de B.
arch.config.edit_aur_pkgbuild=Editar PKGBUILD (AUR) arch.config.edit_aur_pkgbuild=Editar PKGBUILD (AUR)
arch.config.edit_aur_pkgbuild.tip=Si el archivo PKGBUILD de un paquete AUR debe ser exhibido para edición antes de su instalación/actualización/degradación arch.config.edit_aur_pkgbuild.tip=Si el archivo PKGBUILD de un paquete AUR debe ser exhibido para edición antes de su instalación/actualización/degradación
arch.config.mirrors_sort_limit=Límite de ordenación de espejos arch.config.mirrors_sort_limit=Límite de ordenación de espejos
@@ -196,6 +198,7 @@ arch.substatus.integrity=Verificando la integridad de los paquetes
arch.substatus.keyring=Verificando keyring arch.substatus.keyring=Verificando keyring
arch.substatus.loading_files=Cargando archivos de los paquetes arch.substatus.loading_files=Cargando archivos de los paquetes
arch.substatus.pre_hooks=Ejecutando ganchos pre-transacción arch.substatus.pre_hooks=Ejecutando ganchos pre-transacción
arch.sync.dep_breakage.reason={} necesita de {}
arch.sync_databases.substatus=Sincronizando bases de paquetes arch.sync_databases.substatus=Sincronizando bases de paquetes
arch.sync_databases.substatus.error=No fue posible sincronizar la base de paquetes arch.sync_databases.substatus.error=No fue posible sincronizar la base de paquetes
arch.task.disk_cache=Indexando datos de paquetes arch.task.disk_cache=Indexando datos de paquetes

View File

@@ -42,6 +42,8 @@ arch.config.aur_remove_build_dir=Remove build directory (AUR)
arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished. arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished.
arch.config.clean_cache=Rimuovi le vecchie versioni arch.config.clean_cache=Rimuovi le vecchie versioni
arch.config.clean_cache.tip=Se le vecchie versioni di un pacchetto memorizzate sul disco devono essere rimosse durante la disinstallazione arch.config.clean_cache.tip=Se le vecchie versioni di un pacchetto memorizzate sul disco devono essere rimosse durante la disinstallazione
arch.config.check_dependency_breakage=Check dependency version breakage
arch.config.check_dependency_breakage.tip=If, during the verification of upgrade requirements, specific versions of dependencies must also be checked. Example: package A depends on version 1.0 of B.
arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR) arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR)
arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade
arch.config.mirrors_sort_limit=Mirrors sort limit arch.config.mirrors_sort_limit=Mirrors sort limit
@@ -196,6 +198,7 @@ arch.substatus.integrity=Checking packages integrity
arch.substatus.keyring=Checking keyring arch.substatus.keyring=Checking keyring
arch.substatus.loading_files=Loading package files arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync.dep_breakage.reason={} requires {}
arch.sync_databases.substatus=Synchronizing package databases arch.sync_databases.substatus=Synchronizing package databases
arch.sync_databases.substatus.error=It was not possible to synchronize the package database arch.sync_databases.substatus.error=It was not possible to synchronize the package database
arch.task.disk_cache=Indexing packages data arch.task.disk_cache=Indexing packages data

View File

@@ -43,6 +43,8 @@ arch.config.aur_remove_build_dir=Remover diretório de construção (AUR)
arch.config.aur_remove_build_dir.tip=Se o diretório gerado para a construção de um pacote do AUR deve ser removido após a operação ser finalizada. arch.config.aur_remove_build_dir.tip=Se o diretório gerado para a construção de um pacote do AUR deve ser removido após a operação ser finalizada.
arch.config.clean_cache=Remover versões antigas arch.config.clean_cache=Remover versões antigas
arch.config.clean_cache.tip=Se versões antigas de um pacote armazenadas em disco devem ser removidas durante a desinstalação arch.config.clean_cache.tip=Se versões antigas de um pacote armazenadas em disco devem ser removidas durante a desinstalação
arch.config.check_dependency_breakage=Verificar quebra de dependência de versão
arch.config.check_dependency_breakage.tip=Se durante a verificação dos requisitos de atualização deve-se verificar também versões específicas de dependências. Exemplo: pacote A depende da versão 1.0 de B.
arch.config.edit_aur_pkgbuild=Editar PKGBUILD (AUR) arch.config.edit_aur_pkgbuild=Editar PKGBUILD (AUR)
arch.config.edit_aur_pkgbuild.tip=Se o arquivo PKGBUILD de um pacote do AUR deve ser exibido para edição antes da instalação/atualização/reversão arch.config.edit_aur_pkgbuild.tip=Se o arquivo PKGBUILD de um pacote do AUR deve ser exibido para edição antes da instalação/atualização/reversão
arch.config.mirrors_sort_limit=Limite de ordenação de espelhos arch.config.mirrors_sort_limit=Limite de ordenação de espelhos
@@ -196,6 +198,7 @@ arch.substatus.integrity=Verificando a integridade dos pacotes
arch.substatus.keyring=Verificando o keyring arch.substatus.keyring=Verificando o keyring
arch.substatus.loading_files=Carregando os arquivos dos pacotes arch.substatus.loading_files=Carregando os arquivos dos pacotes
arch.substatus.pre_hooks=Executando ganchos pré-transação arch.substatus.pre_hooks=Executando ganchos pré-transação
arch.sync.dep_breakage.reason={} precisa de {}
arch.sync_databases.substatus=Sincronizando bases de pacotes arch.sync_databases.substatus=Sincronizando bases de pacotes
arch.sync_databases.substatus.error=Não foi possível sincronizar as bases de pacotes arch.sync_databases.substatus.error=Não foi possível sincronizar as bases de pacotes
arch.task.disk_cache=Indexando dados de pacotes arch.task.disk_cache=Indexando dados de pacotes

View File

@@ -42,6 +42,8 @@ arch.config.aur_remove_build_dir=Remove build directory (AUR)
arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished. arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished.
arch.config.clean_cache=Remove old versions arch.config.clean_cache=Remove old versions
arch.config.clean_cache.tip=Whether old versions of a package stored on disk should be removed during uninstall arch.config.clean_cache.tip=Whether old versions of a package stored on disk should be removed during uninstall
arch.config.check_dependency_breakage=Check dependency version breakage
arch.config.check_dependency_breakage.tip=If, during the verification of upgrade requirements, specific versions of dependencies must also be checked. Example: package A depends on version 1.0 of B.
arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR) arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR)
arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade
arch.config.mirrors_sort_limit=Ограничение сортировки зеркал arch.config.mirrors_sort_limit=Ограничение сортировки зеркал
@@ -196,6 +198,7 @@ arch.substatus.integrity=Checking packages integrity
arch.substatus.keyring=Checking keyring arch.substatus.keyring=Checking keyring
arch.substatus.loading_files=Loading package files arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync.dep_breakage.reason={} requires {}
arch.sync_databases.substatus=Синхронизация баз данных пакетов arch.sync_databases.substatus=Синхронизация баз данных пакетов
arch.sync_databases.substatus.error=Синхронизировать базу данных пакета не удалось arch.sync_databases.substatus.error=Синхронизировать базу данных пакета не удалось
arch.task.disk_cache=Indexing packages data arch.task.disk_cache=Indexing packages data

View File

@@ -42,6 +42,8 @@ arch.config.aur_remove_build_dir=Remove build directory (AUR)
arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished. arch.config.aur_remove_build_dir.tip=If a package's generated build directory should be removed after the operations is finished.
arch.config.clean_cache=Önbelleği temizle arch.config.clean_cache=Önbelleği temizle
arch.config.clean_cache.tip=Disk üzerinde kurulu bir paketin eski sürümlerinin kaldırma sırasında kaldırılıp kaldırılmayacağı arch.config.clean_cache.tip=Disk üzerinde kurulu bir paketin eski sürümlerinin kaldırma sırasında kaldırılıp kaldırılmayacağı
arch.config.check_dependency_breakage=Check dependency version breakage
arch.config.check_dependency_breakage.tip=If, during the verification of upgrade requirements, specific versions of dependencies must also be checked. Example: package A depends on version 1.0 of B.
arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR) arch.config.edit_aur_pkgbuild=Edit PKGBUILD (AUR)
arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade arch.config.edit_aur_pkgbuild.tip=If the PKGBUILD file of an AUR package should be displayed for editing before its installation/upgrade/downgrade
arch.config.mirrors_sort_limit=Yansı sıralama sınırı arch.config.mirrors_sort_limit=Yansı sıralama sınırı
@@ -196,6 +198,7 @@ arch.substatus.integrity=Checking packages integrity
arch.substatus.keyring=Checking keyring arch.substatus.keyring=Checking keyring
arch.substatus.loading_files=Loading package files arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync.dep_breakage.reason={} requires {}
arch.sync_databases.substatus=Paket veritabanı eşitleniyor arch.sync_databases.substatus=Paket veritabanı eşitleniyor
arch.sync_databases.substatus.error=Paket veritabanı eşitlenemedi arch.sync_databases.substatus.error=Paket veritabanı eşitlenemedi
arch.task.disk_cache=Indexing packages data arch.task.disk_cache=Indexing packages data

View File

@@ -1,7 +1,8 @@
import logging import logging
import time import time
from distutils.version import LooseVersion
from threading import Thread from threading import Thread
from typing import Dict, Set, List, Tuple, Iterable from typing import Dict, Set, List, Tuple, Iterable, Optional
from bauh.api.abstract.controller import UpgradeRequirements, UpgradeRequirement from bauh.api.abstract.controller import UpgradeRequirements, UpgradeRequirement
from bauh.api.abstract.handler import ProcessWatcher from bauh.api.abstract.handler import ProcessWatcher
@@ -261,38 +262,53 @@ class UpdatesSummarizer:
context.pkgs_data.update(all_to_install_data) context.pkgs_data.update(all_to_install_data)
self._fill_conflicts(context, context.to_remove.keys()) self._fill_conflicts(context, context.to_remove.keys())
if context.to_install:
self.__fill_provided_map(context=context, pkgs=context.to_install, fill_installed=False)
tf = time.time() tf = time.time()
self.logger.info("It took {0:.2f} seconds to retrieve required upgrade packages".format(tf - ti)) self.logger.info("It took {0:.2f} seconds to retrieve required upgrade packages".format(tf - ti))
return True return True
def __fill_provided_map(self, context: UpdateRequirementsContext): def __fill_provided_map(self, context: UpdateRequirementsContext, pkgs: Dict[str, ArchPackage], fill_installed: bool = True):
ti = time.time() if pkgs:
self.logger.info("Filling provided names") ti = time.time()
context.installed_names = pacman.list_installed_names() self.logger.info("Filling provided names")
installed_to_ignore = set()
for pkgname in context.to_update: if not context.installed_names:
pacman.fill_provided_map(pkgname, pkgname, context.provided_map) context.installed_names = pacman.list_installed_names()
installed_to_ignore.add(pkgname)
pdata = context.pkgs_data.get(pkgname) installed_to_ignore = set()
if pdata and pdata['p']:
pacman.fill_provided_map('{}={}'.format(pkgname, pdata['v']), pkgname, context.provided_map)
for p in pdata['p']:
pacman.fill_provided_map(p, pkgname, context.provided_map)
split_provided = p.split('=')
if len(split_provided) > 1 and split_provided[0] != p: for pkgname in pkgs:
pacman.fill_provided_map(split_provided[0], pkgname, context.provided_map) pacman.fill_provided_map(pkgname, pkgname, context.provided_map)
if installed_to_ignore: # filling the provided names of the installed if fill_installed:
installed_to_query = context.installed_names.difference(installed_to_ignore) installed_to_ignore.add(pkgname)
if installed_to_query: pdata = context.pkgs_data.get(pkgname)
context.provided_map.update(pacman.map_provided(remote=False, pkgs=installed_to_query)) if pdata and pdata['p']:
pacman.fill_provided_map('{}={}'.format(pkgname, pdata['v']), pkgname, context.provided_map)
tf = time.time() ver_split = pdata['v'].split('-')
self.logger.info("Filling provided names took {0:.2f} seconds".format(tf - ti))
if len(ver_split) > 1:
pacman.fill_provided_map('{}={}'.format(pkgname, '-'.join(ver_split[0:-1])), pkgname, context.provided_map)
for p in pdata['p']:
pacman.fill_provided_map(p, pkgname, context.provided_map)
split_provided = p.split('=')
if len(split_provided) > 1 and split_provided[0] != p:
pacman.fill_provided_map(split_provided[0], pkgname, context.provided_map)
if installed_to_ignore: # filling the provided names of the installed
installed_to_query = context.installed_names.difference(installed_to_ignore)
if installed_to_query:
context.provided_map.update(pacman.map_provided(remote=False, pkgs=installed_to_query))
tf = time.time()
self.logger.info("Filling provided names took {0:.2f} seconds".format(tf - ti))
def __fill_aur_index(self, context: UpdateRequirementsContext): def __fill_aur_index(self, context: UpdateRequirementsContext):
if context.arch_config['aur']: if context.arch_config['aur']:
@@ -381,7 +397,7 @@ class UpdatesSummarizer:
if aur_data: if aur_data:
context.pkgs_data.update(aur_data) context.pkgs_data.update(aur_data)
self.__fill_provided_map(context) self.__fill_provided_map(context=context, pkgs=context.to_update)
if context.pkgs_data: if context.pkgs_data:
self._fill_conflicts(context) self._fill_conflicts(context)
@@ -394,6 +410,9 @@ class UpdatesSummarizer:
self.logger.error("Package '{}' not found".format(e.name)) self.logger.error("Package '{}' not found".format(e.name))
return return
if context.pkgs_data:
self._fill_dependency_breakage(context)
self.__update_context_based_on_to_remove(context) self.__update_context_based_on_to_remove(context)
if context.to_update: if context.to_update:
@@ -558,3 +577,166 @@ class UpdatesSummarizer:
self._add_to_remove(pkgs_to_sync, {dep: {n} for dep in all_deps}, context, blacklist) self._add_to_remove(pkgs_to_sync, {dep: {n} for dep in all_deps}, context, blacklist)
else: else:
self.logger.warning("Package '{}' could not be removed from the transaction context because its data was not loaded") self.logger.warning("Package '{}' could not be removed from the transaction context because its data was not loaded")
def _fill_dependency_breakage(self, context: UpdateRequirementsContext):
if bool(context.arch_config['check_dependency_breakage']) and (context.to_update or context.to_install):
ti = time.time()
self.logger.info("Begin: checking dependency breakage")
required_by = pacman.map_required_by(context.to_update.keys()) if context.to_update else {}
if context.to_install:
required_by.update(pacman.map_required_by(context.to_install.keys(), remote=True))
reqs_not_in_transaction = set()
reqs_in_transaction = set()
transaction_pkgs = {*context.to_update.keys(), *context.to_install.keys()}
for reqs in required_by.values():
for r in reqs:
if r in transaction_pkgs:
reqs_in_transaction.add(r)
elif r in context.installed_names:
reqs_not_in_transaction.add(r)
if not reqs_not_in_transaction and not reqs_in_transaction:
return
provided_versions = {}
for p in context.provided_map:
pkg_split = p.split('=')
if len(pkg_split) > 1:
versions = provided_versions.get(pkg_split[0])
if versions is None:
versions = set()
provided_versions[pkg_split[0]] = versions
versions.add(pkg_split[1])
if not provided_versions:
return
cannot_upgrade = set()
for pkg, deps in pacman.map_required_dependencies(*reqs_not_in_transaction).items():
self._add_dependency_breakage(pkgname=pkg,
pkgdeps=deps,
provided_versions=provided_versions,
cannot_upgrade=cannot_upgrade,
context=context)
for pkg in reqs_in_transaction:
data = context.pkgs_data[pkg]
if data and data['d']:
self._add_dependency_breakage(pkgname=pkg,
pkgdeps=data['d'],
provided_versions=provided_versions,
cannot_upgrade=cannot_upgrade,
context=context)
if cannot_upgrade:
cannot_upgrade.update(self._add_dependents_as_cannot_upgrade(context=context,
names=cannot_upgrade,
pkgs_available={*context.to_update.values(), *context.to_install.values()}))
for p in cannot_upgrade:
if p in context.to_update:
del context.to_update[p]
if p in context.repo_to_update:
del context.repo_to_update[p]
if p in context.aur_to_update:
del context.aur_to_update[p]
if p in context.pkgs_data:
del context.pkgs_data[p]
if p in context.to_install:
del context.to_install[p]
if p in context.repo_to_install:
del context.repo_to_install[p]
if p in context.aur_to_install:
del context.aur_to_install[p]
tf = time.time()
self.logger.info("End: checking dependency breakage. Time: {0:.2f} seconds".format(tf - ti))
def _add_dependents_as_cannot_upgrade(self, context: UpdateRequirementsContext, names: Iterable[str], pkgs_available: Set[ArchPackage], already_removed: Optional[Set[str]] = None, iteration_level: int = 0) -> Set[str]:
removed = set() if already_removed is None else already_removed
removed.update(names)
available = {p for p in pkgs_available if p.name not in removed}
to_remove = set()
if available:
for pkg in available:
if pkg.name not in removed:
data = context.pkgs_data.get(pkg.name)
if data and data['d']:
for dep in data['d']:
dep_providers = context.provided_map.get(dep)
if dep_providers:
for p in dep_providers:
if p in names:
to_remove.add(pkg.name)
if pkg.name not in context.cannot_upgrade:
reason = "{} {}".format(self.i18n['arch.info.depends on'].capitalize(), p)
context.cannot_upgrade[pkg.name] = UpgradeRequirement(pkg=pkg,
reason=reason,
sorting_priority=iteration_level - 1)
break
if to_remove:
removed.update(to_remove)
self._add_dependents_as_cannot_upgrade(context=context, names=to_remove, pkgs_available=available,
already_removed=to_remove, iteration_level=iteration_level-1)
return to_remove
def _add_dependency_breakage(self, pkgname: str, pkgdeps: Optional[Set[str]], provided_versions: Dict[str, Set[str]], cannot_upgrade: Set[str], context: UpdateRequirementsContext):
if pkgdeps:
for dep in pkgdeps:
dep_split = RE_DEP_OPERATORS.split(dep)
if len(dep_split) > 1 and dep_split[1]:
real_providers = context.provided_map.get(dep_split[0])
if real_providers:
versions = provided_versions.get(dep_split[0])
if versions:
op = ''.join(RE_DEP_OPERATORS.findall(dep))
if op == '=':
op = '=='
version_match = False
for v in versions:
provided_version, required_version = LooseVersion(v), LooseVersion(dep_split[1])
if eval('provided_version {} required_version'.format(op)):
version_match = True
break
if not version_match:
for pname in real_providers:
if pname not in cannot_upgrade:
provider = context.to_update.get(pname)
if provider:
cannot_upgrade.add(pname)
reason = self.i18n['arch.sync.dep_breakage.reason'].format(pkgname, dep)
context.cannot_upgrade[pname] = UpgradeRequirement(pkg=provider,
reason=reason)

View File

@@ -619,6 +619,7 @@ class FormMultipleSelectQt(QWidget):
help_icon = QLabel() help_icon = QLabel()
help_icon.setPixmap(pixmap_help) help_icon.setPixmap(pixmap_help)
help_icon.setToolTip(op.tooltip) help_icon.setToolTip(op.tooltip)
help_icon.setCursor(QCursor(Qt.PointingHandCursor))
widget.layout().addWidget(help_icon) widget.layout().addWidget(help_icon)
self._layout.addWidget(widget, line, col) self._layout.addWidget(widget, line, col)

View File

@@ -193,7 +193,7 @@ class UpgradeSelected(AsyncAction):
self.manager = manager self.manager = manager
self.i18n = i18n self.i18n = i18n
def _req_as_option(self, req: UpgradeRequirement, tooltip: bool = True, custom_tooltip: str = None, required_size: bool = True) -> InputOption: def _req_as_option(self, req: UpgradeRequirement, tooltip: bool = True, custom_tooltip: str = None, required_size: bool = True, display_sizes: bool = True) -> InputOption:
if req.pkg.installed: if req.pkg.installed:
icon_path = req.pkg.get_disk_icon_path() icon_path = req.pkg.get_disk_icon_path()
@@ -205,15 +205,19 @@ class UpgradeSelected(AsyncAction):
else: else:
icon_path = req.pkg.get_type_icon_path() icon_path = req.pkg.get_type_icon_path()
size_str = '{}: {}'.format(self.i18n['size'].capitalize(), size_str = None
'?' if req.extra_size is None else get_human_size_str(req.extra_size)) if display_sizes:
if required_size and req.extra_size != req.required_size: size_str = '{}: {}'.format(self.i18n['size'].capitalize(),
size_str += ' ( {}: {} )'.format(self.i18n['action.update.pkg.required_size'].capitalize(), '?' if req.extra_size is None else get_human_size_str(req.extra_size))
'?' if req.required_size is None else get_human_size_str(req.required_size)) if required_size and req.extra_size != req.required_size:
size_str += ' ( {}: {} )'.format(self.i18n['action.update.pkg.required_size'].capitalize(),
'?' if req.required_size is None else get_human_size_str(req.required_size))
label = '{}{} - {}'.format(req.pkg.name, label = '{}{}'.format(req.pkg.name,
' ( {} )'.format(req.pkg.latest_version) if req.pkg.latest_version else '', ' ( {} )'.format(req.pkg.latest_version) if req.pkg.latest_version else '')
size_str)
if size_str:
label += ' - {}'.format(size_str)
return InputOption(label=label, return InputOption(label=label,
value=None, value=None,
@@ -232,11 +236,14 @@ class UpgradeSelected(AsyncAction):
return required, extra return required, extra
def _gen_cannot_update_form(self, reqs: List[UpgradeRequirement]) -> FormComponent: def _gen_cannot_upgrade_form(self, reqs: List[UpgradeRequirement]) -> FormComponent:
opts = [self._req_as_option(r, False, r.reason) for r in reqs] reqs.sort(key=UpgradeRequirement.sort_by_priority)
opts = [self._req_as_option(req=r, tooltip=False, custom_tooltip=r.reason, display_sizes=False) for r in reqs]
comps = [MultipleSelectComponent(label='', options=opts, default_options=set(opts))] comps = [MultipleSelectComponent(label='', options=opts, default_options=set(opts))]
return FormComponent(label=self.i18n['action.update.cannot_update_label'], components=comps) return FormComponent(label='{} ( {}: {} )'.format(self.i18n['action.update.cannot_update_label'],
self.i18n['amount'].capitalize(), len(opts)),
components=comps)
def _gen_to_install_form(self, reqs: List[UpgradeRequirement]) -> Tuple[FormComponent, Tuple[int, int]]: def _gen_to_install_form(self, reqs: List[UpgradeRequirement]) -> Tuple[FormComponent, Tuple[int, int]]:
opts = [self._req_as_option(r, custom_tooltip=r.reason) for r in reqs] opts = [self._req_as_option(r, custom_tooltip=r.reason) for r in reqs]
@@ -396,7 +403,7 @@ class UpgradeSelected(AsyncAction):
comps, required_size, extra_size = [], 0, 0 comps, required_size, extra_size = [], 0, 0
if requirements.cannot_upgrade: if requirements.cannot_upgrade:
comps.append(self._gen_cannot_update_form(requirements.cannot_upgrade)) comps.append(self._gen_cannot_upgrade_form(requirements.cannot_upgrade))
if requirements.to_install: if requirements.to_install:
req_form, reqs_size = self._gen_to_install_form(requirements.to_install) req_form, reqs_size = self._gen_to_install_form(requirements.to_install)