Skip to content

Commit

Permalink
0.9.5
Browse files Browse the repository at this point in the history
  • Loading branch information
vinifmor authored Jun 7, 2020
2 parents b8a494a + 40c4934 commit 0d4d421
Show file tree
Hide file tree
Showing 32 changed files with 319 additions and 80 deletions.
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,47 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [0.9.5] 2020-06-07
### Features
- new custom action (**+**) to open the system backups (snapshots). It is just a shortcut to Timeshift.
<p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh/staging/pictures/releases/0.9.5/backup_action.png">
</p>

### Improvements
- Arch
- new **automatch_providers** settings: bauh will automatically choose which provider will be used for a package dependency when both names are equal (enabled by default).
<p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh/staging/pictures/releases/0.9.5/arch_providers.png">
</p>

- UI
- not limiting the name filter size
- rendering package icons with no full paths declared
- refreshing custom actions (**+**) after installing/uninstalling/downgrading/upgrading packages
- minor improvements
- download clients parameters

### Fixes
- regressions (from **0.9.4**)
- resetting the main configuration when tray mode is active [#118](https://github.com/vinifmor/bauh/issues/118)
- bauh-cli crashing
- tray mode not publishing update notifications
- Arch: not checking if **pacman-mirrors** is available before starting to download repository packages (when multi-threaded download is enabled) [#117](https://github.com/vinifmor/bauh/issues/117)
- Arch
- uninstall: not checking if there are other installed providers for the target package
- not recursively asking for dependencies providers when installing / upgrading / downgrading
- not displaying "removing" substatus during the upgrade process
- UI
- table overwrite effect when updating its content

### i18n contributions

- Turkish (tr): [tulliana](https://github.com/tulliana)


## [0.9.4] 2020-05-29

### Features
- Ignore updates: now it is possible to ignore updates from software packages through their actions button (**+**). Supported types: Arch packages, Flatpaks and AppImages

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ mirrors_sort_limit: 5 # defines the maximum number of mirrors that will be used
aur: true # allows to manage AUR packages
repositories: true # allows to manage packages from the configured repositories
repositories_mthread_download: true # enable multi-threaded download for repository packages if aria2 is installed
automatch_providers: true # if a possible provider for a given package dependency exactly matches its name, it will be chosen instead of asking for the user to decide (false).
```
- Required dependencies:
- **pacman**
Expand Down
2 changes: 1 addition & 1 deletion bauh/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '0.9.4'
__version__ = '0.9.5'
__app_name__ = 'bauh'

import os
Expand Down
2 changes: 1 addition & 1 deletion bauh/cli/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def main():
logger=logger,
distro=util.get_distro(),
file_downloader=AdaptableFileDownloader(logger, bool(app_config['download']['multithreaded']),
i18n, http_client),
i18n, http_client, app_config['download']['multithreaded_client']),
app_name=__app_name__)

managers = gems.load_managers(context=context, locale=i18n.current_key, config=app_config, default_locale=DEFAULT_I18N_KEY)
Expand Down
2 changes: 1 addition & 1 deletion bauh/commons/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

def deep_update(source: dict, overrides: dict):
for key, value in overrides.items():
if isinstance(value, collections.Mapping) and value:
if isinstance(value, dict):
returned = deep_update(source.get(key, {}), value)
source[key] = returned
else:
Expand Down
3 changes: 2 additions & 1 deletion bauh/gems/arch/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ def read_config(update_file: bool = False) -> dict:
"refresh_mirrors_startup": False,
"sync_databases_startup": True,
'mirrors_sort_limit': 5,
'repositories_mthread_download': True}
'repositories_mthread_download': True,
'automatch_providers': True}
return read(CONFIG_FILE, template, update_file=update_file)
51 changes: 47 additions & 4 deletions bauh/gems/arch/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,15 +851,25 @@ def upgrade(self, requirements: UpgradeRequirements, root_password: str, watcher

if requirements.to_remove:
to_remove_names = {r.pkg.name for r in requirements.to_remove}
output_handler = TransactionStatusHandler(watcher=handler.watcher,
i18n=self.i18n,
pkgs_to_sync=0,
logger=self.logger,
pkgs_to_remove=len(to_remove_names))
output_handler.start()
try:
success = handler.handle(pacman.remove_several(to_remove_names, root_password))
success = handler.handle(pacman.remove_several(to_remove_names, root_password), output_handler=output_handler.handle)

if not success:
self.logger.error("Could not remove packages: {}".format(', '.join(to_remove_names)))
output_handler.stop_working()
output_handler.join()
return False
except:
self.logger.error("An error occured while removing packages: {}".format(', '.join(to_remove_names)))
traceback.print_exc()
output_handler.stop_working()
output_handler.join()
return False

if repo_pkgs:
Expand Down Expand Up @@ -972,6 +982,28 @@ def _uninstall(self, context: TransactionContext, remove_unneeded: bool = False)

required_by = self.deps_analyser.map_all_required_by({context.name}, set())

if required_by:
target_provided = pacman.map_provided(pkgs={context.name}).keys()

if target_provided:
required_by_deps = pacman.map_all_deps(required_by, only_installed=True)

if required_by_deps:
all_provided = pacman.map_provided()

for pkg, deps in required_by_deps.items():
target_required_by = 0
for dep in deps:
dep_split = pacman.RE_DEP_OPERATORS.split(dep)
if dep_split[0] in target_provided:
dep_providers = all_provided.get(dep_split[0])

if dep_providers:
target_required_by += 1 if not dep_providers.difference(target_provided) else 0

if not target_required_by:
required_by.remove(pkg)

self._update_progress(context, 50)

to_uninstall = set()
Expand Down Expand Up @@ -1283,7 +1315,7 @@ def _request_conflict_resolution(self, pkg: str, conflicting_pkg: str, context:

return True

def _install_deps(self, context: TransactionContext, deps: List[Tuple[str, str]]) -> Iterable[str]:
def _install_deps(self, context: TransactionContext, deps: List[Tuple[str, str]]) -> Iterable[str]:
"""
:param pkgs_repos:
:param root_password:
Expand Down Expand Up @@ -1333,7 +1365,7 @@ def _install_deps(self, context: TransactionContext, deps: List[Tuple[str, str]
except ArchDownloadException:
return False

status_handler = TransactionStatusHandler(watcher=context.watcher, i18n=self.i18n, npkgs=len(repo_dep_names),
status_handler = TransactionStatusHandler(watcher=context.watcher, i18n=self.i18n, pkgs_to_sync=len(repo_dep_names),
logger=self.logger, percentage=len(repo_deps) > 1, downloading=downloaded)
status_handler.start()
installed, _ = context.handler.handle_simple(pacman.install_as_process(pkgpaths=repo_dep_names,
Expand Down Expand Up @@ -1493,6 +1525,7 @@ def _list_missing_deps(self, context: TransactionContext) -> List[Tuple[str, str
sort=True,
remote_provided_map=context.get_remote_provided_map(),
remote_repo_map=context.get_remote_repo_map(),
automatch_providers=context.config['automatch_providers'],
watcher=context.watcher)

tf = time.time()
Expand Down Expand Up @@ -1594,6 +1627,7 @@ def _install_optdeps(self, context: TransactionContext) -> bool:
watcher=context.watcher,
remote_provided_map=remote_provided_map,
remote_repo_map=remote_repo_map,
automatch_providers=context.config['automatch_providers'],
sort=False)

if missing_deps is None:
Expand Down Expand Up @@ -1627,7 +1661,9 @@ def _install_optdeps(self, context: TransactionContext) -> bool:
return True

def _should_download_packages(self, arch_config: dict) -> bool:
return bool(arch_config['repositories_mthread_download']) and self.context.file_downloader.is_multithreaded()
return bool(arch_config['repositories_mthread_download']) \
and self.context.file_downloader.is_multithreaded() \
and pacman.is_mirrors_available()

def _download_packages(self, pkgnames: List[str], handler: ProcessHandler, root_password: str, sizes: Dict[str, int] = None) -> int:
download_service = MultithreadedDownloadService(file_downloader=self.context.file_downloader,
Expand Down Expand Up @@ -1757,6 +1793,7 @@ def _install(self, context: TransactionContext) -> bool:

disk.save_several(pkgs=cache_map, maintainer=None, overwrite=True)

context.watcher.change_substatus('')
self._update_progress(context, 100)

return installed
Expand Down Expand Up @@ -2099,6 +2136,11 @@ def get_settings(self, screen_width: int, screen_height: int) -> ViewComponent:
tooltip_key='arch.config.optimize.tip',
value=bool(local_config['optimize']),
max_width=max_width),
self._gen_bool_selector(id_='autoprovs',
label_key='arch.config.automatch_providers',
tooltip_key='arch.config.automatch_providers.tip',
value=bool(local_config['automatch_providers']),
max_width=max_width),
self._gen_bool_selector(id_='mthread_download',
label_key='arch.config.pacman_mthread_download',
tooltip_key='arch.config.pacman_mthread_download.tip',
Expand Down Expand Up @@ -2144,6 +2186,7 @@ def save_settings(self, component: PanelComponent) -> Tuple[bool, List[str]]:
config['refresh_mirrors_startup'] = form_install.get_component('ref_mirs').get_selected()
config['mirrors_sort_limit'] = form_install.get_component('mirrors_sort_limit').get_int_value()
config['repositories_mthread_download'] = form_install.get_component('mthread_download').get_selected()
config['automatch_providers'] = form_install.get_component('autoprovs').get_selected()

try:
save_config(config, CONFIG_FILE)
Expand Down
39 changes: 29 additions & 10 deletions bauh/gems/arch/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ def map_known_missing_deps(self, known_deps: Dict[str, str], watcher: ProcessWat
def _fill_missing_dep(self, dep_name: str, dep_exp: str, aur_index: Iterable[str],
missing_deps: Set[Tuple[str, str]],
remote_provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str],
repo_deps: Set[str], aur_deps: Set[str], deps_data: Dict[str, dict], watcher: ProcessWatcher):
repo_deps: Set[str], aur_deps: Set[str], deps_data: Dict[str, dict], watcher: ProcessWatcher,
automatch_providers: bool):

if dep_name == dep_exp:
providers = remote_provided_map.get(dep_name)
Expand Down Expand Up @@ -222,7 +223,16 @@ def _fill_missing_dep(self, dep_name: str, dep_exp: str, aur_index: Iterable[str

if providers:
if len(providers) > 1:
dep_data = (dep_name, '__several__')
dep_data = None

if automatch_providers:
exact_matches = [p for p in providers if p == dep_name]

if exact_matches:
dep_data = (exact_matches[0], remote_repo_map.get(exact_matches[0]))

if not dep_data:
dep_data = (dep_name, '__several__')
else:
real_name = providers.pop()
dep_data = (real_name, remote_repo_map.get(real_name))
Expand All @@ -246,7 +256,8 @@ def __fill_aur_update_data(self, pkgname: str, output: dict):
def map_missing_deps(self, pkgs_data: Dict[str, dict], provided_map: Dict[str, Set[str]],
remote_provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str],
aur_index: Iterable[str], deps_checked: Set[str], deps_data: Dict[str, dict],
sort: bool, watcher: ProcessWatcher, choose_providers: bool = True) -> List[Tuple[str, str]]:
sort: bool, watcher: ProcessWatcher, choose_providers: bool = True,
automatch_providers: bool = False) -> List[Tuple[str, str]]:
sorted_deps = [] # it will hold the proper order to install the missing dependencies

missing_deps, repo_missing, aur_missing = set(), set(), set()
Expand All @@ -271,7 +282,8 @@ def map_missing_deps(self, pkgs_data: Dict[str, dict], provided_map: Dict[str, S
remote_provided_map=remote_provided_map,
remote_repo_map=remote_repo_map,
repo_deps=repo_missing, aur_deps=aur_missing, watcher=watcher,
deps_data=deps_data)
deps_data=deps_data,
automatch_providers=automatch_providers)
else:
version_pattern = '{}='.format(dep_name)
version_found = [p for p in provided_map if p.startswith(version_pattern)]
Expand All @@ -297,15 +309,17 @@ def map_missing_deps(self, pkgs_data: Dict[str, dict], provided_map: Dict[str, S
remote_repo_map=remote_repo_map,
repo_deps=repo_missing, aur_deps=aur_missing,
watcher=watcher,
deps_data=deps_data)
deps_data=deps_data,
automatch_providers=automatch_providers)
else:
self._fill_missing_dep(dep_name=dep_name, dep_exp=dep, aur_index=aur_index,
missing_deps=missing_deps,
remote_provided_map=remote_provided_map,
remote_repo_map=remote_repo_map,
repo_deps=repo_missing, aur_deps=aur_missing,
watcher=watcher,
deps_data=deps_data)
deps_data=deps_data,
automatch_providers=automatch_providers)

if missing_deps:
if repo_missing:
Expand Down Expand Up @@ -339,6 +353,7 @@ def map_missing_deps(self, pkgs_data: Dict[str, dict], provided_map: Dict[str, S
watcher=watcher,
remote_provided_map=remote_provided_map,
remote_repo_map=remote_repo_map,
automatch_providers=automatch_providers,
choose_providers=False)

if missing_subdeps:
Expand All @@ -353,15 +368,16 @@ def map_missing_deps(self, pkgs_data: Dict[str, dict], provided_map: Dict[str, S
return self.fill_providers_deps(missing_deps=sorted_deps, provided_map=provided_map,
remote_provided_map=remote_provided_map, remote_repo_map=remote_repo_map,
watcher=watcher, sort=sort, already_checked=deps_checked,
aur_idx=aur_index, deps_data=deps_data)
aur_idx=aur_index, deps_data=deps_data,
automatch_providers=automatch_providers)

return sorted_deps

def fill_providers_deps(self, missing_deps: List[Tuple[str, str]],
provided_map: Dict[str, Set[str]], remote_repo_map: Dict[str, str],
already_checked: Set[str], remote_provided_map: Dict[str, Set[str]],
deps_data: Dict[str, dict], aur_idx: Iterable[str], sort: bool,
watcher: ProcessWatcher) -> List[Tuple[str, str]]:
watcher: ProcessWatcher, automatch_providers: bool) -> List[Tuple[str, str]]:
"""
:param missing_deps:
:param provided_map:
Expand All @@ -372,6 +388,7 @@ def fill_providers_deps(self, missing_deps: List[Tuple[str, str]],
:param aur_idx:
:param sort:
:param watcher:
:param automatch_providers
:return: all deps sorted or None if the user declined the providers options
"""

Expand Down Expand Up @@ -404,7 +421,8 @@ def fill_providers_deps(self, missing_deps: List[Tuple[str, str]],
remote_provided_map=remote_provided_map,
remote_repo_map=remote_repo_map,
watcher=watcher,
choose_providers=False)
choose_providers=True,
automatch_providers=automatch_providers)

# cleaning the already mapped providers deps:
to_remove = []
Expand All @@ -427,7 +445,8 @@ def fill_providers_deps(self, missing_deps: List[Tuple[str, str]],
if not self.fill_providers_deps(missing_deps=missing_deps, provided_map=provided_map,
remote_repo_map=remote_repo_map, already_checked=already_checked,
aur_idx=aur_idx, remote_provided_map=remote_provided_map,
deps_data=deps_data, sort=False, watcher=watcher):
deps_data=deps_data, sort=False, watcher=watcher,
automatch_providers=automatch_providers):
return

if sort:
Expand Down
Loading

0 comments on commit 0d4d421

Please sign in to comment.