1 |
This makes emerge --search / --searchdesc display individual search |
2 |
results as soon as they become available. A search._iter_search method |
3 |
is split out from the search.execute method, and the search.output |
4 |
method operates on that. The spinner is now disabled, but the spinner |
5 |
code remains, in case we later decide to enable it optionally. |
6 |
|
7 |
X-Gentoo-Bug: 412471 |
8 |
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=412471 |
9 |
--- |
10 |
Note that this patch has been split out from the series for bug 525718. |
11 |
|
12 |
pym/_emerge/search.py | 120 +++++++++++++++++++++++++++++--------------------- |
13 |
1 file changed, 71 insertions(+), 49 deletions(-) |
14 |
|
15 |
diff --git a/pym/_emerge/search.py b/pym/_emerge/search.py |
16 |
index 4b0fd9f..7276c0e 100644 |
17 |
--- a/pym/_emerge/search.py |
18 |
+++ b/pym/_emerge/search.py |
19 |
@@ -1,8 +1,6 @@ |
20 |
# Copyright 1999-2014 Gentoo Foundation |
21 |
# Distributed under the terms of the GNU General Public License v2 |
22 |
|
23 |
-from __future__ import print_function |
24 |
- |
25 |
import re |
26 |
import portage |
27 |
from portage import os |
28 |
@@ -30,10 +28,12 @@ class search(object): |
29 |
The list of available and installed packages is created at object instantiation. |
30 |
This makes successive searches faster.""" |
31 |
self.settings = root_config.settings |
32 |
- self.vartree = root_config.trees["vartree"] |
33 |
- self.spinner = spinner |
34 |
self.verbose = verbose |
35 |
self.searchdesc = searchdesc |
36 |
+ self.searchkey = None |
37 |
+ # Disable the spinner since search results are displayed |
38 |
+ # incrementally. |
39 |
+ self.spinner = None |
40 |
self.root_config = root_config |
41 |
self.setconfig = root_config.setconfig |
42 |
self.matches = {"pkg" : []} |
43 |
@@ -53,6 +53,7 @@ class search(object): |
44 |
|
45 |
self._dbs.append(vardb) |
46 |
self._portdb = portdb |
47 |
+ self._vardb = vardb |
48 |
|
49 |
def _spinner_update(self): |
50 |
if self.spinner: |
51 |
@@ -97,7 +98,7 @@ class search(object): |
52 |
return {} |
53 |
|
54 |
def _visible(self, db, cpv, metadata): |
55 |
- installed = db is self.vartree.dbapi |
56 |
+ installed = db is self._vardb |
57 |
built = installed or db is not self._portdb |
58 |
pkg_type = "ebuild" |
59 |
if installed: |
60 |
@@ -171,8 +172,11 @@ class search(object): |
61 |
|
62 |
def execute(self,searchkey): |
63 |
"""Performs the search for the supplied search key""" |
64 |
+ self.searchkey = searchkey |
65 |
+ |
66 |
+ def _iter_search(self): |
67 |
+ |
68 |
match_category = 0 |
69 |
- self.searchkey=searchkey |
70 |
self.packagematches = [] |
71 |
if self.searchdesc: |
72 |
self.searchdesc=1 |
73 |
@@ -180,7 +184,7 @@ class search(object): |
74 |
else: |
75 |
self.searchdesc=0 |
76 |
self.matches = {"pkg":[], "set":[]} |
77 |
- print("Searching... ", end=' ') |
78 |
+ writemsg_stdout("Searching...\n\n", noiselevel=-1) |
79 |
|
80 |
regexsearch = False |
81 |
if self.searchkey.startswith('%'): |
82 |
@@ -202,29 +206,28 @@ class search(object): |
83 |
else: |
84 |
match_string = package.split("/")[-1] |
85 |
|
86 |
- masked=0 |
87 |
if self.searchre.search(match_string): |
88 |
- if not self._xmatch("match-visible", package): |
89 |
- masked=1 |
90 |
- self.matches["pkg"].append([package,masked]) |
91 |
+ yield ("pkg", package) |
92 |
elif self.searchdesc: # DESCRIPTION searching |
93 |
- full_package = self._xmatch("bestmatch-visible", package) |
94 |
+ # Use match-all to avoid an expensive visibility check, |
95 |
+ # since the visibility check can be avoided entirely |
96 |
+ # when the DESCRIPTION does not match. |
97 |
+ full_package = self._xmatch("match-all", package) |
98 |
if not full_package: |
99 |
- #no match found; we don't want to query description |
100 |
- full_package = portage.best( |
101 |
- self._xmatch("match-all", package)) |
102 |
- if not full_package: |
103 |
- continue |
104 |
- else: |
105 |
- masked=1 |
106 |
+ continue |
107 |
+ full_package = full_package[-1] |
108 |
try: |
109 |
full_desc = self._aux_get( |
110 |
full_package, ["DESCRIPTION"])[0] |
111 |
except KeyError: |
112 |
- print("emerge: search: aux_get() failed, skipping") |
113 |
+ portage.writemsg( |
114 |
+ "emerge: search: aux_get() failed, skipping\n", |
115 |
+ noiselevel=-1) |
116 |
continue |
117 |
- if self.searchre.search(full_desc): |
118 |
- self.matches["desc"].append([full_package,masked]) |
119 |
+ if not self.searchre.search(full_desc): |
120 |
+ continue |
121 |
+ |
122 |
+ yield ("desc", package) |
123 |
|
124 |
self.sdict = self.setconfig.getSets() |
125 |
for setname in self.sdict: |
126 |
@@ -235,51 +238,56 @@ class search(object): |
127 |
match_string = setname.split("/")[-1] |
128 |
|
129 |
if self.searchre.search(match_string): |
130 |
- self.matches["set"].append([setname, False]) |
131 |
+ yield ("set", setname, False) |
132 |
elif self.searchdesc: |
133 |
if self.searchre.search( |
134 |
self.sdict[setname].getMetadata("DESCRIPTION")): |
135 |
- self.matches["set"].append([setname, False]) |
136 |
- |
137 |
- self.mlen=0 |
138 |
- for mtype in self.matches: |
139 |
- self.matches[mtype].sort() |
140 |
- self.mlen += len(self.matches[mtype]) |
141 |
+ yield ("set", setname) |
142 |
|
143 |
def addCP(self, cp): |
144 |
if not self._xmatch("match-all", cp): |
145 |
return |
146 |
- masked = 0 |
147 |
- if not self._xmatch("bestmatch-visible", cp): |
148 |
- masked = 1 |
149 |
- self.matches["pkg"].append([cp, masked]) |
150 |
+ self.matches["pkg"].append(cp) |
151 |
self.mlen += 1 |
152 |
|
153 |
def output(self): |
154 |
"""Outputs the results of the search.""" |
155 |
- msg = [] |
156 |
+ |
157 |
+ class msg(object): |
158 |
+ @staticmethod |
159 |
+ def append(msg): |
160 |
+ writemsg_stdout(msg, noiselevel=-1) |
161 |
+ |
162 |
msg.append("\b\b \n[ Results for search key : " + \ |
163 |
bold(self.searchkey) + " ]\n") |
164 |
- msg.append("[ Applications found : " + \ |
165 |
- bold(str(self.mlen)) + " ]\n\n") |
166 |
- vardb = self.vartree.dbapi |
167 |
+ vardb = self._vardb |
168 |
metadata_keys = set(Package.metadata_keys) |
169 |
metadata_keys.update(["DESCRIPTION", "HOMEPAGE", "LICENSE", "SRC_URI"]) |
170 |
metadata_keys = tuple(metadata_keys) |
171 |
- for mtype in self.matches: |
172 |
- for match,masked in self.matches[mtype]: |
173 |
+ |
174 |
+ if self.searchkey is None: |
175 |
+ # Handle results added via addCP |
176 |
+ addCP_matches = [] |
177 |
+ for mytype, match in self.matches.items(): |
178 |
+ addCP_matches.append(mytype, match) |
179 |
+ iterator = iter(addCP_matches) |
180 |
+ |
181 |
+ else: |
182 |
+ # Do a normal search |
183 |
+ iterator = self._iter_search() |
184 |
+ |
185 |
+ for mtype, match in iterator: |
186 |
+ self.mlen += 1 |
187 |
+ masked = False |
188 |
full_package = None |
189 |
- if mtype == "pkg": |
190 |
+ if mtype in ("pkg", "desc"): |
191 |
full_package = self._xmatch( |
192 |
"bestmatch-visible", match) |
193 |
if not full_package: |
194 |
- #no match found; we don't want to query description |
195 |
- masked=1 |
196 |
- full_package = portage.best( |
197 |
- self._xmatch("match-all",match)) |
198 |
- elif mtype == "desc": |
199 |
- full_package = match |
200 |
- match = portage.cpv_getkey(match) |
201 |
+ masked = True |
202 |
+ full_package = self._xmatch("match-all", match) |
203 |
+ if full_package: |
204 |
+ full_package = full_package[-1] |
205 |
elif mtype == "set": |
206 |
msg.append(green("*") + " " + bold(match) + "\n") |
207 |
if self.verbose: |
208 |
@@ -367,12 +375,26 @@ class search(object): |
209 |
+ " " + desc + "\n") |
210 |
msg.append(" " + darkgreen("License:") + \ |
211 |
" " + license + "\n\n") |
212 |
- writemsg_stdout(''.join(msg), noiselevel=-1) |
213 |
+ |
214 |
+ msg.append("[ Applications found : " + \ |
215 |
+ bold(str(self.mlen)) + " ]\n\n") |
216 |
+ |
217 |
+ # This method can be called multiple times, so |
218 |
+ # reset the match count for the next call. Don't |
219 |
+ # reset it at the beginning of this method, since |
220 |
+ # that would lose modfications from the addCP |
221 |
+ # method. |
222 |
+ self.mlen = 0 |
223 |
+ |
224 |
# |
225 |
# private interface |
226 |
# |
227 |
def getInstallationStatus(self,package): |
228 |
- installed_package = self.vartree.dep_bestmatch(package) |
229 |
+ installed_package = self._vardb.match(package) |
230 |
+ if installed_package: |
231 |
+ installed_package = installed_package[-1] |
232 |
+ else: |
233 |
+ installed_package = "" |
234 |
result = "" |
235 |
version = self.getVersion(installed_package,search.VERSION_RELEASE) |
236 |
if len(version) > 0: |
237 |
-- |
238 |
2.0.4 |