From 5bc64640ad45dfbd7410e6d5e29d709ab73c060f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Wed, 27 May 2020 17:07:02 -0300 Subject: [PATCH] [improvement][arch] always retrieving the package sizes before downloading with mult-threaded clients --- bauh/gems/arch/confirmation.py | 9 +++------ bauh/gems/arch/controller.py | 17 +++++++++-------- bauh/gems/arch/pacman.py | 12 +++++++++++- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/bauh/gems/arch/confirmation.py b/bauh/gems/arch/confirmation.py index 7965f276..1cea016e 100644 --- a/bauh/gems/arch/confirmation.py +++ b/bauh/gems/arch/confirmation.py @@ -18,7 +18,7 @@ def request_optional_deps(pkgname: str, pkg_repos: dict, watcher: ProcessWatcher opts = [] repo_deps = [p for p, data in pkg_repos.items() if data['repository'] != 'aur'] - sizes = pacman.get_update_size(repo_deps) if repo_deps else {} + sizes = pacman.map_update_sizes(repo_deps) if repo_deps else {} for p, d in pkg_repos.items(): size = sizes.get(p) @@ -44,16 +44,13 @@ def request_optional_deps(pkgname: str, pkg_repos: dict, watcher: ProcessWatcher return {o.value for o in view_opts.values} -def request_install_missing_deps(pkgname: str, deps: List[Tuple[str, str]], watcher: ProcessWatcher, i18n: I18n, context: "TransactionContext") -> bool: +def request_install_missing_deps(pkgname: str, deps: List[Tuple[str, str]], watcher: ProcessWatcher, i18n: I18n) -> bool: msg = '

{}

'.format(i18n['arch.missing_deps.body'].format(name=bold(pkgname) if pkgname else '', deps=bold(str(len(deps))))) opts = [] repo_deps = [d[0] for d in deps if d[1] != 'aur'] - sizes = pacman.get_update_size(repo_deps) if repo_deps else {} - - if context and sizes: - context.pkg_sizes.update(sizes) + sizes = pacman.map_update_sizes(repo_deps) if repo_deps else {} for dep in deps: size = sizes.get(dep[0]) diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 7b6bb9ca..78abfc7e 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -63,7 +63,7 @@ class TransactionContext: install_file: str = None, repository: str = None, pkg: ArchPackage = None, remote_repo_map: Dict[str, str] = None, provided_map: Dict[str, Set[str]] = None, remote_provided_map: Dict[str, Set[str]] = None, aur_idx: Set[str] = None, - missing_deps: List[Tuple[str, str]] = None, pkg_sizes: Dict[str, int] = {}): + missing_deps: List[Tuple[str, str]] = None): self.name = name self.base = base self.maintainer = maintainer @@ -84,7 +84,6 @@ class TransactionContext: self.remote_provided_map = remote_provided_map self.aur_idx = aur_idx self.missing_deps = missing_deps - self.pkg_sizes = pkg_sizes @classmethod def gen_context_from(cls, pkg: ArchPackage, arch_config: dict, root_password: str, handler: ProcessHandler) -> "TransactionContext": @@ -1329,7 +1328,8 @@ class ArchManager(SoftwareManager): downloaded = 0 if self._should_download_packages(context.config): try: - downloaded = self._download_packages(repo_dep_names, context.handler, context.root_password, context.pkg_sizes) + pkg_sizes = pacman.map_download_sizes(repo_dep_names) + downloaded = self._download_packages(repo_dep_names, context.handler, context.root_password, pkg_sizes) except ArchDownloadException: return False @@ -1455,7 +1455,7 @@ class ArchManager(SoftwareManager): def _ask_and_install_missing_deps(self, context: TransactionContext, missing_deps: List[Tuple[str, str]]) -> bool: context.watcher.change_substatus(self.i18n['arch.missing_deps_found'].format(bold(context.name))) - if not confirmation.request_install_missing_deps(context.name, missing_deps, context.watcher, self.i18n, context): + if not confirmation.request_install_missing_deps(context.name, missing_deps, context.watcher, self.i18n): context.watcher.print(self.i18n['action.cancelled']) return False @@ -1612,7 +1612,7 @@ class ArchManager(SoftwareManager): sorted_deps = sorting.sort(to_sort, {**deps_data, **subdeps_data}, provided_map) - if display_deps_dialog and not confirmation.request_install_missing_deps(None, sorted_deps, context.watcher, self.i18n, context): + if display_deps_dialog and not confirmation.request_install_missing_deps(None, sorted_deps, context.watcher, self.i18n): context.watcher.print(self.i18n['action.cancelled']) return True # because the main package installation was successful @@ -1693,7 +1693,8 @@ class ArchManager(SoftwareManager): if to_download: try: - downloaded = self._download_packages(to_download, context.handler, context.root_password, context.pkg_sizes) + pkg_sizes = pacman.map_download_sizes(to_download) + downloaded = self._download_packages(to_download, context.handler, context.root_password, pkg_sizes) except ArchDownloadException: return False @@ -1903,7 +1904,7 @@ class ArchManager(SoftwareManager): context.missing_deps = missing_deps context.watcher.change_substatus(self.i18n['arch.missing_deps_found'].format(bold(context.name))) - if not confirmation.request_install_missing_deps(context.name, missing_deps, context.watcher, self.i18n, context): + if not confirmation.request_install_missing_deps(context.name, missing_deps, context.watcher, self.i18n): context.watcher.print(self.i18n['action.cancelled']) return False @@ -2188,7 +2189,7 @@ class ArchManager(SoftwareManager): else: new.append(p) - new_sizes = pacman.get_update_size(all_names) + new_sizes = pacman.map_update_sizes(all_names) if new_sizes: if new: diff --git a/bauh/gems/arch/pacman.py b/bauh/gems/arch/pacman.py index 1eaf2d22..8f23b66a 100644 --- a/bauh/gems/arch/pacman.py +++ b/bauh/gems/arch/pacman.py @@ -15,6 +15,7 @@ RE_DEP_NOTFOUND = re.compile(r'error:.+\'(.+)\'') RE_DEP_OPERATORS = re.compile(r'[<>=]') RE_INSTALLED_FIELDS = re.compile(r'(Name|Description|Version|Validated By)\s*:\s*(.+)') RE_INSTALLED_SIZE = re.compile(r'Installed Size\s*:\s*([0-9,\.]+)\s(\w+)\n?', re.IGNORECASE) +RE_DOWNLOAD_SIZE = re.compile(r'Download Size\s*:\s*([0-9,\.]+)\s(\w+)\n?', re.IGNORECASE) RE_UPDATE_REQUIRED_FIELDS = re.compile(r'(\bProvides\b|\bInstalled Size\b|\bConflicts With\b)\s*:\s(.+)\n') RE_REMOVE_TRANSITIVE_DEPS = re.compile(r'removing\s([\w\-_]+)\s.+required\sby\s([\w\-_]+)\n?') RE_AVAILABLE_MIRRORS = re.compile(r'.+\s+OK\s+.+\s+(\d+:\d+)\s+.+(http.+)') @@ -505,7 +506,7 @@ def is_mirrors_available() -> bool: return bool(run_cmd('which pacman-mirrors', print_error=False)) -def get_update_size(pkgs: List[str]) -> Dict[str, int]: # bytes: +def map_update_sizes(pkgs: List[str]) -> Dict[str, int]: # bytes: output = run_cmd('pacman -Si {}'.format(' '.join(pkgs))) if output: @@ -514,6 +515,15 @@ def get_update_size(pkgs: List[str]) -> Dict[str, int]: # bytes: return {} +def map_download_sizes(pkgs: List[str]) -> Dict[str, int]: # bytes: + output = run_cmd('pacman -Si {}'.format(' '.join(pkgs))) + + if output: + return {pkgs[idx]: size_to_byte(float(size[0]), size[1]) for idx, size in enumerate(RE_DOWNLOAD_SIZE.findall(output))} + + return {} + + def get_installed_size(pkgs: List[str]) -> Dict[str, int]: # bytes output = run_cmd('pacman -Qi {}'.format(' '.join(pkgs)))