1 |
commit: 3bfc83bb03b7c7edd031df62a7a38acba4d628e2 |
2 |
Author: David James <davidjames <AT> google <DOT> com> |
3 |
AuthorDate: Wed Apr 27 22:02:39 2011 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Apr 27 22:02:39 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=3bfc83bb |
7 |
|
8 |
emerge: add 3 new options similar to --exclude |
9 |
|
10 |
Add --nousepkg-atoms, --useoldpkg-atoms, and --reinstall-atoms flag |
11 |
to Portage |
12 |
|
13 |
reinstall-atoms accepts a space separated list of package names or |
14 |
slot atoms. Emerge will treat matching packages as if they are not |
15 |
installed, and reinstall them if necessary. |
16 |
|
17 |
useoldpkg-atoms accepts a space separated list of package names or |
18 |
slot atoms. Emerge will prefer matching binary packages over newer |
19 |
unbuilt packages. This is useful in case you want to request that a |
20 |
particular package won't be rebuilt from source. |
21 |
|
22 |
nousepkg-atoms accepts a space separated list of package names or |
23 |
slot atoms. Emerge will ignore matching binary packages. |
24 |
|
25 |
Change-Id: I0d73039c6a4cd63695b28ffc80215628e0e05c95 |
26 |
|
27 |
BUG=chromium-os:12507 TEST=Try out the flag |
28 |
|
29 |
Review URL: http://codereview.chromium.org/6577024 |
30 |
|
31 |
--- |
32 |
man/emerge.1 | 13 ++++++++ |
33 |
pym/_emerge/depgraph.py | 78 ++++++++++++++++++++++++++++++++++------------ |
34 |
pym/_emerge/main.py | 79 ++++++++++++++++++++++++++++++++++------------- |
35 |
3 files changed, 128 insertions(+), 42 deletions(-) |
36 |
|
37 |
diff --git a/man/emerge.1 b/man/emerge.1 |
38 |
index 2693b67..67f3e47 100644 |
39 |
--- a/man/emerge.1 |
40 |
+++ b/man/emerge.1 |
41 |
@@ -479,6 +479,10 @@ may have changed. |
42 |
Disables the spinner for the session. The spinner is active when the |
43 |
terminal device is determined to be a TTY. This flag disables it regardless. |
44 |
.TP |
45 |
+.BR "\-\-nousepkg\-atoms " ATOMS |
46 |
+A space separated list of package names or slot atoms. Emerge will ignore |
47 |
+matching binary packages. |
48 |
+.TP |
49 |
.BR "\-\-oneshot " (\fB\-1\fR) |
50 |
Emerge as normal, but do not add the packages to the world file |
51 |
for later updating. |
52 |
@@ -549,6 +553,11 @@ changed since installation. Unlike \fB\-\-newuse\fR, this option does |
53 |
not trigger reinstallation when flags that the user has not |
54 |
enabled are added or removed. |
55 |
.TP |
56 |
+.BR "\-\-reinstall\-atoms " ATOMS |
57 |
+A space separated list of package names or slot atoms. Emerge will treat |
58 |
+matching packages as if they are not installed, and reinstall them if |
59 |
+necessary. |
60 |
+.TP |
61 |
.BR \-\-root=DIR |
62 |
Set the \fBROOT\fR environment variable. |
63 |
.TP |
64 |
@@ -606,6 +615,10 @@ atoms may match multiple versions of slotted packages. |
65 |
Use unbuilt ebuild metadata for visibility |
66 |
checks on built packages. |
67 |
.TP |
68 |
+.BR "\-\-useoldpkg\-atoms " ATOMS |
69 |
+A space separated list of package names or slot atoms. Emerge will prefer |
70 |
+matching binary packages over newer unbuilt packages. |
71 |
+.TP |
72 |
.BR "\-\-usepkg [ y | n ] (\-k short option)" |
73 |
Tells emerge to use binary packages (from $PKGDIR) if they are available, thus |
74 |
possibly avoiding some time\-consuming compiles. This option is useful for CD |
75 |
|
76 |
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
77 |
index a0a4622..84e7d24 100644 |
78 |
--- a/pym/_emerge/depgraph.py |
79 |
+++ b/pym/_emerge/depgraph.py |
80 |
@@ -70,6 +70,16 @@ class _scheduler_graph_config(object): |
81 |
self.graph = graph |
82 |
self.mergelist = mergelist |
83 |
|
84 |
+def _wildcard_set(atoms): |
85 |
+ pkgs = InternalPackageSet(allow_wildcard=True) |
86 |
+ for x in atoms: |
87 |
+ try: |
88 |
+ x = Atom(x, allow_wildcard=True) |
89 |
+ except portage.exception.InvalidAtom: |
90 |
+ x = Atom("*/" + x, allow_wildcard=True) |
91 |
+ pkgs.add(x) |
92 |
+ return pkgs |
93 |
+ |
94 |
class _frozen_depgraph_config(object): |
95 |
|
96 |
def __init__(self, settings, trees, myopts, spinner): |
97 |
@@ -109,13 +119,14 @@ class _frozen_depgraph_config(object): |
98 |
|
99 |
self._required_set_names = set(["world"]) |
100 |
|
101 |
- self.excluded_pkgs = InternalPackageSet(allow_wildcard=True) |
102 |
- for x in ' '.join(myopts.get("--exclude", [])).split(): |
103 |
- try: |
104 |
- x = Atom(x, allow_wildcard=True) |
105 |
- except portage.exception.InvalidAtom: |
106 |
- x = Atom("*/" + x, allow_wildcard=True) |
107 |
- self.excluded_pkgs.add(x) |
108 |
+ atoms = ' '.join(myopts.get("--exclude", [])).split() |
109 |
+ self.excluded_pkgs = _wildcard_set(atoms) |
110 |
+ atoms = ' '.join(myopts.get("--reinstall-atoms", [])).split() |
111 |
+ self.reinstall_atoms = _wildcard_set(atoms) |
112 |
+ atoms = ' '.join(myopts.get("--nousepkg-atoms", [])).split() |
113 |
+ self.nousepkg_atoms = _wildcard_set(atoms) |
114 |
+ atoms = ' '.join(myopts.get("--useoldpkg-atoms", [])).split() |
115 |
+ self.useoldpkg_atoms = _wildcard_set(atoms) |
116 |
|
117 |
class _depgraph_sets(object): |
118 |
def __init__(self): |
119 |
@@ -1237,6 +1248,7 @@ class depgraph(object): |
120 |
vardb = root_config.trees["vartree"].dbapi |
121 |
traversed_virt_pkgs = set() |
122 |
|
123 |
+ reinstall_atoms = self._frozen_config.reinstall_atoms |
124 |
for atom, child in self._minimize_children( |
125 |
pkg, dep_priority, root_config, selected_atoms[pkg]): |
126 |
|
127 |
@@ -1254,7 +1266,9 @@ class depgraph(object): |
128 |
|
129 |
mypriority = dep_priority.copy() |
130 |
if not atom.blocker: |
131 |
- inst_pkgs = vardb.match_pkgs(atom) |
132 |
+ inst_pkgs = [inst_pkg for inst_pkg in vardb.match_pkgs(atom) |
133 |
+ if not reinstall_atoms.findAtomForPackage(inst_pkg, |
134 |
+ modified_use=self._pkg_use_enabled(inst_pkg))] |
135 |
if inst_pkgs: |
136 |
for inst_pkg in inst_pkgs: |
137 |
if self._pkg_visibility_check(inst_pkg): |
138 |
@@ -1344,7 +1358,9 @@ class depgraph(object): |
139 |
# This is a GLEP 37 virtual, so its deps are all runtime. |
140 |
mypriority = self._priority(runtime=True) |
141 |
if not atom.blocker: |
142 |
- inst_pkgs = vardb.match_pkgs(atom) |
143 |
+ inst_pkgs = [inst_pkg for inst_pkg in vardb.match_pkgs(atom) |
144 |
+ if not reinstall_atoms.findAtomForPackage(inst_pkg, |
145 |
+ modified_use=self._pkg_use_enabled(inst_pkg))] |
146 |
if inst_pkgs: |
147 |
for inst_pkg in inst_pkgs: |
148 |
if self._pkg_visibility_check(inst_pkg): |
149 |
@@ -3161,6 +3177,10 @@ class depgraph(object): |
150 |
dont_miss_updates = "--update" in self._frozen_config.myopts |
151 |
use_ebuild_visibility = self._frozen_config.myopts.get( |
152 |
'--use-ebuild-visibility', 'n') != 'n' |
153 |
+ reinstall_atoms = self._frozen_config.reinstall_atoms |
154 |
+ nousepkg_atoms = self._frozen_config.nousepkg_atoms |
155 |
+ useoldpkg_atoms = self._frozen_config.useoldpkg_atoms |
156 |
+ matched_oldpkg = [] |
157 |
# Behavior of the "selective" parameter depends on |
158 |
# whether or not a package matches an argument atom. |
159 |
# If an installed package provides an old-style |
160 |
@@ -3200,7 +3220,14 @@ class depgraph(object): |
161 |
modified_use=self._pkg_use_enabled(pkg)): |
162 |
continue |
163 |
|
164 |
- if packages_with_invalid_use_config and \ |
165 |
+ if built and not installed and nousepkg_atoms.findAtomForPackage(pkg, \ |
166 |
+ modified_use=self._pkg_use_enabled(pkg)): |
167 |
+ break |
168 |
+ |
169 |
+ useoldpkg = useoldpkg_atoms.findAtomForPackage(pkg, \ |
170 |
+ modified_use=self._pkg_use_enabled(pkg)) |
171 |
+ |
172 |
+ if packages_with_invalid_use_config and (not built or not useoldpkg) and \ |
173 |
(not pkg.installed or dont_miss_updates): |
174 |
# Check if a higher version was rejected due to user |
175 |
# USE configuration. The packages_with_invalid_use_config |
176 |
@@ -3282,7 +3309,7 @@ class depgraph(object): |
177 |
# instances (installed or binary). |
178 |
# If --usepkgonly is enabled, assume that |
179 |
# the ebuild status should be ignored. |
180 |
- if not use_ebuild_visibility and usepkgonly: |
181 |
+ if not use_ebuild_visibility and (usepkgonly or useoldpkg): |
182 |
if pkg.installed and pkg.masks: |
183 |
continue |
184 |
else: |
185 |
@@ -3419,7 +3446,7 @@ class depgraph(object): |
186 |
break |
187 |
# Compare built package to current config and |
188 |
# reject the built package if necessary. |
189 |
- if built and (not installed or matched_pkgs_ignore_use) and \ |
190 |
+ if built and not useoldpkg and (not installed or matched_pkgs_ignore_use) and \ |
191 |
("--newuse" in self._frozen_config.myopts or \ |
192 |
"--reinstall" in self._frozen_config.myopts or \ |
193 |
"--binpkg-respect-use" in self._frozen_config.myopts): |
194 |
@@ -3434,7 +3461,7 @@ class depgraph(object): |
195 |
forced_flags.update(pkgsettings.useforce) |
196 |
forced_flags.update(pkgsettings.usemask) |
197 |
cur_iuse = iuses |
198 |
- if myeb and not usepkgonly: |
199 |
+ if myeb and not usepkgonly and not useoldpkg: |
200 |
cur_iuse = myeb.iuse.all |
201 |
if self._reinstall_for_flags(forced_flags, |
202 |
old_use, iuses, |
203 |
@@ -3442,7 +3469,7 @@ class depgraph(object): |
204 |
break |
205 |
# Compare current config to installed package |
206 |
# and do not reinstall if possible. |
207 |
- if not installed and \ |
208 |
+ if not installed and not useoldpkg and \ |
209 |
("--newuse" in self._frozen_config.myopts or \ |
210 |
"--reinstall" in self._frozen_config.myopts) and \ |
211 |
cpv in vardb.match(atom): |
212 |
@@ -3460,8 +3487,13 @@ class depgraph(object): |
213 |
cur_use, cur_iuse) |
214 |
if reinstall_for_flags: |
215 |
reinstall = True |
216 |
+ if reinstall_atoms.findAtomForPackage(pkg, \ |
217 |
+ modified_use=self._pkg_use_enabled(pkg)): |
218 |
+ reinstall = True |
219 |
if not built: |
220 |
myeb = pkg |
221 |
+ elif useoldpkg: |
222 |
+ matched_oldpkg.append(pkg) |
223 |
matched_packages.append(pkg) |
224 |
if reinstall_for_flags: |
225 |
self._dynamic_config._reinstall_nodes[pkg] = \ |
226 |
@@ -3545,14 +3577,20 @@ class depgraph(object): |
227 |
allow_license_changes=allow_license_changes): |
228 |
return pkg, existing_node |
229 |
|
230 |
- bestmatch = portage.best( |
231 |
- [pkg.cpv for pkg in matched_packages \ |
232 |
+ visible_matches = [] |
233 |
+ if matched_oldpkg: |
234 |
+ visible_matches = [pkg.cpv for pkg in matched_oldpkg \ |
235 |
if self._pkg_visibility_check(pkg, allow_unstable_keywords=allow_unstable_keywords, |
236 |
- allow_license_changes=allow_license_changes)]) |
237 |
- if not bestmatch: |
238 |
+ allow_license_changes=allow_license_changes)] |
239 |
+ if not visible_matches: |
240 |
+ visible_matches = [pkg.cpv for pkg in matched_packages \ |
241 |
+ if self._pkg_visibility_check(pkg, allow_unstable_keywords=allow_unstable_keywords, |
242 |
+ allow_license_changes=allow_license_changes)] |
243 |
+ if visible_matches: |
244 |
+ bestmatch = portage.best(visible_matches) |
245 |
+ else: |
246 |
# all are masked, so ignore visibility |
247 |
- bestmatch = portage.best( |
248 |
- [pkg.cpv for pkg in matched_packages]) |
249 |
+ bestmatch = portage.best([pkg.cpv for pkg in matched_packages]) |
250 |
matched_packages = [pkg for pkg in matched_packages \ |
251 |
if portage.dep.cpvequal(pkg.cpv, bestmatch)] |
252 |
|
253 |
|
254 |
diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py |
255 |
index 96fee89..af243c0 100644 |
256 |
--- a/pym/_emerge/main.py |
257 |
+++ b/pym/_emerge/main.py |
258 |
@@ -544,6 +544,23 @@ def insert_optional_args(args): |
259 |
|
260 |
return new_args |
261 |
|
262 |
+def _find_bad_atoms(atoms): |
263 |
+ bad_atoms = [] |
264 |
+ for x in ' '.join(atoms).split(): |
265 |
+ bad_atom = False |
266 |
+ try: |
267 |
+ atom = portage.dep.Atom(x, allow_wildcard=True) |
268 |
+ except portage.exception.InvalidAtom: |
269 |
+ try: |
270 |
+ atom = portage.dep.Atom("*/"+x, allow_wildcard=True) |
271 |
+ except portage.exception.InvalidAtom: |
272 |
+ bad_atom = True |
273 |
+ |
274 |
+ if bad_atom or atom.operator or atom.blocker or atom.use: |
275 |
+ bad_atoms.append(x) |
276 |
+ return bad_atoms |
277 |
+ |
278 |
+ |
279 |
def parse_opts(tmpcmdline, silent=False): |
280 |
myaction=None |
281 |
myopts = {} |
282 |
@@ -680,6 +697,14 @@ def parse_opts(tmpcmdline, silent=False): |
283 |
"choices":["changed-use"] |
284 |
}, |
285 |
|
286 |
+ "--reinstall-atoms": { |
287 |
+ "help" :"A space separated list of package names or slot atoms. " + \ |
288 |
+ "Emerge will treat matching packages as if they are not " + \ |
289 |
+ "installed, and reinstall them if necessary. Implies --deep.", |
290 |
+ |
291 |
+ "action" : "append", |
292 |
+ }, |
293 |
+ |
294 |
"--binpkg-respect-use": { |
295 |
"help" : "discard binary packages if their use flags \ |
296 |
don't match the current configuration", |
297 |
@@ -701,6 +726,13 @@ def parse_opts(tmpcmdline, silent=False): |
298 |
"choices" : true_y_or_n |
299 |
}, |
300 |
|
301 |
+ "--nousepkg-atoms": { |
302 |
+ "help" :"A space separated list of package names or slot atoms. " + \ |
303 |
+ "Emerge will ignore matching binary packages. ", |
304 |
+ |
305 |
+ "action" : "append", |
306 |
+ }, |
307 |
+ |
308 |
"--package-moves": { |
309 |
"help" : "perform package moves when necessary", |
310 |
"type" : "choice", |
311 |
@@ -764,6 +796,13 @@ def parse_opts(tmpcmdline, silent=False): |
312 |
"choices" : true_y_or_n |
313 |
}, |
314 |
|
315 |
+ "--useoldpkg-atoms": { |
316 |
+ "help" :"A space separated list of package names or slot atoms. " + \ |
317 |
+ "Emerge will prefer matching binary packages over newer unbuilt packages. ", |
318 |
+ |
319 |
+ "action" : "append", |
320 |
+ }, |
321 |
+ |
322 |
"--usepkg": { |
323 |
"shortopt" : "-k", |
324 |
"help" : "use binary packages", |
325 |
@@ -852,32 +891,28 @@ def parse_opts(tmpcmdline, silent=False): |
326 |
myoptions.depclean_lib_check = True |
327 |
|
328 |
if myoptions.exclude: |
329 |
- exclude = [] |
330 |
- bad_atoms = [] |
331 |
- for x in ' '.join(myoptions.exclude).split(): |
332 |
- bad_atom = False |
333 |
- try: |
334 |
- atom = portage.dep.Atom(x, allow_wildcard=True) |
335 |
- except portage.exception.InvalidAtom: |
336 |
- try: |
337 |
- atom = portage.dep.Atom("*/"+x, allow_wildcard=True) |
338 |
- except portage.exception.InvalidAtom: |
339 |
- bad_atom = True |
340 |
- |
341 |
- if bad_atom: |
342 |
- bad_atoms.append(x) |
343 |
- else: |
344 |
- if atom.operator or atom.blocker or atom.use: |
345 |
- bad_atoms.append(x) |
346 |
- else: |
347 |
- exclude.append(atom) |
348 |
- |
349 |
+ bad_atoms = _find_bad_atoms(myoptions.exclude) |
350 |
if bad_atoms and not silent: |
351 |
parser.error("Invalid Atom(s) in --exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \ |
352 |
(",".join(bad_atoms),)) |
353 |
|
354 |
- if myoptions.fail_clean in true_y: |
355 |
- myoptions.fail_clean = True |
356 |
+ if myoptions.reinstall_atoms: |
357 |
+ bad_atoms = _find_bad_atoms(myoptions.reinstall_atoms) |
358 |
+ if bad_atoms and not silent: |
359 |
+ parser.error("Invalid Atom(s) in --reinstall-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \ |
360 |
+ (",".join(bad_atoms),)) |
361 |
+ |
362 |
+ if myoptions.nousepkg_atoms: |
363 |
+ bad_atoms = _find_bad_atoms(myoptions.nousepkg_atoms) |
364 |
+ if bad_atoms and not silent: |
365 |
+ parser.error("Invalid Atom(s) in --nousepkg-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \ |
366 |
+ (",".join(bad_atoms),)) |
367 |
+ |
368 |
+ if myoptions.useoldpkg_atoms: |
369 |
+ bad_atoms = _find_bad_atoms(myoptions.useoldpkg_atoms) |
370 |
+ if bad_atoms and not silent: |
371 |
+ parser.error("Invalid Atom(s) in --useoldpkg-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \ |
372 |
+ (",".join(bad_atoms),)) |
373 |
|
374 |
if myoptions.getbinpkg in true_y: |
375 |
myoptions.getbinpkg = True |