diff --git a/CHANGELOG.md b/CHANGELOG.md index b54e2b20..fac10f66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

+ - new package actions to Allow/Ignore rebuild check for a specific package. Useful for binary packages (e.g: package-bin). +

+ +

+ +

+ +

+ - form some reason **rebuild-detector** hangs when executed within PyCharm (this integration is disabled regarding this particular scenario for now) - new custom action to quickly reinstall a package diff --git a/README.md b/README.md index 602575e3..b89db5ab 100644 --- a/README.md +++ b/README.md @@ -188,6 +188,8 @@ database: - **clean cache**: it cleans the pacman cache directory (default: `/var/cache/pacman/pkg`) - **mark PKGBUILD as editable**: it marks a given PKGBUILD of a package as editable (a popup with the PKGBUILD will be displayed before upgrading/downgrading this package). Action only available when the configuration property **edit_aur_pkgbuild** is not **false**. - **unmark PKGBUILD as editable**: reverts the action described above. Action only available when the configuration property **edit_aur_pkgbuild** is not **false**. + - **allow reinstallation check**: it allows to check if a given AUR packages requires to be rebuilt + - **ignore reinstallation check**: it does not to check if a given AUR packages requires to be rebuilt - **check Snaps support**: checks if the Snapd services are properly enabled. - Installed AUR packages have their **PKGBUILD** files cached at **~/.cache/bauh/arch/installed/$pkgname** - Packages with ignored updates are defined at **~/.config/bauh/arch/updates_ignored.txt** diff --git a/bauh/gems/arch/__init__.py b/bauh/gems/arch/__init__.py index 5350f171..22fcb91f 100644 --- a/bauh/gems/arch/__init__.py +++ b/bauh/gems/arch/__init__.py @@ -18,6 +18,7 @@ CONFIG_FILE = '{}/arch.yml'.format(CONFIG_PATH) SUGGESTIONS_FILE = 'https://raw.githubusercontent.com/vinifmor/bauh-files/master/arch/aur_suggestions.txt' UPDATES_IGNORED_FILE = '{}/updates_ignored.txt'.format(CONFIG_DIR) EDITABLE_PKGBUILDS_FILE = '{}/aur/editable_pkgbuilds.txt'.format(CONFIG_DIR) +IGNORED_REBUILD_CHECK_FILE = '{}/aur/ignored_rebuild_check.txt'.format(CONFIG_DIR) def get_icon_path() -> str: diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 047a2a15..a7acef56 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -449,7 +449,7 @@ class ArchManager(SoftwareManager): return res def _fill_aur_pkgs(self, aur_pkgs: dict, output: List[ArchPackage], disk_loader: DiskCacheLoader, internet_available: bool, - arch_config: dict, rebuild_check: Optional[Thread], to_rebuild: Set[str]): + arch_config: dict, rebuild_check: Optional[Thread], rebuild_ignored: Optional[Thread], rebuild_output: Optional[Dict[str, Set[str]]]): if internet_available: try: @@ -462,9 +462,16 @@ class ArchManager(SoftwareManager): if pkgsinfo: editable_pkgbuilds = self._read_editable_pkgbuilds() if arch_config['edit_aur_pkgbuild'] is not False else None - if rebuild_check: + ignore_rebuild_check = None + if rebuild_ignored and rebuild_output is not None: + rebuild_ignored.join() + ignore_rebuild_check = rebuild_output['ignored'] + + to_rebuild = None + if rebuild_check and rebuild_output is not None: self.logger.info("Waiting for rebuild-detector") rebuild_check.join() + to_rebuild = rebuild_output['to_rebuild'] for pkgdata in pkgsinfo: pkg = self.aur_mapper.map_api_data(pkgdata, aur_pkgs, self.categories) @@ -477,10 +484,15 @@ class ArchManager(SoftwareManager): pkg.update = self._check_aur_package_update(pkg=pkg, installed_data=aur_pkgs.get(pkg.name, {}), api_data=pkgdata) + pkg.aur_update = pkg.update # used in 'set_rebuild_check' + + if ignore_rebuild_check is not None: + pkg.allow_rebuild = pkg.name not in ignore_rebuild_check if to_rebuild and not pkg.update and pkg.name in to_rebuild: pkg.require_rebuild = True - pkg.update = True + + pkg.update_state() pkg.status = PackageStatus.READY output.append(pkg) @@ -564,15 +576,19 @@ class ArchManager(SoftwareManager): self.disk_cache_updater.join() self.logger.info("Disk cache ready") - def __fill_packages_to_rebuild(self, output: Set[str]): + def __fill_packages_to_rebuild(self, output: Dict[str, Set[str]]): if rebuild_detector.is_installed(): if 'PYCHARM_CLASSPATH' in os.environ: self.logger.warning("'rebuild-detector' is currently not working within PyCharm. Aborting...") return self.logger.info("rebuild-detector: checking") - output.update(rebuild_detector.list_required_rebuild()) - self.logger.info("rebuild-detector: packages detected -> {}".format(output)) + to_rebuild = rebuild_detector.list_required_rebuild() + output['to_rebuild'].update(to_rebuild) + self.logger.info("rebuild-detector: {} packages require rebuild".format(len(to_rebuild))) + + def __fill_ignored_by_rebuild_detector(self, output: Dict[str, Set[str]]): + output['ignored'].update(rebuild_detector.list_ignored()) def read_installed(self, disk_loader: Optional[DiskCacheLoader], limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None, names: Iterable[str] = None, wait_disk_cache: bool = True) -> SearchResult: self.aur_client.clean_caches() @@ -583,11 +599,15 @@ class ArchManager(SoftwareManager): if not aur_supported and not repos_supported: return SearchResult.empty() - to_rebuild, rebuild_check = set(), None + rebuild_output, rebuild_check, rebuild_ignored = None, None, None if aur_supported and arch_config['aur_rebuild_detector']: - rebuild_check = Thread(target=self.__fill_packages_to_rebuild, args=(to_rebuild,), daemon=True) + rebuild_output = {'to_rebuild': set(), 'ignored': set()} + rebuild_check = Thread(target=self.__fill_packages_to_rebuild, args=(rebuild_output,), daemon=True) rebuild_check.start() + rebuild_ignored = Thread(target=self.__fill_ignored_by_rebuild_detector, args=(rebuild_output, ), daemon=True) + rebuild_ignored.start() + installed = pacman.map_installed(names=names) aur_pkgs, repo_pkgs = None, None @@ -622,7 +642,7 @@ class ArchManager(SoftwareManager): map_threads = [] if aur_pkgs: - t = Thread(target=self._fill_aur_pkgs, args=(aur_pkgs, pkgs, disk_loader, internet_available, arch_config, rebuild_check, to_rebuild), daemon=True) + t = Thread(target=self._fill_aur_pkgs, args=(aur_pkgs, pkgs, disk_loader, internet_available, arch_config, rebuild_check, rebuild_ignored, rebuild_output), daemon=True) t.start() map_threads.append(t) @@ -3461,3 +3481,22 @@ class ArchManager(SoftwareManager): watcher=watcher, context=context, disk_loader=self.context.disk_loader_factory.new()).success + + def set_rebuild_check(self, pkg: ArchPackage, root_password: str, watcher: ProcessWatcher) -> bool: + if pkg.repository != 'aur': + return False + + try: + if pkg.allow_rebuild: + rebuild_detector.add_as_ignored(pkg.name) + pkg.allow_rebuild = False + else: + rebuild_detector.remove_from_ignored(pkg.name) + pkg.allow_rebuild = True + except: + self.logger.error("An unexpected exception happened") + traceback.print_exc() + return False + + pkg.update_state() + return True diff --git a/bauh/gems/arch/model.py b/bauh/gems/arch/model.py index c2410ee1..f63c26d4 100644 --- a/bauh/gems/arch/model.py +++ b/bauh/gems/arch/model.py @@ -28,6 +28,20 @@ ACTION_AUR_REINSTALL = CustomSoftwareAction(i18n_label_key='arch.action.reinstal manager_method='reinstall', icon_path=resource.get_path('img/build.svg', ROOT_DIR)) +ACTION_IGNORE_REBUILD_CHECK = CustomSoftwareAction(i18n_label_key='arch.action.rebuild_check.ignore', + i18n_status_key='arch.action.rebuild_check.ignore.status', + i18n_confirm_key='arch.action.rebuild_check.ignore.confirm', + requires_root=False, + manager_method='set_rebuild_check', + icon_path=resource.get_path('img/check_disabled.svg', ROOT_DIR)) + +ACTION_ALLOW_REBUILD_CHECK = CustomSoftwareAction(i18n_label_key='arch.action.rebuild_check.allow', + i18n_status_key='arch.action.rebuild_check.allow.status', + i18n_confirm_key='arch.action.rebuild_check.allow.confirm', + requires_root=False, + manager_method='set_rebuild_check', + icon_path=resource.get_path('img/check.svg', ROOT_DIR)) + class ArchPackage(SoftwarePackage): @@ -38,7 +52,9 @@ class ArchPackage(SoftwarePackage): desktop_entry: str = None, installed: bool = False, srcinfo: dict = None, dependencies: Set[str] = None, categories: List[str] = None, i18n: I18n = None, update_ignored: bool = False, arch: str = None, pkgbuild_editable: bool = None, install_date: Optional[int] = None, commit: Optional[str] = None, - require_rebuild: bool = False): + require_rebuild: bool = False, + allow_rebuild: Optional[bool] = None, + aur_update: bool = False): super(ArchPackage, self).__init__(name=name, version=version, latest_version=latest_version, description=description, installed=installed, categories=categories) @@ -64,6 +80,8 @@ class ArchPackage(SoftwarePackage): self.install_date = install_date self.commit = commit # only for AUR for downgrading purposes self.require_rebuild = require_rebuild + self.allow_rebuild = allow_rebuild + self.aur_update = aur_update @staticmethod def disk_cache_path(pkgname: str): @@ -189,12 +207,22 @@ class ArchPackage(SoftwarePackage): if self.pkgbuild_editable is not None: actions.append(ACTION_AUR_DISABLE_PKGBUILD_EDITION if self.pkgbuild_editable else ACTION_AUR_ENABLE_PKGBUILD_EDITION) + if self.allow_rebuild is not None: + actions.append(ACTION_IGNORE_REBUILD_CHECK if self.allow_rebuild else ACTION_ALLOW_REBUILD_CHECK) + return actions def get_update_tip(self) -> Optional[str]: - if self.repository == 'aur' and self.require_rebuild: + if self.repository == 'aur' and self.allow_rebuild and self.require_rebuild: return self.i18n['arch.package.requires_rebuild'] + ' (rebuild)' + def update_state(self): + if self.repository == 'aur': + if self.allow_rebuild and self.require_rebuild: + self.update = True + else: + self.update = self.aur_update + def __hash__(self): if self.view_name is not None: return hash((self.view_name, self.repository)) diff --git a/bauh/gems/arch/rebuild_detector.py b/bauh/gems/arch/rebuild_detector.py index 5188c9e3..5c8c59f3 100644 --- a/bauh/gems/arch/rebuild_detector.py +++ b/bauh/gems/arch/rebuild_detector.py @@ -1,6 +1,9 @@ +import os +from pathlib import Path from typing import Set from bauh.commons import system +from bauh.gems.arch import IGNORED_REBUILD_CHECK_FILE def is_installed() -> bool: @@ -22,3 +25,42 @@ def list_required_rebuild() -> Set[str]: required.add(line_split[1]) return required + + +def list_ignored() -> Set[str]: + if os.path.isfile(IGNORED_REBUILD_CHECK_FILE): + with open(IGNORED_REBUILD_CHECK_FILE) as f: + ignored_str = f.read() + + return {p.strip() for p in ignored_str.split('\n') if p} + else: + return set() + + +def add_as_ignored(pkgname: str): + ignored = list_ignored() + ignored.add(pkgname) + + Path(os.path.dirname(IGNORED_REBUILD_CHECK_FILE)).mkdir(parents=True, exist_ok=True) + + with open(IGNORED_REBUILD_CHECK_FILE, 'w+') as f: + for p in ignored: + f.write('{}\n'.format(p)) + + +def remove_from_ignored(pkgname: str): + ignored = list_ignored() + + if ignored is None or pkgname not in ignored: + return + + ignored.remove(pkgname) + + Path(os.path.dirname(IGNORED_REBUILD_CHECK_FILE)).mkdir(parents=True, exist_ok=True) + + if ignored: + with open(IGNORED_REBUILD_CHECK_FILE, 'w+') as f: + for p in ignored: + f.write('{}\n'.format(p)) + else: + os.remove(IGNORED_REBUILD_CHECK_FILE) diff --git a/bauh/gems/arch/resources/img/check.svg b/bauh/gems/arch/resources/img/check.svg new file mode 100644 index 00000000..991670c3 --- /dev/null +++ b/bauh/gems/arch/resources/img/check.svg @@ -0,0 +1,63 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/bauh/gems/arch/resources/img/check_disabled.svg b/bauh/gems/arch/resources/img/check_disabled.svg new file mode 100644 index 00000000..d25f6602 --- /dev/null +++ b/bauh/gems/arch/resources/img/check_disabled.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/bauh/gems/arch/resources/locale/ca b/bauh/gems/arch/resources/locale/ca index 0a24e9fd..a73540ed 100644 --- a/bauh/gems/arch/resources/locale/ca +++ b/bauh/gems/arch/resources/locale/ca @@ -1,3 +1,9 @@ +arch.action.rebuild_check.allow=Allow reinstallation check +arch.action.rebuild_check.allow.status=Allowing reinstallation check +arch.action.rebuild_check.allow.confirm=Allow reinstallation check for {} ? +arch.action.rebuild_check.ignore=Ignore reinstallation check +arch.action.rebuild_check.ignore.status=Ignoring reinstallation check +arch.action.rebuild_check.ignore.confirm=Ignore reinstallation check for {} ? arch.action.db_locked.body.l1=The system's package database is locked. arch.action.db_locked.body.l2=It is necessary to unlock it to continue. arch.action.db_locked.confirmation=Unlock and continue diff --git a/bauh/gems/arch/resources/locale/de b/bauh/gems/arch/resources/locale/de index 7e45334f..f5d9c984 100644 --- a/bauh/gems/arch/resources/locale/de +++ b/bauh/gems/arch/resources/locale/de @@ -1,3 +1,9 @@ +arch.action.rebuild_check.allow=Allow reinstallation check +arch.action.rebuild_check.allow.status=Allowing reinstallation check +arch.action.rebuild_check.allow.confirm=Allow reinstallation check for {} ? +arch.action.rebuild_check.ignore=Ignore reinstallation check +arch.action.rebuild_check.ignore.status=Ignoring reinstallation check +arch.action.rebuild_check.ignore.confirm=Ignore reinstallation check for {} ? arch.action.db_locked.body.l1=The system's package database is locked. arch.action.db_locked.body.l2=It is necessary to unlock it to continue. arch.action.db_locked.confirmation=Unlock and continue diff --git a/bauh/gems/arch/resources/locale/en b/bauh/gems/arch/resources/locale/en index 7c0ef1c2..1da1c75f 100644 --- a/bauh/gems/arch/resources/locale/en +++ b/bauh/gems/arch/resources/locale/en @@ -1,3 +1,9 @@ +arch.action.rebuild_check.allow=Allow reinstallation check +arch.action.rebuild_check.allow.status=Allowing reinstallation check +arch.action.rebuild_check.allow.confirm=Allow reinstallation check for {} ? +arch.action.rebuild_check.ignore=Ignore reinstallation check +arch.action.rebuild_check.ignore.status=Ignoring reinstallation check +arch.action.rebuild_check.ignore.confirm=Ignore reinstallation check for {} ? arch.action.db_locked.body.l1=The system's package database is locked. arch.action.db_locked.body.l2=It is necessary to unlock it to continue. arch.action.db_locked.confirmation=Unlock and continue diff --git a/bauh/gems/arch/resources/locale/es b/bauh/gems/arch/resources/locale/es index 778253b5..13af4cfb 100644 --- a/bauh/gems/arch/resources/locale/es +++ b/bauh/gems/arch/resources/locale/es @@ -1,3 +1,9 @@ +arch.action.rebuild_check.allow=Permitir verificación de reinstalación +arch.action.rebuild_check.allow.status=Permitindo verificación de reinstalación +arch.action.rebuild_check.allow.confirm=¿ Permitir verificación de reinstalación para {} ? +arch.action.rebuild_check.ignore=Ignorar verificación de reinstalación +arch.action.rebuild_check.ignore.status=Ignorando verificación de reinstalación +arch.action.rebuild_check.ignore.confirm=¿ Ignorar verificación de reinstalación para {} ? arch.action.db_locked.body.l1=La base de datos de paquetes del sistema está bloqueada. arch.action.db_locked.body.l2=Es necesario desbloquearla para continuar. arch.action.db_locked.confirmation=Desbloquear y continuar diff --git a/bauh/gems/arch/resources/locale/fr b/bauh/gems/arch/resources/locale/fr index 800bd188..e1e1c834 100644 --- a/bauh/gems/arch/resources/locale/fr +++ b/bauh/gems/arch/resources/locale/fr @@ -1,3 +1,9 @@ +arch.action.rebuild_check.allow=Allow reinstallation check +arch.action.rebuild_check.allow.status=Allowing reinstallation check +arch.action.rebuild_check.allow.confirm=Allow reinstallation check for {} ? +arch.action.rebuild_check.ignore=Ignore reinstallation check +arch.action.rebuild_check.ignore.status=Ignoring reinstallation check +arch.action.rebuild_check.ignore.confirm=Ignore reinstallation check for {} ? arch.action.db_locked.body.l1=La base de données de paquets du système est verrouillée. arch.action.db_locked.body.l2=Il faut la déverrouiller pour continuer. arch.action.db_locked.confirmation=Déverrouiller et continuer diff --git a/bauh/gems/arch/resources/locale/it b/bauh/gems/arch/resources/locale/it index febc4807..3d4742f3 100644 --- a/bauh/gems/arch/resources/locale/it +++ b/bauh/gems/arch/resources/locale/it @@ -1,3 +1,9 @@ +arch.action.rebuild_check.allow=Allow reinstallation check +arch.action.rebuild_check.allow.status=Allowing reinstallation check +arch.action.rebuild_check.allow.confirm=Allow reinstallation check for {} ? +arch.action.rebuild_check.ignore=Ignore reinstallation check +arch.action.rebuild_check.ignore.status=Ignoring reinstallation check +arch.action.rebuild_check.ignore.confirm=Ignore reinstallation check for {} ? arch.action.db_locked.body.l1=The system's package database is locked. arch.action.db_locked.body.l2=It is necessary to unlock it to continue. arch.action.db_locked.confirmation=Unlock and continue diff --git a/bauh/gems/arch/resources/locale/pt b/bauh/gems/arch/resources/locale/pt index 0e3ba052..1c9f55b1 100644 --- a/bauh/gems/arch/resources/locale/pt +++ b/bauh/gems/arch/resources/locale/pt @@ -1,3 +1,9 @@ +arch.action.rebuild_check.allow=Permitir verificação de reinstalação +arch.action.rebuild_check.allow.status=Permitindo verificação de reinstalação +arch.action.rebuild_check.allow.confirm=Permitir verificação de reinstalação para {} ? +arch.action.rebuild_check.ignore=Ignorar verificação de reinstalação +arch.action.rebuild_check.ignore.status=Ignorando verificação de reinstalação +arch.action.rebuild_check.ignore.confirm=Ignorar verificação de reinstalação para {} ? arch.action.db_locked.body.l1=O banco de dados de pacotes do sistema está bloqueado. arch.action.db_locked.body.l2=É necessário desbloquea-lo para continuar. arch.action.db_locked.confirmation=Desbloquear e continuar diff --git a/bauh/gems/arch/resources/locale/ru b/bauh/gems/arch/resources/locale/ru index 7a25ba98..7dd07afd 100644 --- a/bauh/gems/arch/resources/locale/ru +++ b/bauh/gems/arch/resources/locale/ru @@ -1,3 +1,9 @@ +arch.action.rebuild_check.allow=Allow reinstallation check +arch.action.rebuild_check.allow.status=Allowing reinstallation check +arch.action.rebuild_check.allow.confirm=Allow reinstallation check for {} ? +arch.action.rebuild_check.ignore=Ignore reinstallation check +arch.action.rebuild_check.ignore.status=Ignoring reinstallation check +arch.action.rebuild_check.ignore.confirm=Ignore reinstallation check for {} ? arch.action.db_locked.body.l1=The system package database is locked. arch.action.db_locked.body.l2=It is necessary to unlock it to continue. arch.action.db_locked.confirmation=Unlock and continue diff --git a/bauh/gems/arch/resources/locale/tr b/bauh/gems/arch/resources/locale/tr index ac651e6d..0ebb0965 100644 --- a/bauh/gems/arch/resources/locale/tr +++ b/bauh/gems/arch/resources/locale/tr @@ -1,3 +1,9 @@ +arch.action.rebuild_check.allow=Allow reinstallation check +arch.action.rebuild_check.allow.status=Allowing reinstallation check +arch.action.rebuild_check.allow.confirm=Allow reinstallation check for {} ? +arch.action.rebuild_check.ignore=Ignore reinstallation check +arch.action.rebuild_check.ignore.status=Ignoring reinstallation check +arch.action.rebuild_check.ignore.confirm=Ignore reinstallation check for {} ? arch.action.db_locked.body.l1=Sistemin paket veritabanı kilitli. arch.action.db_locked.body.l2=Devam etmek için veritabanı kilidini açmak gerekiyor. arch.action.db_locked.confirmation=Veritabanı kilidini aç ve devam et