diff --git a/client/solo/commands/match.py b/client/solo/commands/match.py index ce43edd9e..d29c0897d 100644 --- a/client/solo/commands/match.py +++ b/client/solo/commands/match.py @@ -161,49 +161,60 @@ Match package names. """ Match method, returns search results. """ - matches = [] inst_repo = entropy_client.installed_repository() inst_repo_id = inst_repo.repository_id() - if self._installed: - inst_pkg_id, inst_rc = inst_repo.atomMatch( - string, multiMatch = self._multimatch) - if inst_rc != 0: - match = (-1, 1) - else: - if self._multimatch: - match = ([(x, inst_repo_id) for x in inst_pkg_id], 0) + def iterify(match): + if match[1] == 1: + return + if not self._multimatch: + if self._multirepo: + for x in match[0]: + yield x else: - match = (inst_pkg_id, inst_repo_id) + yield match + else: + for x in match[0]: + yield x + + def filter_injected(pkgs): + if self._injected: + is_injected = lambda x: entropy_client.open_repository( + x[1]).isInjected(x[0]) + return filter(is_injected, pkgs) + + return pkgs + + def key_sorter(pkg): + x, y = pkg + return entropy_client.open_repository(y).retrieveAtom(x) + + if self._installed: + with inst_repo.shared(): + inst_pkg_id, inst_rc = inst_repo.atomMatch( + string, multiMatch = self._multimatch) + + if inst_rc != 0: + match = (-1, 1) + else: + if self._multimatch: + match = ([(x, inst_repo_id) for x in inst_pkg_id], 0) + else: + match = (inst_pkg_id, inst_repo_id) + + return sorted( + filter_injected(iterify(match)), + key=key_sorter) + else: + match = entropy_client.atom_match( string, multi_match = self._multimatch, multi_repo = self._multirepo, mask_filter = False) - - _matches = [] - if match[1] != 1: - if not self._multimatch: - if self._multirepo: - _matches += match[0] - else: - _matches += [match] - else: - _matches += match[0] - - # apply filters - if self._injected: - - def is_injected(x, y): - return entropy_client.open_repository(y).isInjected(x) - - _matches = filter(is_injected, _matches) - - matches.extend(_matches) - - key_sorter = lambda x: \ - entropy_client.open_repository(x[1]).retrieveAtom(x[0]) - return sorted(matches, key=key_sorter) + return sorted( + filter_injected(iterify(match)), + key=key_sorter) def match(self, entropy_client): """ @@ -241,18 +252,23 @@ Match package names. entropy_client, string) inst_repo = entropy_client.installed_repository() - inst_repo_class = inst_repo.__class__ for pkg_id, pkg_repo in results: - dbconn = entropy_client.open_repository(pkg_repo) - from_client = isinstance(dbconn, inst_repo_class) + + repo = entropy_client.open_repository(pkg_repo) + if not repo.isPackageIdAvailable(pkg_id): + continue + + # this method is fault tolerant and we better not + # hold the installed repository lock during print + # because we can deadlock other processes/threads. print_package_info( - pkg_id, entropy_client, dbconn, + pkg_id, entropy_client, repo, show_download_if_quiet = self._showdownload, show_repo_if_quiet = self._showrepo, show_desc_if_quiet = self._showdesc, show_slot_if_quiet = self._showslot, extended = self._verbose, - installed_search = from_client, + installed_search = repo is inst_repo, quiet = self._quiet) return results