[feature][arch] supporting multi-threaded download for repository packages

This commit is contained in:
Vinícius Moreira
2020-05-27 11:51:24 -03:00
parent 12055fe0e1
commit cec0c06e4f
24 changed files with 402 additions and 51 deletions

View File

@@ -3,6 +3,7 @@ import re
from threading import Thread
from typing import List, Set, Tuple, Dict, Iterable
from bauh.commons import system
from bauh.commons.system import run_cmd, new_subprocess, new_root_subprocess, SystemProcess, SimpleProcess, \
ProcessHandler
from bauh.commons.util import size_to_byte
@@ -16,6 +17,7 @@ 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_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.+)')
def is_available() -> bool:
@@ -599,6 +601,36 @@ def map_provided(remote: bool = False, pkgs: Iterable[str] = None) -> Dict[str,
return provided_map
def list_download_data(pkgs: Iterable[str]) -> List[Dict[str, str]]:
_, output = system.run(['pacman', '-Si', *pkgs])
if output:
res = []
data = {'a': None, 'v': None, 'r': None, 'n': None}
for l in output.split('\n'):
if l:
if l[0] != ' ':
line = l.strip()
field_sep_idx = line.index(':')
field = line[0:field_sep_idx].strip()
val = line[field_sep_idx + 1:].strip()
if field == 'Repository':
data['r'] = val
elif field == 'Name':
data['n'] = val
elif field == 'Version':
data['v'] = val.split('=')[0]
elif field == 'Architecture':
data['a'] = val
elif data.get('a'):
res.append(data)
data = {'a': None, 'v': None, 'r': None, 'n': None}
return res
def map_updates_data(pkgs: Iterable[str], files: bool = False) -> dict:
if files:
output = run_cmd('pacman -Qi -p {}'.format(' '.join(pkgs)))
@@ -1021,3 +1053,19 @@ def list_installed_names() -> Set[str]:
output = run_cmd('pacman -Qq', print_error=False)
return {name.strip() for name in output.split('\n') if name} if output else set()
def list_available_mirrors() -> List[str]:
_, output = system.run(['pacman-mirrors', '--status', '--no-color'])
if output:
mirrors = RE_AVAILABLE_MIRRORS.findall(output)
if mirrors:
mirrors.sort(key=lambda o: o[0])
return [m[1] for m in mirrors]
def get_mirrors_branch() -> str:
_, output = system.run(['pacman-mirrors', '-G'])
return output.strip()