mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 00:04:15 +02:00
[arch] improvement -> AUR: new settings property 'aur_build_only_chosen'
This commit is contained in:
@@ -40,6 +40,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- upgrading firstly the keyring packages declared in **SyncFirst** (**/etc/pacman.conf**) to avoid pacman downloading issues
|
||||
- only removing packages after downloading the required ones
|
||||
- "Multi-threaded download (repositories)" is not the default behavior anymore (current pacman download approach is faster). If your settings has this property set as 'Yes', just change it to 'No'.
|
||||
- preventing a possible error when the optional deps of a given package cannot be found
|
||||
- AUR:
|
||||
- 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.
|
||||
@@ -47,7 +48,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/aur_buildir.png">
|
||||
</p>
|
||||
- new settings property **aur_remove_build_dir** -> it defines if a package's generated build directory should be removed after the operation is finished (installation, upgrading, ...). Default: true
|
||||
- preventing a possible error when the optional deps of a given package cannot be found
|
||||
- new settings property **aur_build_only_chosen**: 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.
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/aur_build_chosen.png">
|
||||
</p>
|
||||
|
||||
- Flatpak
|
||||
- creating the exports path **~/.local/share/flatpak/exports/share** (if it does not exist) and adding it to install/upgrade/downgrade/remove commands path to prevent warning messages. [#128](https://github.com/vinifmor/bauh/issues/128)
|
||||
|
||||
@@ -196,6 +196,7 @@ automatch_providers: true # if a possible provider for a given package dependen
|
||||
edit_aur_pkgbuild: false # if the AUR PKGBUILD file should be displayed for edition before the make process. true (PKGBUILD will always be displayed for edition), false (PKGBUILD never will be displayed), null (a popup will ask if the user want to edit the PKGBUILD). Default: false.
|
||||
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_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.
|
||||
```
|
||||
- Required dependencies:
|
||||
- **pacman**
|
||||
|
||||
@@ -164,8 +164,9 @@ class ProcessHandler:
|
||||
|
||||
return process.subproc.returncode is None or process.subproc.returncode == 0
|
||||
|
||||
def handle_simple(self, proc: SimpleProcess, output_handler=None) -> Tuple[bool, str]:
|
||||
self._notify_watcher((proc.instance.args if isinstance(proc.instance.args, str) else ' '.join(proc.instance.args)) + '\n')
|
||||
def handle_simple(self, proc: SimpleProcess, output_handler=None, notify_watcher: bool = True) -> Tuple[bool, str]:
|
||||
if notify_watcher:
|
||||
self._notify_watcher((proc.instance.args if isinstance(proc.instance.args, str) else ' '.join(proc.instance.args)) + '\n')
|
||||
|
||||
output = StringIO()
|
||||
for o in proc.instance.stdout:
|
||||
@@ -179,8 +180,9 @@ class ProcessHandler:
|
||||
if line:
|
||||
if output_handler:
|
||||
output_handler(line)
|
||||
|
||||
self._notify_watcher(line)
|
||||
|
||||
if notify_watcher:
|
||||
self._notify_watcher(line)
|
||||
|
||||
proc.instance.wait()
|
||||
output.seek(0)
|
||||
|
||||
@@ -46,7 +46,7 @@ def map_pkgbuild(pkgbuild: str) -> dict:
|
||||
return {attr: val.replace('"', '').replace("'", '').replace('(', '').replace(')', '') for attr, val in re.findall(r'\n(\w+)=(.+)', pkgbuild)}
|
||||
|
||||
|
||||
def map_srcinfo(string: str, pkgname: str, fields: Set[str] = None) -> dict:
|
||||
def map_srcinfo(string: str, pkgname: Optional[str], fields: Set[str] = None) -> dict:
|
||||
subinfos, subinfo = [], {}
|
||||
|
||||
key_fields = {'pkgname', 'pkgbase'}
|
||||
@@ -72,7 +72,7 @@ def map_srcinfo(string: str, pkgname: str, fields: Set[str] = None) -> dict:
|
||||
|
||||
pkgnames = {s['pkgname'] for s in subinfos if 'pkgname' in s}
|
||||
return merge_subinfos(subinfos=subinfos,
|
||||
pkgname=None if (len(pkgnames) == 1 or pkgname not in pkgnames) else pkgname,
|
||||
pkgname=None if (not pkgname or len(pkgnames) == 1 or pkgname not in pkgnames) else pkgname,
|
||||
fields=fields)
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ def read_config(update_file: bool = False) -> dict:
|
||||
'automatch_providers': True,
|
||||
'edit_aur_pkgbuild': False,
|
||||
'aur_build_dir': None,
|
||||
'aur_remove_build_dir': True}
|
||||
'aur_remove_build_dir': True,
|
||||
'aur_build_only_chosen': True}
|
||||
return read(CONFIG_FILE, template, update_file=update_file)
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ from bauh.gems.arch.exceptions import PackageNotFoundException
|
||||
from bauh.gems.arch.mapper import ArchDataMapper
|
||||
from bauh.gems.arch.model import ArchPackage
|
||||
from bauh.gems.arch.output import TransactionStatusHandler
|
||||
from bauh.gems.arch.pacman import RE_DEP_OPERATORS
|
||||
from bauh.gems.arch.updates import UpdatesSummarizer
|
||||
from bauh.gems.arch.worker import AURIndexUpdater, ArchDiskCacheUpdater, ArchCompilationOptimizer, SyncDatabases, \
|
||||
RefreshMirrors
|
||||
@@ -56,6 +57,8 @@ RE_SPLIT_VERSION = re.compile(r'([=><]+)')
|
||||
SOURCE_FIELDS = ('source', 'source_x86_64')
|
||||
RE_PRE_DOWNLOAD_WL_PROTOCOLS = re.compile(r'^(.+::)?(https?|ftp)://.+')
|
||||
RE_PRE_DOWNLOAD_BL_EXT = re.compile(r'.+\.(git|gpg)$')
|
||||
RE_PKGBUILD_PKGNAME = re.compile(r'pkgname\s*=.+')
|
||||
RE_CONFLICT_DETECTED = re.compile(r'\n::\s*(.+)\s+are in conflict\s*.')
|
||||
|
||||
|
||||
class TransactionContext:
|
||||
@@ -63,12 +66,13 @@ class TransactionContext:
|
||||
def __init__(self, name: str = None, base: str = None, maintainer: str = None, watcher: ProcessWatcher = None,
|
||||
handler: ProcessHandler = None, dependency: bool = None, skip_opt_deps: bool = False, root_password: str = None,
|
||||
build_dir: str = None, project_dir: str = None, change_progress: bool = False, arch_config: dict = None,
|
||||
install_file: str = None, repository: str = None, pkg: ArchPackage = None,
|
||||
install_files: Set[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, installed: Set[str] = None, removed: Dict[str, SoftwarePackage] = None,
|
||||
disk_loader: DiskCacheLoader = None, disk_cache_updater: Thread = None,
|
||||
new_pkg: bool = False):
|
||||
new_pkg: bool = False, custom_pkgbuild_path: str = None,
|
||||
pkgs_to_build: Set[str] = None):
|
||||
self.name = name
|
||||
self.base = base
|
||||
self.maintainer = maintainer
|
||||
@@ -82,7 +86,7 @@ class TransactionContext:
|
||||
self.change_progress = change_progress
|
||||
self.repository = repository
|
||||
self.config = arch_config
|
||||
self.install_file = install_file
|
||||
self.install_files = install_files
|
||||
self.pkg = pkg
|
||||
self.provided_map = provided_map
|
||||
self.remote_repo_map = remote_repo_map
|
||||
@@ -95,6 +99,8 @@ class TransactionContext:
|
||||
self.disk_cache_updater = disk_cache_updater
|
||||
self.pkgbuild_edited = False
|
||||
self.new_pkg = new_pkg
|
||||
self.custom_pkgbuild_path = custom_pkgbuild_path
|
||||
self.pkgs_to_build = pkgs_to_build
|
||||
|
||||
@classmethod
|
||||
def gen_context_from(cls, pkg: ArchPackage, arch_config: dict, root_password: str, handler: ProcessHandler) -> "TransactionContext":
|
||||
@@ -123,11 +129,14 @@ class TransactionContext:
|
||||
dep_context.removed = {}
|
||||
return dep_context
|
||||
|
||||
def has_install_file(self) -> bool:
|
||||
return self.install_file is not None
|
||||
def has_install_files(self) -> bool:
|
||||
return bool(self.install_files)
|
||||
|
||||
def get_package_path(self) -> str:
|
||||
return self.install_file if self.install_file else self.name
|
||||
def get_packages_paths(self) -> Set[str]:
|
||||
return self.install_files if self.install_files else {self.name}
|
||||
|
||||
def get_package_names(self) -> Set[str]:
|
||||
return self.pkgs_to_build if (self.pkgs_to_build and self.install_files) else {self.name}
|
||||
|
||||
def get_version(self) -> str:
|
||||
return self.pkg.version if self.pkg else None
|
||||
@@ -693,7 +702,7 @@ class ArchManager(SoftwareManager):
|
||||
|
||||
context.watcher.change_progress(50)
|
||||
|
||||
context.install_file = version_files[versions[0]]
|
||||
context.install_files = version_files[versions[0]] # TODO verify
|
||||
if not self._handle_missing_deps(context=context):
|
||||
return False
|
||||
|
||||
@@ -1654,11 +1663,26 @@ class ArchManager(SoftwareManager):
|
||||
'description': 'pkgdesc'}.items():
|
||||
setattr(context.pkg, pkgattr, srcinfo.get(srcattr, getattr(context.pkg, pkgattr)))
|
||||
|
||||
def _read_srcinfo(self, context: TransactionContext) -> str:
|
||||
src_path = '{}/.SRCINFO'.format(context.project_dir)
|
||||
if not os.path.exists(src_path):
|
||||
srcinfo = makepkg.gen_srcinfo(context.project_dir, context.custom_pkgbuild_path)
|
||||
|
||||
with open(src_path, 'w+') as f:
|
||||
f.write(srcinfo)
|
||||
else:
|
||||
with open(src_path) as f:
|
||||
srcinfo = f.read()
|
||||
|
||||
return srcinfo
|
||||
|
||||
def _build(self, context: TransactionContext) -> bool:
|
||||
self._edit_pkgbuild_and_update_context(context)
|
||||
self._pre_download_source(context.name, context.project_dir, context.watcher)
|
||||
self._update_progress(context, 50)
|
||||
|
||||
context.custom_pkgbuild_path = self._gen_custom_pkgbuild_if_required(context)
|
||||
|
||||
if not self._handle_aur_package_deps_and_keys(context):
|
||||
return False
|
||||
|
||||
@@ -1673,7 +1697,10 @@ class ArchManager(SoftwareManager):
|
||||
cpu_optimized = True
|
||||
|
||||
try:
|
||||
pkgbuilt, output = makepkg.make(context.project_dir, optimize=optimize, handler=context.handler)
|
||||
pkgbuilt, output = makepkg.make(pkgdir=context.project_dir,
|
||||
optimize=optimize,
|
||||
handler=context.handler,
|
||||
custom_pkgbuild=context.custom_pkgbuild_path)
|
||||
finally:
|
||||
if cpu_optimized:
|
||||
self.logger.info("Setting cpus to powersave mode")
|
||||
@@ -1682,7 +1709,32 @@ class ArchManager(SoftwareManager):
|
||||
self._update_progress(context, 65)
|
||||
|
||||
if pkgbuilt:
|
||||
gen_file = [fname for root, dirs, files in os.walk(context.build_dir) for fname in files if re.match(r'^{}-.+\.tar\.(xz|zst)'.format(context.name), fname)]
|
||||
self.__fill_aur_output_files(context)
|
||||
|
||||
if self._install(context=context):
|
||||
self._save_pkgbuild(context)
|
||||
|
||||
if context.dependency or context.skip_opt_deps:
|
||||
return True
|
||||
|
||||
context.watcher.change_substatus(self.i18n['arch.optdeps.checking'].format(bold(context.name)))
|
||||
|
||||
self._update_progress(context, 100)
|
||||
if self._install_optdeps(context):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def __fill_aur_output_files(self, context: TransactionContext):
|
||||
self.logger.info("Determining output files of '{}'".format(context.name))
|
||||
context.watcher.change_substatus(self.i18n['arch.aur.build.list_output'])
|
||||
output_files = {f for f in makepkg.list_output_files(context.project_dir, context.custom_pkgbuild_path) if os.path.isfile(f)}
|
||||
|
||||
if output_files:
|
||||
context.install_files = output_files
|
||||
else:
|
||||
gen_file = [fname for root, dirs, files in os.walk(context.build_dir) for fname in files if
|
||||
re.match(r'^{}-.+\.tar\.(xz|zst)'.format(context.name), fname)]
|
||||
|
||||
if not gen_file:
|
||||
context.watcher.print('Could not find the built package. Aborting...')
|
||||
@@ -1702,21 +1754,9 @@ class ArchManager(SoftwareManager):
|
||||
if perfect_match:
|
||||
file_to_install = perfect_match[0]
|
||||
|
||||
context.install_file = '{}/{}'.format(context.project_dir, file_to_install)
|
||||
context.install_files = {'{}/{}'.format(context.project_dir, file_to_install)}
|
||||
|
||||
if self._install(context=context):
|
||||
self._save_pkgbuild(context)
|
||||
|
||||
if context.dependency or context.skip_opt_deps:
|
||||
return True
|
||||
|
||||
context.watcher.change_substatus(self.i18n['arch.optdeps.checking'].format(bold(context.name)))
|
||||
|
||||
self._update_progress(context, 100)
|
||||
if self._install_optdeps(context):
|
||||
return True
|
||||
|
||||
return False
|
||||
context.watcher.change_substatus('')
|
||||
|
||||
def _save_pkgbuild(self, context: TransactionContext):
|
||||
cache_path = ArchPackage.disk_cache_path(context.name)
|
||||
@@ -1761,13 +1801,27 @@ class ArchManager(SoftwareManager):
|
||||
ti = time.time()
|
||||
|
||||
if context.repository == 'aur':
|
||||
with open('{}/.SRCINFO'.format(context.project_dir)) as f:
|
||||
srcinfo = aur.map_srcinfo(string=f.read(), pkgname=context.name)
|
||||
srcinfo = aur.map_srcinfo(string=self._read_srcinfo(context),
|
||||
pkgname=context.name if (not context.pkgs_to_build or len(context.pkgs_to_build) == 1) else None)
|
||||
|
||||
if context.pkgs_to_build and len(context.pkgs_to_build) > 1: # removing self dependencies from srcinfo
|
||||
for attr in ('depends', 'makedepends', 'optdepends'):
|
||||
dep_list = srcinfo.get(attr)
|
||||
|
||||
if dep_list and isinstance(dep_list, list):
|
||||
to_remove = set()
|
||||
for dep in dep_list:
|
||||
dep_name = RE_DEP_OPERATORS.split(dep.split(':')[0])[0].strip()
|
||||
|
||||
if dep_name and dep_name in context.pkgs_to_build:
|
||||
to_remove.add(dep)
|
||||
|
||||
for dep in to_remove:
|
||||
dep_list.remove(dep)
|
||||
|
||||
pkgs_data = {context.name: self.aur_client.map_update_data(context.name, context.get_version(), srcinfo)}
|
||||
else:
|
||||
file = bool(context.install_file)
|
||||
pkgs_data = pacman.map_updates_data({context.install_file if file else context.name}, files=file)
|
||||
pkgs_data = pacman.map_updates_data(context.get_packages_paths(), files=bool(context.install_files))
|
||||
|
||||
deps_data, alread_checked_deps = {}, set()
|
||||
|
||||
@@ -1807,7 +1861,8 @@ class ArchManager(SoftwareManager):
|
||||
check_res = makepkg.check(context.project_dir,
|
||||
optimize=bool(context.config['optimize']),
|
||||
missing_deps=False,
|
||||
handler=context.handler)
|
||||
handler=context.handler,
|
||||
custom_pkgbuild=context.custom_pkgbuild_path)
|
||||
|
||||
if check_res:
|
||||
if check_res.get('gpg_key'):
|
||||
@@ -1952,22 +2007,28 @@ class ArchManager(SoftwareManager):
|
||||
raise ArchDownloadException()
|
||||
|
||||
def _install(self, context: TransactionContext) -> bool:
|
||||
check_install_output = []
|
||||
pkgpath = context.get_package_path()
|
||||
pkgpaths = context.get_packages_paths()
|
||||
|
||||
context.watcher.change_substatus(self.i18n['arch.checking.conflicts'].format(bold(context.name)))
|
||||
self.logger.info("Checking for possible conflicts with '{}'".format(context.name))
|
||||
|
||||
for check_out in SimpleProcess(cmd=['pacman', '-U' if context.install_file else '-S', pkgpath],
|
||||
root_password=context.root_password,
|
||||
cwd=context.project_dir or '.').instance.stdout:
|
||||
check_install_output.append(check_out.decode())
|
||||
_, output = context.handler.handle_simple(pacman.install_as_process(pkgpaths=pkgpaths,
|
||||
root_password=context.root_password,
|
||||
pkgdir=context.project_dir or '.',
|
||||
file=bool(context.install_files),
|
||||
simulate=True),
|
||||
notify_watcher=False)
|
||||
# for check_out in SimpleProcess(cmd=['pacman', '-U' if context.install_files else '-S', pkgpath],
|
||||
# root_password=context.root_password,
|
||||
# cwd=context.project_dir or '.').instance.stdout:
|
||||
# check_install_output.append(check_out.decode())
|
||||
|
||||
self._update_progress(context, 70)
|
||||
|
||||
if check_install_output and 'conflict' in check_install_output[-1]:
|
||||
if 'unresolvable package conflicts detected' in output:
|
||||
self.logger.info("Conflicts detected for '{}'".format(context.name))
|
||||
conflicting_apps = [w[0] for w in re.findall(r'((\w|\-|\.)+)\s(and|are)', check_install_output[-1])]
|
||||
conflict_msgs = RE_CONFLICT_DETECTED.findall(output)
|
||||
conflicting_apps = {n.strip() for m in conflict_msgs for n in m.split(' and ')}
|
||||
conflict_msg = ' {} '.format(self.i18n['and']).join([bold(c) for c in conflicting_apps])
|
||||
if not context.watcher.request_confirmation(title=self.i18n['arch.install.conflict.popup.title'],
|
||||
body=self.i18n['arch.install.conflict.popup.body'].format(conflict_msg)):
|
||||
@@ -1975,7 +2036,8 @@ class ArchManager(SoftwareManager):
|
||||
return False
|
||||
else: # uninstall conflicts
|
||||
self._update_progress(context, 75)
|
||||
to_uninstall = [conflict for conflict in conflicting_apps if conflict != context.name]
|
||||
names_to_install = context.get_package_names()
|
||||
to_uninstall = [conflict for conflict in conflicting_apps if conflict not in names_to_install]
|
||||
|
||||
self.logger.info("Preparing to uninstall conflicting packages: {}".format(to_uninstall))
|
||||
|
||||
@@ -2006,7 +2068,7 @@ class ArchManager(SoftwareManager):
|
||||
if context.missing_deps:
|
||||
to_install.extend((d[0] for d in context.missing_deps))
|
||||
|
||||
to_install.append(pkgpath)
|
||||
to_install.extend(pkgpaths)
|
||||
|
||||
downloaded = 0
|
||||
if self._multithreaded_download_enabled(context.config):
|
||||
@@ -2027,7 +2089,7 @@ class ArchManager(SoftwareManager):
|
||||
else:
|
||||
status_handler = None
|
||||
|
||||
installed_with_same_name = self.read_installed(disk_loader=context.disk_loader, internet_available=True, names={context.name}).installed
|
||||
installed_with_same_name = self.read_installed(disk_loader=context.disk_loader, internet_available=True, names=context.get_package_names()).installed
|
||||
context.watcher.change_substatus(self.i18n['arch.installing.package'].format(bold(context.name)))
|
||||
installed = self._handle_install_call(context=context, to_install=to_install, status_handler=status_handler)
|
||||
|
||||
@@ -2038,7 +2100,7 @@ class ArchManager(SoftwareManager):
|
||||
self._update_progress(context, 95)
|
||||
|
||||
if installed:
|
||||
context.installed.add(context.name)
|
||||
context.installed.update(context.get_package_names())
|
||||
context.installed.update((p for p in to_install if not p.startswith('/')))
|
||||
|
||||
if installed_with_same_name:
|
||||
@@ -2091,7 +2153,7 @@ class ArchManager(SoftwareManager):
|
||||
def _call_pacman_install(self, context: TransactionContext, to_install: List[str], overwrite_files: bool, status_handler: Optional[object] = None) -> Tuple[bool, str]:
|
||||
return context.handler.handle_simple(pacman.install_as_process(pkgpaths=to_install,
|
||||
root_password=context.root_password,
|
||||
file=context.has_install_file(),
|
||||
file=context.has_install_files(),
|
||||
pkgdir=context.project_dir,
|
||||
overwrite_conflicting_files=overwrite_files),
|
||||
output_handler=status_handler.handle if status_handler else None)
|
||||
@@ -2520,6 +2582,17 @@ class ArchManager(SoftwareManager):
|
||||
only_int=True,
|
||||
max_width=max_width,
|
||||
value=local_config['mirrors_sort_limit'] if isinstance(local_config['mirrors_sort_limit'], int) else ''),
|
||||
new_select(id_='aur_build_only_chosen',
|
||||
label=self.i18n['arch.config.aur_build_only_chosen'],
|
||||
tip=self.i18n['arch.config.aur_build_only_chosen.tip'],
|
||||
opts=[(self.i18n['yes'].capitalize(), True, None),
|
||||
(self.i18n['no'].capitalize(), False, None),
|
||||
(self.i18n['ask'].capitalize(), None, None),
|
||||
],
|
||||
value=local_config['aur_build_only_chosen'],
|
||||
max_width=max_width,
|
||||
type_=SelectViewType.RADIO,
|
||||
capitalize_label=False),
|
||||
new_select(label=self.i18n['arch.config.edit_aur_pkgbuild'],
|
||||
tip=self.i18n['arch.config.edit_aur_pkgbuild.tip'],
|
||||
id_='edit_aur_pkgbuild',
|
||||
@@ -2565,6 +2638,7 @@ class ArchManager(SoftwareManager):
|
||||
config['edit_aur_pkgbuild'] = form_install.get_component('edit_aur_pkgbuild').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_only_chosen'] = form_install.get_component('aur_build_only_chosen').get_selected()
|
||||
|
||||
if not config['aur_build_dir']:
|
||||
config['aur_build_dir'] = None
|
||||
@@ -2932,3 +3006,61 @@ class ArchManager(SoftwareManager):
|
||||
body=self.i18n['snap.custom_action.setup_snapd.ready.body'],
|
||||
type_=MessageType.INFO)
|
||||
return True
|
||||
|
||||
def _gen_custom_pkgbuild_if_required(self, context: TransactionContext) -> Optional[str]:
|
||||
build_only_chosen = context.config.get('aur_build_only_chosen')
|
||||
|
||||
pkgs_to_build = aur.map_srcinfo(string=self._read_srcinfo(context), pkgname=None, fields={'pkgname'}).get('pkgname')
|
||||
|
||||
if isinstance(pkgs_to_build, str):
|
||||
pkgs_to_build = {pkgs_to_build}
|
||||
else:
|
||||
pkgs_to_build = {*pkgs_to_build}
|
||||
|
||||
if build_only_chosen is False:
|
||||
context.pkgs_to_build = pkgs_to_build
|
||||
return
|
||||
|
||||
# checking if more than one package is mapped for this pkgbuild
|
||||
|
||||
if not pkgs_to_build or not isinstance(pkgs_to_build, set) or len(pkgs_to_build) == 1 or context.name not in pkgs_to_build:
|
||||
context.pkgs_to_build = pkgs_to_build
|
||||
return
|
||||
|
||||
if build_only_chosen is None:
|
||||
if not context.dependency:
|
||||
pkgnames = [InputOption(label=n, value=n, read_only=False) for n in pkgs_to_build if n != context.name]
|
||||
select = MultipleSelectComponent(label='',
|
||||
options=pkgnames,
|
||||
default_options={*pkgnames},
|
||||
max_per_line=1)
|
||||
|
||||
if not context.watcher.request_confirmation(title=self.i18n['warning'].capitalize(),
|
||||
body=self.i18n['arch.aur.sync.several_names.popup.body'].format(bold(context.name)) + ':',
|
||||
components=[select],
|
||||
confirmation_label=self.i18n['arch.aur.sync.several_names.popup.bt_only_chosen'].format(context.name),
|
||||
deny_label=self.i18n['arch.aur.sync.several_names.popup.bt_selected']):
|
||||
context.pkgs_to_build = {context.name, *select.get_selected_values()}
|
||||
|
||||
pkgbuild_path = '{}/PKGBUILD'.format(context.project_dir)
|
||||
with open(pkgbuild_path) as f:
|
||||
current_pkgbuild = f.read()
|
||||
|
||||
if context.pkgs_to_build:
|
||||
names = '({})'.format(' '.join(("'{}'".format(p) for p in context.pkgs_to_build)))
|
||||
else:
|
||||
names = context.name
|
||||
context.pkgs_to_build = {context.name}
|
||||
|
||||
new_pkgbuild = RE_PKGBUILD_PKGNAME.sub("pkgname={}".format(names), current_pkgbuild)
|
||||
custom_pkgbuild_path = pkgbuild_path + '_CUSTOM'
|
||||
|
||||
with open(custom_pkgbuild_path, 'w+') as f:
|
||||
f.write(new_pkgbuild)
|
||||
|
||||
new_srcinfo = makepkg.gen_srcinfo(context.project_dir, custom_pkgbuild_path)
|
||||
|
||||
with open('{}/.SRCINFO'.format(context.project_dir), 'w+') as f:
|
||||
f.write(new_srcinfo)
|
||||
|
||||
return custom_pkgbuild_path
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
import re
|
||||
from typing import Tuple
|
||||
from typing import Tuple, Optional, Set
|
||||
|
||||
from bauh.commons.system import SimpleProcess, ProcessHandler, run_cmd
|
||||
from bauh.gems.arch import CUSTOM_MAKEPKG_FILE
|
||||
@@ -9,18 +9,23 @@ RE_DEPS_PATTERN = re.compile(r'\n?\s+->\s(.+)\n')
|
||||
RE_UNKNOWN_GPG_KEY = re.compile(r'\(unknown public key (\w+)\)')
|
||||
|
||||
|
||||
def gen_srcinfo(build_dir: str) -> str:
|
||||
return run_cmd('makepkg --printsrcinfo', cwd=build_dir)
|
||||
def gen_srcinfo(build_dir: str, custom_pkgbuild_path: Optional[str] = None) -> str:
|
||||
return run_cmd('makepkg --printsrcinfo{}'.format(' -p {}'.format(custom_pkgbuild_path) if custom_pkgbuild_path else ''),
|
||||
cwd=build_dir)
|
||||
|
||||
|
||||
def check(pkgdir: str, optimize: bool, missing_deps: bool, handler: ProcessHandler) -> dict:
|
||||
def check(pkgdir: str, optimize: bool, missing_deps: bool, handler: ProcessHandler, custom_pkgbuild: Optional[str] = None) -> dict:
|
||||
res = {}
|
||||
|
||||
cmd = ['makepkg', '-ALcf', '--check', '--noarchive', '--nobuild', '--noprepare']
|
||||
cmd = ['makepkg', '-ALcfm', '--check', '--noarchive', '--nobuild', '--noprepare']
|
||||
|
||||
if not missing_deps:
|
||||
cmd.append('--nodeps')
|
||||
|
||||
if custom_pkgbuild:
|
||||
cmd.append('-p')
|
||||
cmd.append(custom_pkgbuild)
|
||||
|
||||
if optimize:
|
||||
if os.path.exists(CUSTOM_MAKEPKG_FILE):
|
||||
handler.watcher.print('Using custom makepkg.conf -> {}'.format(CUSTOM_MAKEPKG_FILE))
|
||||
@@ -44,9 +49,13 @@ def check(pkgdir: str, optimize: bool, missing_deps: bool, handler: ProcessHandl
|
||||
return res
|
||||
|
||||
|
||||
def make(pkgdir: str, optimize: bool, handler: ProcessHandler) -> Tuple[bool, str]:
|
||||
def make(pkgdir: str, optimize: bool, handler: ProcessHandler, custom_pkgbuild: Optional[str] = None) -> Tuple[bool, str]:
|
||||
cmd = ['makepkg', '-ALcsmf', '--skipchecksums']
|
||||
|
||||
if custom_pkgbuild:
|
||||
cmd.append('-p')
|
||||
cmd.append(custom_pkgbuild)
|
||||
|
||||
if optimize:
|
||||
if os.path.exists(CUSTOM_MAKEPKG_FILE):
|
||||
handler.watcher.print('Using custom makepkg.conf -> {}'.format(CUSTOM_MAKEPKG_FILE))
|
||||
@@ -66,3 +75,14 @@ def update_srcinfo(project_dir: str) -> bool:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def list_output_files(project_dir: str, custom_pkgbuild_path: Optional[str] = None) -> Set[str]:
|
||||
output = run_cmd(cmd='makepkg --packagelist{}'.format(' -p {}'.format(custom_pkgbuild_path) if custom_pkgbuild_path else ''),
|
||||
print_error=False,
|
||||
cwd=project_dir)
|
||||
|
||||
if output:
|
||||
return {p.strip() for p in output.split('\n') if p}
|
||||
|
||||
return set()
|
||||
|
||||
@@ -141,11 +141,13 @@ def map_installed(names: Iterable[str] = None) -> dict: # returns a dict with w
|
||||
return pkgs
|
||||
|
||||
|
||||
def install_as_process(pkgpaths: Iterable[str], root_password: str, file: bool, pkgdir: str = '.', overwrite_conflicting_files: bool = False) -> SimpleProcess:
|
||||
if file:
|
||||
cmd = ['pacman', '-U', *pkgpaths, '--noconfirm'] # pkgpath = install file path
|
||||
else:
|
||||
cmd = ['pacman', '-S', *pkgpaths, '--noconfirm'] # pkgpath = pkgname
|
||||
def install_as_process(pkgpaths: Iterable[str], root_password: str, file: bool, pkgdir: str = '.',
|
||||
overwrite_conflicting_files: bool = False, simulate: bool = False) -> SimpleProcess:
|
||||
cmd = ['pacman', '-U'] if file else ['pacman', '-S']
|
||||
cmd.extend(pkgpaths)
|
||||
|
||||
if not simulate:
|
||||
cmd.append('--noconfirm')
|
||||
|
||||
if overwrite_conflicting_files:
|
||||
cmd.append('--overwrite=*')
|
||||
|
||||
@@ -21,6 +21,10 @@ arch.aur.install.validity_check.body=Alguns dels fitxers font necessaris per a l
|
||||
arch.aur.install.validity_check.proceed=Voleu continuar de totes maneres? ( no es recomana )
|
||||
arch.aur.install.validity_check.title=Problemes d’integritat {}
|
||||
arch.aur.install.verifying_pgp=S’estan comprovant les claus PGP
|
||||
arch.aur.build.list_output=Checking built files
|
||||
arch.aur.sync.several_names.popup.body=The definition file (PKGBUILD) of {} configures the build of other packages
|
||||
arch.aur.sync.several_names.popup.bt_only_chosen=Build only {}
|
||||
arch.aur.sync.several_names.popup.bt_selected=Build selected too
|
||||
arch.building.package=S’està compilant el paquet {}
|
||||
arch.checking.conflicts=S’està comprovant si hi ha conflictes amb {}
|
||||
arch.checking.deps=S’estan comprovant les dependències de {}
|
||||
@@ -32,6 +36,8 @@ arch.config.automatch_providers=Auto-define dependency providers
|
||||
arch.config.automatch_providers.tip=It automatically chooses which provider will be used for a package dependency when both names are equal.
|
||||
arch.config.aur_build_dir=Build directory (AUR)
|
||||
arch.config.aur_build_dir.tip=It define a custom directory where the AUR packages will be built. Default: {}.
|
||||
arch.config.aur_build_only_chosen=Build only chosen (AUR)
|
||||
arch.config.aur_build_only_chosen.tip=Some AUR packages have a common PKGBUILD shared with other packages and that defines build instructions for each one. This property enabled will ensure that only the chosen package will be built.
|
||||
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.clean_cache=Elimina les versions antigues
|
||||
|
||||
@@ -21,6 +21,10 @@ arch.aur.install.validity_check.body=Einige der Source-Dateien für die Installa
|
||||
arch.aur.install.validity_check.proceed=Wollen Sie trotzdem fortfahren? ( nicht empfohlen )
|
||||
arch.aur.install.validity_check.title=Integritätsprobleme {}
|
||||
arch.aur.install.verifying_pgp=PGP Schlüssel überprüfen
|
||||
arch.aur.build.list_output=Checking built files
|
||||
arch.aur.sync.several_names.popup.body=The definition file (PKGBUILD) of {} configures the build of other packages
|
||||
arch.aur.sync.several_names.popup.bt_only_chosen=Build only {}
|
||||
arch.aur.sync.several_names.popup.bt_selected=Build selected too
|
||||
arch.building.package=Paket {} erstellen
|
||||
arch.checking.conflicts=Konflikte mit {} überprüfen
|
||||
arch.checking.deps={} Abhängigkeiten überprüfen
|
||||
@@ -32,6 +36,8 @@ arch.config.automatch_providers=Auto-define dependency providers
|
||||
arch.config.automatch_providers.tip=It automatically chooses which provider will be used for a package dependency when both names are equal.
|
||||
arch.config.aur_build_dir=Build directory (AUR)
|
||||
arch.config.aur_build_dir.tip=It define a custom directory where the AUR packages will be built. Default: {}.
|
||||
arch.config.aur_build_only_chosen=Build only chosen (AUR)
|
||||
arch.config.aur_build_only_chosen.tip=Some AUR packages have a common PKGBUILD shared with other packages and that defines build instructions for each one. This property enabled will ensure that only the chosen package will be built.
|
||||
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.clean_cache=Remove old versions
|
||||
|
||||
@@ -22,6 +22,10 @@ arch.aur.install.validity_check.body=Some of the source-files needed for {} inst
|
||||
arch.aur.install.validity_check.proceed=Do you want to continue anyway ? ( not recommended )
|
||||
arch.aur.install.validity_check.title=Integrity issues {}
|
||||
arch.aur.install.verifying_pgp=Verifying PGP keys
|
||||
arch.aur.build.list_output=Checking built files
|
||||
arch.aur.sync.several_names.popup.body=The definition file (PKGBUILD) of {} configures the build of other packages
|
||||
arch.aur.sync.several_names.popup.bt_only_chosen=Build only {}
|
||||
arch.aur.sync.several_names.popup.bt_selected=Build selected too
|
||||
arch.building.package=Building package {}
|
||||
arch.checking.conflicts=Checking any conflicts with {}
|
||||
arch.checking.deps=Checking {} dependencies
|
||||
@@ -33,6 +37,8 @@ arch.config.automatch_providers=Auto-define dependency providers
|
||||
arch.config.automatch_providers.tip=It automatically chooses which provider will be used for a package dependency when both names are equal.
|
||||
arch.config.aur_build_dir=Build directory (AUR)
|
||||
arch.config.aur_build_dir.tip=It define a custom directory where the AUR packages will be built. Default: {}.
|
||||
arch.config.aur_build_only_chosen=Build only chosen (AUR)
|
||||
arch.config.aur_build_only_chosen.tip=Some AUR packages have a common PKGBUILD shared with other packages and that defines build instructions for each one. This property enabled will ensure that only the chosen package will be built.
|
||||
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.clean_cache=Remove old versions
|
||||
|
||||
@@ -21,6 +21,10 @@ arch.aur.install.validity_check.body=Algunos de los archivos fuente necesarios p
|
||||
arch.aur.install.validity_check.proceed=¿Desea continuar de todos modos? ( no recomendado )
|
||||
arch.aur.install.validity_check.title=Problemas de integridad {}
|
||||
arch.aur.install.verifying_pgp=Verificando claves PGP
|
||||
arch.aur.build.list_output=Checking built files
|
||||
arch.aur.sync.several_names.popup.body=El archivo de definición (PKGBUILD) de {} configura la compilación de otros paquetes
|
||||
arch.aur.sync.several_names.popup.bt_only_chosen=Compilar sólo {}
|
||||
arch.aur.sync.several_names.popup.bt_selected=Compilar seleccionados también
|
||||
arch.building.package=Construyendo el paquete {}
|
||||
arch.checking.conflicts=Verificando se hay conflictos con {}
|
||||
arch.checking.deps=Verificando las dependencias de {}
|
||||
@@ -32,6 +36,8 @@ arch.config.automatch_providers=Autodefinir proveedores de dependencia
|
||||
arch.config.automatch_providers.tip=Elige automáticamente qué proveedor se usará para una dependencia de paquete cuando ambos nombres son iguales.
|
||||
arch.config.aur_build_dir=Directorio de compilación (AUR)
|
||||
arch.config.aur_build_dir.tip=Define un directorio personalizado donde se construirán los paquetes AUR. Defecto: {}.
|
||||
arch.config.aur_build_only_chosen=Compilar solo elegido (AUR)
|
||||
arch.config.aur_build_only_chosen.tip=Algunos paquetes AUR tienen un PKGBUILD común compartido con otros paquetes y que define las instrucciones de construcción para cada uno. Esta propiedad habilitada garantizará que solo se compile el paquete elegido.
|
||||
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.clean_cache=Eliminar versiones antiguas
|
||||
|
||||
@@ -21,6 +21,10 @@ arch.aur.install.validity_check.body=Alcuni dei file di origine necessari per l'
|
||||
arch.aur.install.validity_check.proceed=Vuoi continuare comunque? ( non consigliato )
|
||||
arch.aur.install.validity_check.title=Problemi di integrità {}
|
||||
arch.aur.install.verifying_pgp=Verifica chiavi PGP
|
||||
arch.aur.build.list_output=Checking built files
|
||||
arch.aur.sync.several_names.popup.body=The definition file (PKGBUILD) of {} configures the build of other packages
|
||||
arch.aur.sync.several_names.popup.bt_only_chosen=Build only {}
|
||||
arch.aur.sync.several_names.popup.bt_selected=Build selected too
|
||||
arch.building.package=Pacchetto costruito {}
|
||||
arch.checking.conflicts=Verifica di eventuali conflitti con {}
|
||||
arch.checking.deps=Verifica di {} dipendenze
|
||||
@@ -32,6 +36,8 @@ arch.config.automatch_providers=Auto-define dependency providers
|
||||
arch.config.automatch_providers.tip=It automatically chooses which provider will be used for a package dependency when both names are equal.
|
||||
arch.config.aur_build_dir=Build directory (AUR)
|
||||
arch.config.aur_build_dir.tip=It define a custom directory where the AUR packages will be built. Default: {}.
|
||||
arch.config.aur_build_only_chosen=Build only chosen (AUR)
|
||||
arch.config.aur_build_only_chosen.tip=Some AUR packages have a common PKGBUILD shared with other packages and that defines build instructions for each one. This property enabled will ensure that only the chosen package will be built.
|
||||
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.clean_cache=Rimuovi le vecchie versioni
|
||||
|
||||
@@ -22,6 +22,10 @@ arch.aur.install.validity_check.body=Alguns dos arquivos-fonte necessários para
|
||||
arch.aur.install.validity_check.proceed=Você deseja continuar mesmo assim ? ( não recomendado )
|
||||
arch.aur.install.validity_check.title=Problemas de integridade {}
|
||||
arch.aur.install.verifying_pgp=Verificando chaves PGP
|
||||
arch.aur.build.list_output=Verificando arquivos construídos
|
||||
arch.aur.sync.several_names.popup.body=O arquivo de definição (PKGBUILD) de {} configura a construção de outros pacotes
|
||||
arch.aur.sync.several_names.popup.bt_only_chosen=Construir somente {}
|
||||
arch.aur.sync.several_names.popup.bt_selected=Construir selecionados também
|
||||
arch.building.package=Construindo o pacote {}
|
||||
arch.checking.conflicts=Verificando se há conflitos com {}
|
||||
arch.checking.deps=Verificando as dependências de {}
|
||||
@@ -33,6 +37,8 @@ arch.config.automatch_providers=Auto-definir provedores de dependências
|
||||
arch.config.automatch_providers.tip=Escolhe automaticamente qual provedor será utilizado para determinada dependência de um pacote caso os nomes de ambos sejam iguais.
|
||||
arch.config.aur_build_dir=Diretório de construção (AUR)
|
||||
arch.config.aur_build_dir.tip=Define um diretório personalizado onde pacotes do AUR serão construídos. Padrão: {}.
|
||||
arch.config.aur_build_only_chosen=Construir somente escolhido (AUR)
|
||||
arch.config.aur_build_only_chosen.tip=Alguns pacotes do AUR têm um PKGBUILD comum a outros pacotes e que define a construção para todos. Essa propriedade ativada garantirá que somente o pacote escolhido será construído.
|
||||
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.clean_cache=Remover versões antigas
|
||||
|
||||
@@ -21,6 +21,10 @@ arch.aur.install.validity_check.body=Некоторые исходные фай
|
||||
arch.aur.install.validity_check.proceed=Вы всё равно хотите продолжить ? ( не рекомендуется )
|
||||
arch.aur.install.validity_check.title=Проблемы целостности
|
||||
arch.aur.install.verifying_pgp=Проверка ключей PGP
|
||||
arch.aur.build.list_output=Checking built files
|
||||
arch.aur.sync.several_names.popup.body=The definition file (PKGBUILD) of {} configures the build of other packages
|
||||
arch.aur.sync.several_names.popup.bt_only_chosen=Build only {}
|
||||
arch.aur.sync.several_names.popup.bt_selected=Build selected too
|
||||
arch.building.package=Сборка пакета {}
|
||||
arch.checking.conflicts=Проверка конфликтов с {}
|
||||
arch.checking.deps=Проверка зависимостей {}
|
||||
@@ -32,6 +36,8 @@ arch.config.automatch_providers=Auto-define dependency providers
|
||||
arch.config.automatch_providers.tip=It automatically chooses which provider will be used for a package dependency when both names are equal.
|
||||
arch.config.aur_build_dir=Build directory (AUR)
|
||||
arch.config.aur_build_dir.tip=It define a custom directory where the AUR packages will be built. Default: {}.
|
||||
arch.config.aur_build_only_chosen=Build only chosen (AUR)
|
||||
arch.config.aur_build_only_chosen.tip=Some AUR packages have a common PKGBUILD shared with other packages and that defines build instructions for each one. This property enabled will ensure that only the chosen package will be built.
|
||||
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.clean_cache=Remove old versions
|
||||
|
||||
@@ -21,6 +21,10 @@ arch.aur.install.validity_check.body={} kurulumu için gereken kaynak dosyalarda
|
||||
arch.aur.install.validity_check.proceed=Yine de devam etmek istiyor musunuz? ( önerilmez )
|
||||
arch.aur.install.validity_check.title=Bütünlük sorunları {}
|
||||
arch.aur.install.verifying_pgp=PGP anahtarları doğrulanıyor
|
||||
arch.aur.build.list_output=Checking built files
|
||||
arch.aur.sync.several_names.popup.body=The definition file (PKGBUILD) of {} configures the build of other packages
|
||||
arch.aur.sync.several_names.popup.bt_only_chosen=Build only {}
|
||||
arch.aur.sync.several_names.popup.bt_selected=Build selected too
|
||||
arch.building.package=Paket inşa ediliyor {}
|
||||
arch.checking.conflicts={} ile çakışmalar kontrol ediliyor
|
||||
arch.checking.deps={} bağımlılıkları kontrol ediliyor
|
||||
@@ -32,6 +36,8 @@ arch.config.automatch_providers=Auto-define dependency providers
|
||||
arch.config.automatch_providers.tip=It automatically chooses which provider will be used for a package dependency when both names are equal.
|
||||
arch.config.aur_build_dir=Build directory (AUR)
|
||||
arch.config.aur_build_dir.tip=It define a custom directory where the AUR packages will be built. Default: {}.
|
||||
arch.config.aur_build_only_chosen=Build only chosen (AUR)
|
||||
arch.config.aur_build_only_chosen.tip=Some AUR packages have a common PKGBUILD shared with other packages and that defines build instructions for each one. This property enabled will ensure that only the chosen package will be built.
|
||||
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.clean_cache=Önbelleği temizle
|
||||
|
||||
Reference in New Issue
Block a user