1 |
This patch allows users to re-attempt an emerge after USE flag changes |
2 |
have been automatically written via --autounmask-write, allowing easier |
3 |
installation of ebuilds when users are not concerned about USE flag |
4 |
details. Previously, users would have needed to invoke emerge multiple |
5 |
times. |
6 |
|
7 |
Implementation was choosen based off of what was possible for me to get |
8 |
working at the time. Based on Portage 2.2.10_p25_p484922. |
9 |
--- |
10 |
man/emerge.1 | 4 +++ |
11 |
pym/_emerge/depgraph.py | 5 +++- |
12 |
pym/_emerge/main.py | 66 ++++++++++++++++++++++++++++++------------------ |
13 |
pym/portage/exception.py | 3 +++ |
14 |
4 files changed, 52 insertions(+), 26 deletions(-) |
15 |
|
16 |
diff --git a/man/emerge.1 b/man/emerge.1 |
17 |
index abb0ed8..d921c4c 100644 |
18 |
--- a/man/emerge.1 |
19 |
+++ b/man/emerge.1 |
20 |
@@ -355,6 +355,10 @@ it, if it is a directory, changes are written to the lexicographically |
21 |
last file. This way it is always ensured that the new changes take |
22 |
precedence over existing changes. |
23 |
.TP |
24 |
+.BR "\-\-autounmask\-write\-retry [ y | n ]" |
25 |
+If \fB\-\-autounmask\-write\fR is enabled and changes are written |
26 |
+successfully then \fBemerge\fR will re\-attempt the action. |
27 |
+.TP |
28 |
.BR \-\-backtrack=COUNT |
29 |
Specifies an integer number of times to backtrack if |
30 |
dependency calculation fails due to a conflict or an |
31 |
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
32 |
index 28d4026..8864e88 100644 |
33 |
--- a/pym/_emerge/depgraph.py |
34 |
+++ b/pym/_emerge/depgraph.py |
35 |
@@ -28,7 +28,7 @@ from portage.dep._slot_operator import ignore_built_slot_operator_deps |
36 |
from portage.eapi import eapi_has_strong_blocks, eapi_has_required_use, \ |
37 |
_get_eapi_attrs |
38 |
from portage.exception import (InvalidAtom, InvalidData, InvalidDependString, |
39 |
- PackageNotFound, PortageException) |
40 |
+ PackageNotFound, PortageException, RetryEmerge) |
41 |
from portage.output import colorize, create_color_func, \ |
42 |
darkgreen, green |
43 |
bad = create_color_func("BAD") |
44 |
@@ -7300,6 +7300,7 @@ class depgraph(object): |
45 |
""" |
46 |
|
47 |
autounmask_write = self._frozen_config.myopts.get("--autounmask-write", "n") == True |
48 |
+ autounmask_write_retry = self._frozen_config.myopts.get("--autounmask-write-retry", "n") == True |
49 |
autounmask_unrestricted_atoms = \ |
50 |
self._frozen_config.myopts.get("--autounmask-unrestricted-atoms", "n") == True |
51 |
quiet = "--quiet" in self._frozen_config.myopts |
52 |
@@ -7660,6 +7661,8 @@ class depgraph(object): |
53 |
for root in roots: |
54 |
chk_updated_cfg_files(root, |
55 |
[os.path.join(os.sep, USER_CONFIG_PATH)]) |
56 |
+ if autounmask_write_retry: |
57 |
+ raise RetryEmerge("Re-try emerge") |
58 |
elif not pretend and not autounmask_write and roots: |
59 |
writemsg("\nUse --autounmask-write to write changes to config files (honoring\n" |
60 |
"CONFIG_PROTECT). Carefully examine the list of proposed changes,\n" |
61 |
diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py |
62 |
index eddb16c..b033f7b 100644 |
63 |
--- a/pym/_emerge/main.py |
64 |
+++ b/pym/_emerge/main.py |
65 |
@@ -19,6 +19,7 @@ portage.proxy.lazyimport.lazyimport(globals(), |
66 |
'_emerge.is_valid_package_atom:insert_category_into_atom' |
67 |
) |
68 |
from portage import os |
69 |
+from portage.exception import RetryEmerge |
70 |
from portage.util._argparse import ArgumentParser |
71 |
|
72 |
if sys.hexversion >= 0x3000000: |
73 |
@@ -129,6 +130,7 @@ def insert_optional_args(args): |
74 |
'--autounmask-keep-masks': y_or_n, |
75 |
'--autounmask-unrestricted-atoms' : y_or_n, |
76 |
'--autounmask-write' : y_or_n, |
77 |
+ '--autounmask-write-retry' : y_or_n, |
78 |
'--buildpkg' : y_or_n, |
79 |
'--complete-graph' : y_or_n, |
80 |
'--deep' : valid_integers, |
81 |
@@ -326,6 +328,11 @@ def parse_opts(tmpcmdline, silent=False): |
82 |
"choices" : true_y_or_n |
83 |
}, |
84 |
|
85 |
+ "--autounmask-write-retry": { |
86 |
+ "help" : "retry emerge after writing unmask changes", |
87 |
+ "choices" : true_y_or_n |
88 |
+ }, |
89 |
+ |
90 |
"--accept-properties": { |
91 |
"help":"temporarily override ACCEPT_PROPERTIES", |
92 |
"action":"store" |
93 |
@@ -691,6 +698,10 @@ def parse_opts(tmpcmdline, silent=False): |
94 |
|
95 |
if myoptions.autounmask_write in true_y: |
96 |
myoptions.autounmask_write = True |
97 |
+ if myoptions.autounmask_write_retry in true_y: |
98 |
+ myoptions.autounmask_write_retry = True |
99 |
+ elif myoptions.autounmask_write_retry in true_y: |
100 |
+ parser.error("--autounmask-write must be set if -autounmask-write-retry is specified") |
101 |
|
102 |
if myoptions.buildpkg in true_y: |
103 |
myoptions.buildpkg = True |
104 |
@@ -1020,28 +1031,33 @@ def emerge_main(args=None): |
105 |
|
106 |
# Portage needs to ensure a sane umask for the files it creates. |
107 |
os.umask(0o22) |
108 |
- if myaction == "sync": |
109 |
- portage._sync_mode = True |
110 |
- emerge_config = load_emerge_config( |
111 |
- action=myaction, args=myfiles, opts=myopts) |
112 |
- rval = profile_check(emerge_config.trees, emerge_config.action) |
113 |
- if rval != os.EX_OK: |
114 |
- return rval |
115 |
- |
116 |
- tmpcmdline = [] |
117 |
- if "--ignore-default-opts" not in myopts: |
118 |
- tmpcmdline.extend(portage.util.shlex_split( |
119 |
- emerge_config.target_config.settings.get( |
120 |
- "EMERGE_DEFAULT_OPTS", ""))) |
121 |
- tmpcmdline.extend(args) |
122 |
- emerge_config.action, emerge_config.opts, emerge_config.args = \ |
123 |
- parse_opts(tmpcmdline) |
124 |
- |
125 |
- try: |
126 |
- return run_action(emerge_config) |
127 |
- finally: |
128 |
- # Call destructors for our portdbapi instances. |
129 |
- for x in emerge_config.trees.values(): |
130 |
- if "porttree" in x.lazy_items: |
131 |
- continue |
132 |
- x["porttree"].dbapi.close_caches() |
133 |
+ while 1: |
134 |
+ if myaction == "sync": |
135 |
+ portage._sync_mode = True |
136 |
+ emerge_config = load_emerge_config( |
137 |
+ action=myaction, args=myfiles, opts=myopts) |
138 |
+ rval = profile_check(emerge_config.trees, emerge_config.action) |
139 |
+ if rval != os.EX_OK: |
140 |
+ return rval |
141 |
+ |
142 |
+ tmpcmdline = [] |
143 |
+ if "--ignore-default-opts" not in myopts: |
144 |
+ tmpcmdline.extend(portage.util.shlex_split( |
145 |
+ emerge_config.target_config.settings.get( |
146 |
+ "EMERGE_DEFAULT_OPTS", ""))) |
147 |
+ tmpcmdline.extend(args) |
148 |
+ emerge_config.action, emerge_config.opts, emerge_config.args = \ |
149 |
+ parse_opts(tmpcmdline) |
150 |
+ |
151 |
+ try: |
152 |
+ status = run_action(emerge_config) |
153 |
+ break |
154 |
+ except RetryEmerge: |
155 |
+ continue |
156 |
+ finally: |
157 |
+ # Call destructors for our portdbapi instances. |
158 |
+ for x in emerge_config.trees.values(): |
159 |
+ if "porttree" in x.lazy_items: |
160 |
+ continue |
161 |
+ x["porttree"].dbapi.close_caches() |
162 |
+ return status |
163 |
diff --git a/pym/portage/exception.py b/pym/portage/exception.py |
164 |
index 6fa5447..7b3b4f4 100644 |
165 |
--- a/pym/portage/exception.py |
166 |
+++ b/pym/portage/exception.py |
167 |
@@ -75,6 +75,9 @@ class InvalidData(PortageException): |
168 |
class InvalidDataType(PortageException): |
169 |
"""An incorrect type was passed instead of the expected one""" |
170 |
|
171 |
+class RetryEmerge(PortageException): |
172 |
+ """Re-try the emerge request""" |
173 |
+ |
174 |
class InvalidLocation(PortageException): |
175 |
"""Data was not found when it was expected to exist or was specified incorrectly""" |
176 |
|
177 |
-- |
178 |
1.8.5.5 |