aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pym/portage/emaint/modules/sync/sync.py')
-rw-r--r--pym/portage/emaint/modules/sync/sync.py57
1 files changed, 48 insertions, 9 deletions
diff --git a/pym/portage/emaint/modules/sync/sync.py b/pym/portage/emaint/modules/sync/sync.py
index 57c779d31..15d63e2c8 100644
--- a/pym/portage/emaint/modules/sync/sync.py
+++ b/pym/portage/emaint/modules/sync/sync.py
@@ -233,15 +233,17 @@ class SyncRepos(object):
retvals = sync_scheduler.retvals
msgs.extend(sync_scheduler.msgs)
- # run the post_sync_hook one last time for
- # run only at sync completion hooks
- rcode = sync_manager.perform_post_sync_hook('')
if retvals:
msgs.extend(self.rmessage(retvals, 'sync'))
else:
msgs.extend(self.rmessage([('None', os.EX_OK)], 'sync'))
- if rcode:
- msgs.extend(self.rmessage([('None', rcode)], 'post-sync'))
+
+ # run the post_sync_hook one last time for
+ # run only at sync completion hooks
+ if sync_scheduler.global_hooks_enabled:
+ rcode = sync_manager.perform_post_sync_hook('')
+ if rcode:
+ msgs.extend(self.rmessage([('None', rcode)], 'post-sync'))
# Reload the whole config.
portage._sync_mode = False
@@ -339,6 +341,8 @@ class SyncScheduler(AsyncScheduler):
if master.name in selected_repo_names:
self._repo_map[master.name] = master
self._sync_graph.add(master.name, repo.name)
+ self._complete_graph = self._sync_graph.copy()
+ self._hooks_repos = set()
self._update_leaf_nodes()
def _task_exit(self, task):
@@ -347,9 +351,13 @@ class SyncScheduler(AsyncScheduler):
more leaf nodes.
'''
self._running_tasks.discard(task)
+ # Set hooks_enabled = True by default, in order to ensure
+ # that hooks will be called in a backward-compatible manner
+ # even if all sync tasks have failed.
+ hooks_enabled = True
returncode = task.returncode
if task.returncode == os.EX_OK:
- returncode, message, updatecache_flg = task.result
+ returncode, message, updatecache_flg, hooks_enabled = task.result
if message:
self.msgs.append(message)
repo = task.kwargs['repo'].name
@@ -357,8 +365,38 @@ class SyncScheduler(AsyncScheduler):
self.retvals.append((repo, returncode))
self._sync_graph.remove(repo)
self._update_leaf_nodes()
+ if hooks_enabled:
+ self._hooks_repos.add(repo)
super(SyncScheduler, self)._task_exit(self)
+ def _master_hooks(self, repo_name):
+ """
+ @param repo_name: a repo name
+ @type repo_name: str
+ @return: True if hooks would have been executed for any master
+ repositories of the given repo, False otherwise
+ @rtype: bool
+ """
+ traversed_nodes = set()
+ node_stack = [repo_name]
+ while node_stack:
+ node = node_stack.pop()
+ if node in self._hooks_repos:
+ return True
+ if node not in traversed_nodes:
+ traversed_nodes.add(node)
+ node_stack.extend(self._complete_graph.child_nodes(node))
+ return False
+
+ @property
+ def global_hooks_enabled(self):
+ """
+ @return: True if repo.postsync.d hooks would have been executed
+ for any repositories.
+ @rtype: bool
+ """
+ return bool(self._hooks_repos)
+
def _update_leaf_nodes(self):
'''
Populate self._leaf_nodes with current leaves from
@@ -389,9 +427,10 @@ class SyncScheduler(AsyncScheduler):
self._running_repos.add(node)
self._update_leaf_nodes()
- task = self._sync_manager.async(
- self._emerge_config, self._repo_map[node])
- return task
+ return self._sync_manager.async(
+ emerge_config=self._emerge_config,
+ repo=self._repo_map[node],
+ master_hooks=self._master_hooks(node))
def _can_add_job(self):
'''