diff --git a/CHANGELOG.md b/CHANGELOG.md index dc6c62a6..e7758bc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - AUR: - The AUR indexer daemon is not running every 20 minutes anymore. It will only run during the boot, and will generate the optimized index at **/tmp/bauh/arch/aur.txt**. This new behavior does not harm the current experience, and reduces memory usage. More information about this behavior in [README](https://github.com/vinifmor/bauh/blob/master/README.md). - +- Minor memory improvements ### Fixes - AUR: - an exception happens when retrieving matches from the cached AUR index diff --git a/README.md b/README.md index 485d0fc4..cd6af633 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ If bauh is not starting properly after changing its style, execute `bauh --reset Obs: There are some crashes when **AppImageLauncher** is installed. It is advisable to uninstall it and reboot the system before trying to install an AppImage application. #### AUR ( arch ) +- Only available for Arch-based systems - The user is able to search, install, uninstall, downgrade, launch and retrieve the packages history - It handles conflicts, and missing / optional packages installations ( including from your distro mirrors ) - If [**aria2**](https://github.com/aria2/aria2) is installed on your system and multi-threaded downloads are enabled ( see **BAUH_DOWNLOAD_MULTITHREAD** ), the source packages @@ -126,11 +127,20 @@ will be pre-downloaded faster ( it does **NOT** modify your **pacman** settings b) same as previous, but related to **COMPRESSXZ** definition ( if '--threads=0' is not defined ) - Obs: this feature can be disabled through the environment variable **BAUH_ARCH_OPTIMIZE=0** - ( For more information about these optimizations, have a look at [Makepkg](https://wiki.archlinux.org/index.php/Makepkg) ) -- During bauh initialization the a full AUR normalized index is saved at /tmp/bauh/arch/aur.txt, and it will only be used if the AUR Api cannot handle the number of matches for a given query. + Obs: For more information about them, have a look at [Makepkg](https://wiki.archlinux.org/index.php/Makepkg) +- During bauh initialization a full AUR normalized index is saved at **/tmp/bauh/arch/aur.txt**, and it will only be used if the AUR API cannot handle the number of matches for a given query. - If some of your installed packages are not categorized, send an e-mail to **bauh4linux@gmail.com** informing their names and categories in the following format: ```name=category1[,category2,category3,...]``` -- Transitive dependencies checking can be disabled through the environment variable **BAUH_ARCH_CHECK_SUBDEPS=0**. The dependency checking process will be faster, but the application will ask for a confirmation every time a not installed dependency is detected. +- The configuration file is located at **~/.config/bauh/arch.yml** and it allows the following customizations: +``` +optimize: true # if false: disables the auto-compilation improvements +transitive_checking: true # if false: the dependency checking process will be faster, but the application will ask for a confirmation every time a not installed dependency is detected. +``` +- Required dependencies: + - **pacman** + - **wget** +- Optional dependencies: + - **git**: allows to retrieve packages release history and downgrading + - **aria2**: provides faster and multi-threaded downloads #### Web Applications ( web ) - It allows the installation of native Web applications by typing an address / URL in the search bar. @@ -154,7 +164,7 @@ environment: version: null # set a custom Electron version here ( e.g: '6.1.4' ) system: false # set it to 'true' if you want to use the nativefier version globally installed on your system ``` -- Required packages: +- Required dependencies: - Arch systems: **python-lxml**, **python-beautifulsoup4** - Debian systems ( using pip ): **beautifulsoup4**, **lxml** diff --git a/bauh/commons/config.py b/bauh/commons/config.py index 87890cb2..28e8b161 100644 --- a/bauh/commons/config.py +++ b/bauh/commons/config.py @@ -3,12 +3,13 @@ from pathlib import Path import yaml +from bauh.api.constants import CONFIG_PATH from bauh.commons import util def read_config(file_path: str, template: dict, update_file: bool = False) -> dict: if not os.path.exists(file_path): - Path(file_path).mkdir(parents=True, exist_ok=True) + Path(CONFIG_PATH).mkdir(parents=True, exist_ok=True) with open(file_path, 'w+') as f: f.write(yaml.dump(template)) diff --git a/bauh/gems/arch/__init__.py b/bauh/gems/arch/__init__.py index e77b4c57..10103d7f 100644 --- a/bauh/gems/arch/__init__.py +++ b/bauh/gems/arch/__init__.py @@ -1,6 +1,6 @@ import os -from bauh.api.constants import CACHE_PATH, HOME_PATH +from bauh.api.constants import CACHE_PATH, HOME_PATH, CONFIG_PATH ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) BUILD_DIR = '/tmp/bauh/aur' @@ -11,6 +11,7 @@ URL_CATEGORIES_FILE = 'https://raw.githubusercontent.com/vinifmor/bauh-files/mas CONFIG_DIR = '{}/.config/bauh/arch'.format(HOME_PATH) CUSTOM_MAKEPKG_PATH = '{}/makepkg.conf'.format(CONFIG_DIR) AUR_INDEX_FILE = '{}/aur.txt'.format(BUILD_DIR) +CONFIG_FILE = '{}/arch.yml'.format(CONFIG_PATH) def should_optimize_compilation() -> bool: diff --git a/bauh/gems/arch/config.py b/bauh/gems/arch/config.py new file mode 100644 index 00000000..0dd25b8d --- /dev/null +++ b/bauh/gems/arch/config.py @@ -0,0 +1,7 @@ +from bauh.commons.config import read_config as read +from bauh.gems.arch import CONFIG_FILE + + +def read_config(update_file: bool = False) -> dict: + template = {'optimize': True, 'transitive_checking': True} + return read(CONFIG_FILE, template, update_file=update_file) diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 917da21a..edb02b69 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -22,6 +22,7 @@ from bauh.commons.system import SystemProcess, ProcessHandler, new_subprocess, r from bauh.gems.arch import BUILD_DIR, aur, pacman, makepkg, pkgbuild, message, confirmation, disk, git, suggestions, \ gpg, URL_CATEGORIES_FILE, CATEGORIES_CACHE_DIR, CATEGORIES_FILE_PATH from bauh.gems.arch.aur import AURClient +from bauh.gems.arch.config import read_config from bauh.gems.arch.depedencies import DependenciesAnalyser from bauh.gems.arch.mapper import ArchDataMapper from bauh.gems.arch.model import ArchPackage @@ -54,7 +55,6 @@ class ArchManager(SoftwareManager): self.i18n = context.i18n self.aur_client = AURClient(context.http_client, context.logger) self.dcache_updater = ArchDiskCacheUpdater(context.logger, context.disk_cache) - self.comp_optimizer = ArchCompilationOptimizer(context.logger) self.logger = context.logger self.enabled = True self.arch_distro = context.distro == 'arch' @@ -62,6 +62,7 @@ class ArchManager(SoftwareManager): URL_CATEGORIES_FILE, CATEGORIES_CACHE_DIR, CATEGORIES_FILE_PATH) self.categories = {} self.deps_analyser = DependenciesAnalyser(self.aur_client) + self.local_config = None def _upgrade_search_result(self, apidata: dict, installed_pkgs: dict, downgrade_enabled: bool, res: SearchResult, disk_loader: DiskCacheLoader): app = self.mapper.map_api_data(apidata, installed_pkgs['not_signed'], self.categories) @@ -182,6 +183,7 @@ class ArchManager(SoftwareManager): return SearchResult(apps, None, len(apps)) def downgrade(self, pkg: ArchPackage, root_password: str, watcher: ProcessWatcher) -> bool: + self.local_config = read_config() handler = ProcessHandler(watcher) app_build_dir = '{}/build_{}'.format(BUILD_DIR, int(time.time())) @@ -237,6 +239,8 @@ class ArchManager(SoftwareManager): if os.path.exists(app_build_dir): handler.handle(SystemProcess(subproc=new_subprocess(['rm', '-rf', app_build_dir]))) + self.local_config = None + return False def clean_cache_for(self, pkg: ArchPackage): @@ -244,7 +248,11 @@ class ArchManager(SoftwareManager): shutil.rmtree(pkg.get_disk_cache_path()) def update(self, pkg: ArchPackage, root_password: str, watcher: ProcessWatcher) -> bool: - return self.install(pkg=pkg, root_password=root_password, watcher=watcher, skip_optdeps=True) + self.local_config = read_config() + try: + return self.install(pkg=pkg, root_password=root_password, watcher=watcher, skip_optdeps=True) + finally: + self.local_config = None def _uninstall(self, pkg_name: str, root_password: str, handler: ProcessHandler) -> bool: res = handler.handle(SystemProcess(new_root_subprocess(['pacman', '-R', pkg_name, '--noconfirm'], root_password))) @@ -260,6 +268,7 @@ class ArchManager(SoftwareManager): return res def uninstall(self, pkg: ArchPackage, root_password: str, watcher: ProcessWatcher) -> bool: + self.local_config = read_config() handler = ProcessHandler(watcher) watcher.change_progress(10) @@ -274,6 +283,7 @@ class ArchManager(SoftwareManager): uninstalled = self._uninstall(pkg.name, root_password, handler) watcher.change_progress(100) + self.local_config = None return uninstalled def get_managed_types(self) -> Set["type"]: @@ -434,7 +444,7 @@ class ArchManager(SoftwareManager): return True def _should_check_subdeps(self): - return bool(int(os.getenv('BAUH_ARCH_CHECK_SUBDEPS', 1))) + return self.local_config['transitive_checking'] def _build(self, pkgname: str, maintainer: str, root_password: str, handler: ProcessHandler, build_dir: str, project_dir: str, dependency: bool, skip_optdeps: bool = False, change_progress: bool = True) -> bool: @@ -447,7 +457,7 @@ class ArchManager(SoftwareManager): # building main package handler.watcher.change_substatus(self.i18n['arch.building.package'].format(bold(pkgname))) - pkgbuilt, output = makepkg.make(project_dir, handler) + pkgbuilt, output = makepkg.make(project_dir, optimize=self.local_config['optimize'], handler=handler) self._update_progress(handler.watcher, 65, change_progress) if pkgbuilt: @@ -745,6 +755,12 @@ class ArchManager(SoftwareManager): return False def install(self, pkg: ArchPackage, root_password: str, watcher: ProcessWatcher, skip_optdeps: bool = False) -> bool: + clean_config = False + + if not self.local_config: + self.local_config = read_config() + clean_config = True + res = self._install_from_aur(pkg.name, pkg.maintainer, root_password, ProcessHandler(watcher), dependency=False, skip_optdeps=skip_optdeps) if res: @@ -755,6 +771,9 @@ class ArchManager(SoftwareManager): data = json.loads(data) pkg.fill_cached_data(data) + if clean_config: + self.local_config = None + return res def _is_wget_available(self): @@ -788,7 +807,7 @@ class ArchManager(SoftwareManager): def prepare(self): self.dcache_updater.start() - self.comp_optimizer.start() + ArchCompilationOptimizer(self.context.logger).start() self.categories_mapper.start() AURIndexUpdater(self.context).start() diff --git a/bauh/gems/arch/makepkg.py b/bauh/gems/arch/makepkg.py index a6ba0ff9..08f2e0a8 100644 --- a/bauh/gems/arch/makepkg.py +++ b/bauh/gems/arch/makepkg.py @@ -37,10 +37,10 @@ def check(pkgdir: str, handler: ProcessHandler) -> dict: return res -def make(pkgdir: str, handler: ProcessHandler) -> Tuple[bool, str]: +def make(pkgdir: str, optimize: bool, handler: ProcessHandler) -> Tuple[bool, str]: cmd = ['makepkg', '-ALcsmf'] - if should_optimize_compilation(): + if optimize: if os.path.exists(CUSTOM_MAKEPKG_PATH): handler.watcher.print('Using custom makepkg.conf -> {}'.format(CUSTOM_MAKEPKG_PATH)) cmd.append('--config={}'.format(CUSTOM_MAKEPKG_PATH)) diff --git a/bauh/gems/arch/worker.py b/bauh/gems/arch/worker.py index 792aaf73..61f1f4f5 100644 --- a/bauh/gems/arch/worker.py +++ b/bauh/gems/arch/worker.py @@ -9,7 +9,7 @@ import requests from bauh.api.abstract.context import ApplicationContext from bauh.gems.arch import pacman, disk, CUSTOM_MAKEPKG_PATH, CONFIG_DIR, should_optimize_compilation, BUILD_DIR, \ - AUR_INDEX_FILE + AUR_INDEX_FILE, config URL_INDEX = 'https://aur.archlinux.org/packages.gz' URL_INFO = 'https://aur.archlinux.org/rpc/?v=5&type=info&arg={}' @@ -69,16 +69,17 @@ class ArchDiskCacheUpdater(Thread if bool(os.getenv('BAUH_DEBUG', 0)) else Proce self.logger.info('Pre-cached data of {} AUR packages to the disk'.format(saved)) -class ArchCompilationOptimizer(Thread if bool(os.getenv('BAUH_DEBUG', 0)) else Process): +class ArchCompilationOptimizer(Thread): def __init__(self, logger: logging.Logger): super(ArchCompilationOptimizer, self).__init__(daemon=True) self.logger = logger def run(self): + local_config = config.read_config(update_file=True) - if not should_optimize_compilation(): - self.logger.info("Arch packages compilation optimization is disabled") + if not local_config['optimize']: + self.logger.info("Arch packages compilation optimizations are disabled") if os.path.exists(CUSTOM_MAKEPKG_PATH): self.logger.info("Removing custom 'makepkg.conf' -> '{}'".format(CUSTOM_MAKEPKG_PATH))