1 |
On Wed, 18 Jan 2017 19:15:54 +0200 |
2 |
Alexandru Elisei <alexandru.elisei@×××××.com> wrote: |
3 |
|
4 |
> Module functions currently return a message to emaint after |
5 |
> invocation. Emaint prints this message then exits normally (with a |
6 |
> success return code) even if the module encountered an error. This |
7 |
> patch aims to change this by having each module public function |
8 |
> return a tuple of (returncode, message), where returncode is boolean |
9 |
> True if the function was successful or False otherwise. Emaint will |
10 |
> inspect the return codes and exit unsuccessfully if necessary. |
11 |
> |
12 |
> The variable PORT_LOGDIR was added to the test environment to prevent |
13 |
> CleanLogs.clean() from failing when the variable isn't set or not a |
14 |
> directory. |
15 |
> --- |
16 |
> pym/portage/emaint/main.py | 12 +++++++++--- |
17 |
> pym/portage/emaint/modules/binhost/binhost.py | 6 ++++-- |
18 |
> pym/portage/emaint/modules/config/config.py | 6 ++++-- |
19 |
> pym/portage/emaint/modules/logs/logs.py | 9 +++++---- |
20 |
> pym/portage/emaint/modules/merges/merges.py | 18 +++++++++++------- |
21 |
> pym/portage/emaint/modules/move/move.py | 9 +++++++-- |
22 |
> pym/portage/emaint/modules/resume/resume.py | 3 ++- |
23 |
> pym/portage/emaint/modules/sync/sync.py | 20 |
24 |
> +++++++++++++------- pym/portage/emaint/modules/world/world.py | |
25 |
> 8 ++++++-- pym/portage/tests/emerge/test_simple.py | 1 + |
26 |
> 10 files changed, 62 insertions(+), 30 deletions(-) |
27 |
> |
28 |
> diff --git a/pym/portage/emaint/main.py b/pym/portage/emaint/main.py |
29 |
> index 65e3545..f448d6b 100644 |
30 |
> --- a/pym/portage/emaint/main.py |
31 |
> +++ b/pym/portage/emaint/main.py |
32 |
> @@ -115,6 +115,7 @@ class TaskHandler(object): |
33 |
> """Runs the module tasks""" |
34 |
> if tasks is None or func is None: |
35 |
> return |
36 |
> + returncodes = [] |
37 |
> for task in tasks: |
38 |
> inst = task() |
39 |
> show_progress = self.show_progress_bar and |
40 |
> self.isatty @@ -135,14 +136,17 @@ class TaskHandler(object): |
41 |
> # them for other tasks if there is |
42 |
> more to do. 'options': options.copy() |
43 |
> } |
44 |
> - result = getattr(inst, func)(**kwargs) |
45 |
> + returncode, msgs = getattr(inst, |
46 |
> func)(**kwargs) |
47 |
> + returncodes.append(returncode) |
48 |
> if show_progress: |
49 |
> # make sure the final progress is |
50 |
> displayed self.progress_bar.display() |
51 |
> print() |
52 |
> self.progress_bar.stop() |
53 |
> if self.callback: |
54 |
> - self.callback(result) |
55 |
> + self.callback(msgs) |
56 |
> + |
57 |
> + return returncodes |
58 |
> |
59 |
> |
60 |
> def print_results(results): |
61 |
> @@ -237,4 +241,6 @@ def emaint_main(myargv): |
62 |
> task_opts = options.__dict__ |
63 |
> task_opts['return-messages'] = True |
64 |
> taskmaster = TaskHandler(callback=print_results, |
65 |
> module_output=sys.stdout) |
66 |
> - taskmaster.run_tasks(tasks, func, status, options=task_opts) |
67 |
> + returncodes = taskmaster.run_tasks(tasks, func, status, |
68 |
> options=task_opts) + |
69 |
> + sys.exit(False in returncodes) |
70 |
> diff --git a/pym/portage/emaint/modules/binhost/binhost.py |
71 |
> b/pym/portage/emaint/modules/binhost/binhost.py |
72 |
> index cf1213e..527b02f 100644 |
73 |
> --- a/pym/portage/emaint/modules/binhost/binhost.py |
74 |
> +++ b/pym/portage/emaint/modules/binhost/binhost.py |
75 |
> @@ -86,7 +86,9 @@ class BinhostHandler(object): |
76 |
> stale = set(metadata).difference(cpv_all) |
77 |
> for cpv in stale: |
78 |
> errors.append("'%s' is not in the |
79 |
> repository" % cpv) |
80 |
> - return errors |
81 |
> + if errors: |
82 |
> + return (False, errors) |
83 |
> + return (True, None) |
84 |
> |
85 |
> def fix(self, **kwargs): |
86 |
> onProgress = kwargs.get('onProgress', None) |
87 |
> @@ -177,4 +179,4 @@ class BinhostHandler(object): |
88 |
> if maxval == 0: |
89 |
> maxval = 1 |
90 |
> onProgress(maxval, maxval) |
91 |
> - return None |
92 |
> + return (True, None) |
93 |
> diff --git a/pym/portage/emaint/modules/config/config.py |
94 |
> b/pym/portage/emaint/modules/config/config.py |
95 |
> index dad024b..a05a3c2 100644 |
96 |
> --- a/pym/portage/emaint/modules/config/config.py |
97 |
> +++ b/pym/portage/emaint/modules/config/config.py |
98 |
> @@ -36,7 +36,8 @@ class CleanConfig(object): |
99 |
> if onProgress: |
100 |
> onProgress(maxval, i+1) |
101 |
> i += 1 |
102 |
> - return self._format_output(messages) |
103 |
> + msgs = self._format_output(messages) |
104 |
> + return (True, msgs) |
105 |
> |
106 |
> def fix(self, **kwargs): |
107 |
> onProgress = kwargs.get('onProgress', None) |
108 |
> @@ -65,7 +66,8 @@ class CleanConfig(object): |
109 |
> i += 1 |
110 |
> if modified: |
111 |
> writedict(configs, self.target) |
112 |
> - return self._format_output(messages, True) |
113 |
> + msgs = self._format_output(messages, True) |
114 |
> + return (True, msgs) |
115 |
> |
116 |
> def _format_output(self, messages=[], cleaned=False): |
117 |
> output = [] |
118 |
> diff --git a/pym/portage/emaint/modules/logs/logs.py |
119 |
> b/pym/portage/emaint/modules/logs/logs.py |
120 |
> index fe65cf5..028084a 100644 |
121 |
> --- a/pym/portage/emaint/modules/logs/logs.py |
122 |
> +++ b/pym/portage/emaint/modules/logs/logs.py |
123 |
> @@ -40,7 +40,6 @@ class CleanLogs(object): |
124 |
> 'NUM': int: number of days |
125 |
> 'pretend': boolean |
126 |
> """ |
127 |
> - messages = [] |
128 |
> num_of_days = None |
129 |
> pretend = False |
130 |
> if kwargs: |
131 |
> @@ -70,10 +69,12 @@ class CleanLogs(object): |
132 |
> clean_cmd.remove("-delete") |
133 |
> |
134 |
> if not clean_cmd: |
135 |
> - return [] |
136 |
> + return (True, None) |
137 |
> rval = self._clean_logs(clean_cmd, settings) |
138 |
> - messages += self._convert_errors(rval) |
139 |
> - return messages |
140 |
> + errors = self._convert_errors(rval) |
141 |
> + if errors: |
142 |
> + return (False, errors) |
143 |
> + return (True, None) |
144 |
> |
145 |
> |
146 |
> @staticmethod |
147 |
> diff --git a/pym/portage/emaint/modules/merges/merges.py |
148 |
> b/pym/portage/emaint/modules/merges/merges.py |
149 |
> index 8f677c2..416a725 100644 |
150 |
> --- a/pym/portage/emaint/modules/merges/merges.py |
151 |
> +++ b/pym/portage/emaint/modules/merges/merges.py |
152 |
> @@ -239,7 +239,9 @@ class MergesHandler(object): |
153 |
> for pkg, mtime in failed_pkgs.items(): |
154 |
> mtime_str = time.ctime(int(mtime)) |
155 |
> errors.append("'%s' failed to merge on '%s'" |
156 |
> % (pkg, mtime_str)) |
157 |
> - return errors |
158 |
> + if errors: |
159 |
> + return (False, errors) |
160 |
> + return (True, None) |
161 |
> |
162 |
> |
163 |
> def fix(self, **kwargs): |
164 |
> @@ -247,13 +249,13 @@ class MergesHandler(object): |
165 |
> module_output = kwargs.get('module_output', None) |
166 |
> failed_pkgs = self._failed_pkgs() |
167 |
> if not failed_pkgs: |
168 |
> - return ['No failed merges found.'] |
169 |
> + return (True, ['No failed merges found.']) |
170 |
> |
171 |
> pkg_invalid_entries = set() |
172 |
> pkg_atoms = set() |
173 |
> self._get_pkg_atoms(failed_pkgs, pkg_atoms, |
174 |
> pkg_invalid_entries) if pkg_invalid_entries: |
175 |
> - return pkg_invalid_entries |
176 |
> + return (False, pkg_invalid_entries) |
177 |
> |
178 |
> try: |
179 |
> self._tracking_file.save(failed_pkgs) |
180 |
> @@ -261,7 +263,7 @@ class MergesHandler(object): |
181 |
> errors = ['Unable to save failed merges to |
182 |
> tracking file: %s\n' % str(ex)] |
183 |
> errors.append(', '.join(sorted(failed_pkgs))) |
184 |
> - return errors |
185 |
> + return (False, errors) |
186 |
> self._remove_failed_dirs(failed_pkgs) |
187 |
> results = self._emerge_pkg_atoms(module_output, |
188 |
> pkg_atoms) # list any new failed merges |
189 |
> @@ -276,12 +278,14 @@ class MergesHandler(object): |
190 |
> if not vardb.cpv_exists(pkg_name): |
191 |
> still_failed_pkgs[pkg] = mtime |
192 |
> self._tracking_file.save(still_failed_pkgs) |
193 |
> - return results |
194 |
> + if still_failed_pkgs: |
195 |
> + return (False, results) |
196 |
> + return (True, results) |
197 |
> |
198 |
> |
199 |
> def purge(self, **kwargs): |
200 |
> """Attempt to remove previously saved tracking |
201 |
> file.""" if not self._tracking_file.exists(): |
202 |
> - return ['Tracking file not found.'] |
203 |
> + return (True, ['Tracking file not found.']) |
204 |
> self._tracking_file.purge() |
205 |
> - return ['Removed tracking file.'] |
206 |
> + return (True, ['Removed tracking file.']) |
207 |
> diff --git a/pym/portage/emaint/modules/move/move.py |
208 |
> b/pym/portage/emaint/modules/move/move.py |
209 |
> index 41ca167..1c2636d 100644 |
210 |
> --- a/pym/portage/emaint/modules/move/move.py |
211 |
> +++ b/pym/portage/emaint/modules/move/move.py |
212 |
> @@ -123,7 +123,10 @@ class MoveHandler(object): |
213 |
> errors.append("'%s' has outdated |
214 |
> metadata" % cpv) if onProgress: |
215 |
> onProgress(maxval, i+1) |
216 |
> - return errors |
217 |
> + |
218 |
> + if errors: |
219 |
> + return (False, errors) |
220 |
> + return (True, None) |
221 |
> |
222 |
> def fix(self, **kwargs): |
223 |
> onProgress = kwargs.get('onProgress', None) |
224 |
> @@ -156,7 +159,9 @@ class MoveHandler(object): |
225 |
> # Searching for updates in all the metadata is |
226 |
> relatively slow, so this # is where the progress bar comes out of |
227 |
> indeterminate mode. self._tree.dbapi.update_ents(allupdates, |
228 |
> onProgress=onProgress) |
229 |
> - return errors |
230 |
> + if errors: |
231 |
> + return (False, errors) |
232 |
> + return (True, None) |
233 |
> |
234 |
> class MoveInstalled(MoveHandler): |
235 |
> |
236 |
> diff --git a/pym/portage/emaint/modules/resume/resume.py |
237 |
> b/pym/portage/emaint/modules/resume/resume.py |
238 |
> index 1bada52..0d65d41 100644 |
239 |
> --- a/pym/portage/emaint/modules/resume/resume.py |
240 |
> +++ b/pym/portage/emaint/modules/resume/resume.py |
241 |
> @@ -37,7 +37,7 @@ class CleanResume(object): |
242 |
> finally: |
243 |
> if onProgress: |
244 |
> onProgress(maxval, i+1) |
245 |
> - return messages |
246 |
> + return (True, messages) |
247 |
> |
248 |
> def fix(self, **kwargs): |
249 |
> onProgress = kwargs.get('onProgress', None) |
250 |
> @@ -56,3 +56,4 @@ class CleanResume(object): |
251 |
> onProgress(maxval, i+1) |
252 |
> if delete_count: |
253 |
> mtimedb.commit() |
254 |
> + return (True, None) |
255 |
> diff --git a/pym/portage/emaint/modules/sync/sync.py |
256 |
> b/pym/portage/emaint/modules/sync/sync.py |
257 |
> index 15d63e2..d867699 100644 |
258 |
> --- a/pym/portage/emaint/modules/sync/sync.py |
259 |
> +++ b/pym/portage/emaint/modules/sync/sync.py |
260 |
> @@ -127,8 +127,8 @@ class SyncRepos(object): |
261 |
> % (bold(", ".join(repos))) + |
262 |
> "\n ...returning" ] |
263 |
> if return_messages: |
264 |
> - return msgs |
265 |
> - return |
266 |
> + return (False, msgs) |
267 |
> + return (False, None) |
268 |
> return self._sync(selected, return_messages, |
269 |
> emaint_opts=options) |
270 |
> |
271 |
> @@ -211,8 +211,8 @@ class SyncRepos(object): |
272 |
> msgs.append("Emaint sync, nothing to sync... |
273 |
> returning") if return_messages: |
274 |
> msgs.extend(self.rmessage([('None', |
275 |
> os.EX_OK)], 'sync')) |
276 |
> - return msgs |
277 |
> - return |
278 |
> + return (True, msgs) |
279 |
> + return (True, None) |
280 |
> # Portage needs to ensure a sane umask for the files |
281 |
> it creates. os.umask(0o22) |
282 |
> |
283 |
> @@ -232,9 +232,14 @@ class SyncRepos(object): |
284 |
> sync_scheduler.wait() |
285 |
> retvals = sync_scheduler.retvals |
286 |
> msgs.extend(sync_scheduler.msgs) |
287 |
> + returncode = True |
288 |
> |
289 |
> if retvals: |
290 |
> msgs.extend(self.rmessage(retvals, 'sync')) |
291 |
> + for repo, returncode in retvals: |
292 |
> + if returncode != os.EX_OK: |
293 |
> + returncode = False |
294 |
> + break |
295 |
> else: |
296 |
> msgs.extend(self.rmessage([('None', |
297 |
> os.EX_OK)], 'sync')) |
298 |
> |
299 |
> @@ -244,6 +249,8 @@ class SyncRepos(object): |
300 |
> rcode = |
301 |
> sync_manager.perform_post_sync_hook('') if rcode: |
302 |
> msgs.extend(self.rmessage([('None', |
303 |
> rcode)], 'post-sync')) |
304 |
> + if rcode != os.EX_OK: |
305 |
> + returncode = False |
306 |
> |
307 |
> # Reload the whole config. |
308 |
> portage._sync_mode = False |
309 |
> @@ -254,8 +261,8 @@ class SyncRepos(object): |
310 |
> self.emerge_config.opts) |
311 |
> |
312 |
> if return_messages: |
313 |
> - return msgs |
314 |
> - return |
315 |
> + return (returncode, msgs) |
316 |
> + return (returncode, None) |
317 |
> |
318 |
> |
319 |
> def _do_pkg_moves(self): |
320 |
> @@ -355,7 +362,6 @@ class SyncScheduler(AsyncScheduler): |
321 |
> # that hooks will be called in a backward-compatible |
322 |
> manner # even if all sync tasks have failed. |
323 |
> hooks_enabled = True |
324 |
> - returncode = task.returncode |
325 |
> if task.returncode == os.EX_OK: |
326 |
> returncode, message, updatecache_flg, |
327 |
> hooks_enabled = task.result if message: |
328 |
> diff --git a/pym/portage/emaint/modules/world/world.py |
329 |
> b/pym/portage/emaint/modules/world/world.py |
330 |
> index 2c9dbff..ebc3adc 100644 |
331 |
> --- a/pym/portage/emaint/modules/world/world.py |
332 |
> +++ b/pym/portage/emaint/modules/world/world.py |
333 |
> @@ -65,7 +65,9 @@ class WorldHandler(object): |
334 |
> errors += ["'%s' is not installed" % x for x |
335 |
> in self.not_installed] else: |
336 |
> errors.append(self.world_file + " could not |
337 |
> be opened for reading") |
338 |
> - return errors |
339 |
> + if errors: |
340 |
> + return (False, errors) |
341 |
> + return (True, None) |
342 |
> |
343 |
> def fix(self, **kwargs): |
344 |
> onProgress = kwargs.get('onProgress', None) |
345 |
> @@ -83,7 +85,9 @@ class WorldHandler(object): |
346 |
> except |
347 |
> portage.exception.PortageException: errors.append("%s could not be |
348 |
> opened for writing" % \ self.world_file) |
349 |
> - return errors |
350 |
> + if errors: |
351 |
> + return (False, errors) |
352 |
> + return (True, None) |
353 |
> finally: |
354 |
> world_set.unlock() |
355 |
> |
356 |
> diff --git a/pym/portage/tests/emerge/test_simple.py |
357 |
> b/pym/portage/tests/emerge/test_simple.py |
358 |
> index b1a2af5..5930f6c 100644 |
359 |
> --- a/pym/portage/tests/emerge/test_simple.py |
360 |
> +++ b/pym/portage/tests/emerge/test_simple.py |
361 |
> @@ -382,6 +382,7 @@ pkg_preinst() { |
362 |
> "PORTAGE_PYTHON" : portage_python, |
363 |
> "PORTAGE_REPOSITORIES" : |
364 |
> settings.repositories.config_string(), "PORTAGE_TMPDIR" : |
365 |
> portage_tmpdir, |
366 |
> + "PORT_LOGDIR" : portage_tmpdir, |
367 |
> "PYTHONDONTWRITEBYTECODE" : |
368 |
> os.environ.get("PYTHONDONTWRITEBYTECODE", ""), "PYTHONPATH" : |
369 |
> pythonpath, "__PORTAGE_TEST_PATH_OVERRIDE" : fake_bin, |
370 |
|
371 |
merged :) thank you |
372 |
|
373 |
-- |
374 |
Brian Dolbec <dolsen> |