commit: 957160d020ce6a31912932495ff17382442509f4
Author: Brian Dolbec <dolsen <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 21 18:30:00 2014 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Oct 20 03:48:33 2014 +0000
URL:
http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=957160d0
emaint/modules: New emaint module "sync"
This code is a migration from _emerge.actions.action_sync.
The code has been split up into logical blocks.
Some changes have been made to handle multiple repositories better.
It also adds more flexibility as to what is synced.
---
pym/portage/emaint/modules/sync/__init__.py | 44 ++++++
pym/portage/emaint/modules/sync/sync.py | 237 ++++++++++++++++++++++++++++
2 files changed, 281 insertions(+)
diff --git a/pym/portage/emaint/modules/sync/__init__.py
b/pym/portage/emaint/modules/sync/__init__.py
new file mode 100644
index 0000000..4070200
--- /dev/null
+++ b/pym/portage/emaint/modules/sync/__init__.py
@@ -0,0 +1,44 @@
+# Copyright 2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+"""Check repos.conf settings and sync repositories.
+"""
+
+
+module_spec = {
+ 'name': 'sync',
+ 'description': __doc__,
+ 'provides':{
+ 'sync-module': {
+ 'name': "sync",
+ 'class': "SyncRepos",
+ 'description': __doc__,
+ 'functions': ['allrepos', 'auto', 'repo'],
+ 'func_desc': {
+ 'repo': {
+ "short": "-r", "long": "--repo",
+ "help": "(sync module only): -r, --repo
Sync the specified repo",
+ 'status': "Syncing %s",
+ 'action': 'store',
+ 'func': 'repo',
+ },
+ 'allrepos': {
+ "short": "-A", "long": "--allrepos",
+ "help": "(sync module only): -A,
--allrepos Sync all repos that have a sync-url defined",
+ 'status': "Syncing %s",
+ 'action': 'store_true',
+ 'dest': 'allrepos',
+ 'func': 'all_repos',
+ },
+ 'auto': {
+ "short": "-a", "long": "--auto",
+ "help": "(sync module only): -a, --auto
Sync auto-sync enabled repos only",
+ 'status': "Syncing %s",
+ 'action': 'store_true',
+ 'dest': 'auto',
+ 'func': 'auto_sync',
+ },
+ }
+ }
+ }
+ }
diff --git a/pym/portage/emaint/modules/sync/sync.py
b/pym/portage/emaint/modules/sync/sync.py
new file mode 100644
index 0000000..3aa318a
--- /dev/null
+++ b/pym/portage/emaint/modules/sync/sync.py
@@ -0,0 +1,237 @@
+# Copyright 2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import logging
+import os
+import sys
+
+import portage
+from portage.localization import _
+from portage.output import bold, create_color_func
+from portage.sync import get_syncer
+from portage._global_updates import _global_updates
+from portage.util import writemsg_level
+
+import _emerge
+from _emerge.emergelog import emergelog
+
+
+portage.proxy.lazyimport.lazyimport(globals(),
+ '_emerge.actions:adjust_configs,load_emerge_config',
+ '_emerge.chk_updated_cfg_files:chk_updated_cfg_files',
+ '_emerge.main:parse_opts',
+ '_emerge.post_emerge:display_news_notification',
+)
+
+warn = create_color_func("WARN")
+
+if sys.hexversion >= 0x3000000:
+ _basestring = str
+else:
+ _basestring = basestring
+
+
+class SyncRepos(object):
+
+ short_desc = "Check repos.conf settings and/or sync repositories"
+
+ @staticmethod
+ def name():
+ return "sync"
+
+
+ def can_progressbar(self, func):
+ return False
+
+
+ def __init__(self, emerge_config=None, emerge_logging=False):
+ '''Class init function
+
+ @param emerge_config: optional an emerge_config instance to use
+ @param emerge_logging: boolean, defaults to False
+ '''
+ if emerge_config:
+ self.emerge_config = emerge_config
+ else:
+ # need a basic options instance
+ actions, opts, _files = parse_opts([], silent=True)
+ self.emerge_config = load_emerge_config(
+ action='sync', args=_files, trees=[], opts=opts)
+ if emerge_logging:
+ _emerge.emergelog._disable = False
+ self.xterm_titles = "notitles" not in \
+ self.emerge_config.target_config.settings.features
+ emergelog(self.xterm_titles, " === sync")
+
+
+ def auto_sync(self, **kwargs):
+ '''Sync auto-sync enabled repos'''
+ options = kwargs.get('options', None)
+ selected = self._get_repos(True)
+ if options.get('return-messages', False):
+ return self.rmessage(self._sync(selected), 'sync')
+ return self._sync(selected)
+
+
+ def all_repos(self, **kwargs):
+ '''Sync all repos defined in repos.conf'''
+ selected = self._get_repos(auto_sync_only=False)
+ options = kwargs.get('options', None)
+ if options.get('return-messages', False):
+ return self.rmessage(
+ self._sync(selected),
+ 'sync')
+ return self._sync(selected)
+
+
+ def repo(self, **kwargs):
+ '''Sync the specified repo'''
+ options = kwargs.get('options', None)
+ if options:
+ repos = options.get('repo', '')
+ return_messages = options.get('return-messages', False)
+ else:
+ return_messages = False
+ if isinstance(repos, _basestring):
+ repos = repos.split()
+ available = self._get_repos(auto_sync_only=False)
+ selected = self._match_repos(repos, available)
+ if return_messages:
+ return self.rmessage(self._sync(selected), 'sync')
+ return self._sync(selected)
+
+
+ @staticmethod
+ def _match_repos(repos, available):
+ '''Internal search, matches up the repo.name in repos
+
+ @param repos: list, of repo names to match
+ @param avalable: list of repo objects to search
+ @return: list of repo objects that match
+ '''
+ selected = []
+ for repo in available:
+ if repo.name in repos:
+ selected.append(repo)
+ return selected
+
+
+ def _get_repos(self, auto_sync_only=True):
+ selected_repos = []
+ unknown_repo_names = []
+ missing_sync_type = []
+ if self.emerge_config.args:
+ for repo_name in self.emerge_config.args:
+ print("_get_repos(): repo_name =", repo_name)
+ try:
+ repo =
self.emerge_config.target_config.settings.repositories[repo_name]
+ except KeyError:
+ unknown_repo_names.append(repo_name)
+ else:
+ selected_repos.append(repo)
+ if repo.sync_type is None:
+ missing_sync_type.append(repo)
+
+ if unknown_repo_names:
+ writemsg_level("!!! %s\n" % _("Unknown repo(s):
%s") %
+ " ".join(unknown_repo_names),
+ level=logging.ERROR, noiselevel=-1)
+
+ if missing_sync_type:
+ writemsg_level("!!! %s\n" %
+ _("Missing sync-type for repo(s): %s") %
+ " ".join(repo.name for repo in
missing_sync_type),
+ level=logging.ERROR, noiselevel=-1)
+
+ if unknown_repo_names or missing_sync_type:
+ print("missing or unknown repos... returning")
+ return []
+
+ else:
+
selected_repos.extend(self.emerge_config.target_config.settings.repositories)
+ #print("_get_repos(), selected =", selected_repos)
+ if auto_sync_only:
+ return self._filter_auto(selected_repos)
+ return selected_repos
+
+
+ def _filter_auto(self, repos):
+ selected = []
+ for repo in repos:
+ if repo.auto_sync in ['yes', 'true']:
+ selected.append(repo)
+ return selected
+
+
+ def _sync(self, selected_repos):
+ if not selected_repos:
+ print("_sync(), nothing to sync... returning")
+ return [('None', os.EX_OK)]
+ # Portage needs to ensure a sane umask for the files it creates.
+ os.umask(0o22)
+ portage._sync_mode = True
+
+ sync_manager =
get_syncer(self.emerge_config.target_config.settings, emergelog)
+ retvals = []
+ for repo in selected_repos:
+ print("syncing repo:", repo.name)
+ if repo.sync_type is not None:
+ returncode =
sync_manager.sync(self.emerge_config, repo)
+ #if returncode != os.EX_OK:
+ retvals.append((repo.name, returncode))
+
+ # Reload the whole config.
+ portage._sync_mode = False
+ self._reload_config()
+ self._do_pkg_moves()
+ self._check_updates()
+ display_news_notification(self.emerge_config.target_config,
+ self.emerge_config.opts)
+ if retvals:
+ return retvals
+ return [('None', os.EX_OK)]
+
+
+ def _do_pkg_moves(self):
+ if self.emerge_config.opts.get('--package-moves') != 'n' and \
+ _global_updates(self.emerge_config.trees,
+ self.emerge_config.target_config.mtimedb["updates"],
+ quiet=("--quiet" in self.emerge_config.opts)):
+ self.emerge_config.target_config.mtimedb.commit()
+ # Reload the whole config.
+ self._reload_config()
+
+
+ def _check_updates(self):
+ mybestpv =
self.emerge_config.target_config.trees['porttree'].dbapi.xmatch(
+ "bestmatch-visible", portage.const.PORTAGE_PACKAGE_ATOM)
+ mypvs = portage.best(
+
self.emerge_config.target_config.trees['vartree'].dbapi.match(
+ portage.const.PORTAGE_PACKAGE_ATOM))
+
+ chk_updated_cfg_files(self.emerge_config.target_config.root,
+ portage.util.shlex_split(
+
self.emerge_config.target_config.settings.get("CONFIG_PROTECT", "")))
+
+ if mybestpv != mypvs and "--quiet" not in
self.emerge_config.opts:
+ print()
+ print(warn(" * ")+bold("An update to portage is
available.")+" It is _highly_ recommended")
+ print(warn(" * ")+"that you update portage now, before
any other packages are updated.")
+ print()
+ print(warn(" * ")+"To update portage, run 'emerge
--oneshot portage' now.")
+ print()
+
+
+ def _reload_config(self):
+ '''Reload the whole config from scratch.'''
+ load_emerge_config(emerge_config=self.emerge_config)
+ adjust_configs(self.emerge_config.opts,
self.emerge_config.trees)
+
+
+ def rmessage(self, rvals, action):
+ '''Creates emaint style messages to return to the task
handler'''
+ messages = []
+ for rval in rvals:
+ messages.append("Action: %s for repo: %s, returned code
= %s"
+ % (action, rval[0], rval[1]))
+ return messages