Gentoo Archives: gentoo-commits

From: Brian Dolbec <brian.dolbec@×××××.com>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:plugin-sync commit in: pym/portage/emaint/modules/sync/
Date: Fri, 02 May 2014 23:13:52
Message-Id: 1399072253.d998b427e535c0c7190c2fc3af9c1995ee82821e.dol-sen@gentoo
1 commit: d998b427e535c0c7190c2fc3af9c1995ee82821e
2 Author: Brian Dolbec <dolsen <AT> gentoo <DOT> org>
3 AuthorDate: Mon Apr 21 18:30:00 2014 +0000
4 Commit: Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
5 CommitDate: Fri May 2 23:10:53 2014 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=d998b427
7
8 emaint/modules: New emaint module "sync"
9
10 This code is a migration from _emerge.actions.action_sync.
11 The code has been split up into logical blocks.
12 Some changes have been made to handle multiple repositories better.
13 It also adds more flexibility as to what is synced.
14
15 ---
16 pym/portage/emaint/modules/sync/__init__.py | 44 ++++++
17 pym/portage/emaint/modules/sync/sync.py | 237 ++++++++++++++++++++++++++++
18 2 files changed, 281 insertions(+)
19
20 diff --git a/pym/portage/emaint/modules/sync/__init__.py b/pym/portage/emaint/modules/sync/__init__.py
21 new file mode 100644
22 index 0000000..4070200
23 --- /dev/null
24 +++ b/pym/portage/emaint/modules/sync/__init__.py
25 @@ -0,0 +1,44 @@
26 +# Copyright 2014 Gentoo Foundation
27 +# Distributed under the terms of the GNU General Public License v2
28 +
29 +"""Check repos.conf settings and sync repositories.
30 +"""
31 +
32 +
33 +module_spec = {
34 + 'name': 'sync',
35 + 'description': __doc__,
36 + 'provides':{
37 + 'sync-module': {
38 + 'name': "sync",
39 + 'class': "SyncRepos",
40 + 'description': __doc__,
41 + 'functions': ['allrepos', 'auto', 'repo'],
42 + 'func_desc': {
43 + 'repo': {
44 + "short": "-r", "long": "--repo",
45 + "help": "(sync module only): -r, --repo Sync the specified repo",
46 + 'status': "Syncing %s",
47 + 'action': 'store',
48 + 'func': 'repo',
49 + },
50 + 'allrepos': {
51 + "short": "-A", "long": "--allrepos",
52 + "help": "(sync module only): -A, --allrepos Sync all repos that have a sync-url defined",
53 + 'status': "Syncing %s",
54 + 'action': 'store_true',
55 + 'dest': 'allrepos',
56 + 'func': 'all_repos',
57 + },
58 + 'auto': {
59 + "short": "-a", "long": "--auto",
60 + "help": "(sync module only): -a, --auto Sync auto-sync enabled repos only",
61 + 'status': "Syncing %s",
62 + 'action': 'store_true',
63 + 'dest': 'auto',
64 + 'func': 'auto_sync',
65 + },
66 + }
67 + }
68 + }
69 + }
70
71 diff --git a/pym/portage/emaint/modules/sync/sync.py b/pym/portage/emaint/modules/sync/sync.py
72 new file mode 100644
73 index 0000000..3aa318a
74 --- /dev/null
75 +++ b/pym/portage/emaint/modules/sync/sync.py
76 @@ -0,0 +1,237 @@
77 +# Copyright 2014 Gentoo Foundation
78 +# Distributed under the terms of the GNU General Public License v2
79 +
80 +import logging
81 +import os
82 +import sys
83 +
84 +import portage
85 +from portage.localization import _
86 +from portage.output import bold, create_color_func
87 +from portage.sync import get_syncer
88 +from portage._global_updates import _global_updates
89 +from portage.util import writemsg_level
90 +
91 +import _emerge
92 +from _emerge.emergelog import emergelog
93 +
94 +
95 +portage.proxy.lazyimport.lazyimport(globals(),
96 + '_emerge.actions:adjust_configs,load_emerge_config',
97 + '_emerge.chk_updated_cfg_files:chk_updated_cfg_files',
98 + '_emerge.main:parse_opts',
99 + '_emerge.post_emerge:display_news_notification',
100 +)
101 +
102 +warn = create_color_func("WARN")
103 +
104 +if sys.hexversion >= 0x3000000:
105 + _basestring = str
106 +else:
107 + _basestring = basestring
108 +
109 +
110 +class SyncRepos(object):
111 +
112 + short_desc = "Check repos.conf settings and/or sync repositories"
113 +
114 + @staticmethod
115 + def name():
116 + return "sync"
117 +
118 +
119 + def can_progressbar(self, func):
120 + return False
121 +
122 +
123 + def __init__(self, emerge_config=None, emerge_logging=False):
124 + '''Class init function
125 +
126 + @param emerge_config: optional an emerge_config instance to use
127 + @param emerge_logging: boolean, defaults to False
128 + '''
129 + if emerge_config:
130 + self.emerge_config = emerge_config
131 + else:
132 + # need a basic options instance
133 + actions, opts, _files = parse_opts([], silent=True)
134 + self.emerge_config = load_emerge_config(
135 + action='sync', args=_files, trees=[], opts=opts)
136 + if emerge_logging:
137 + _emerge.emergelog._disable = False
138 + self.xterm_titles = "notitles" not in \
139 + self.emerge_config.target_config.settings.features
140 + emergelog(self.xterm_titles, " === sync")
141 +
142 +
143 + def auto_sync(self, **kwargs):
144 + '''Sync auto-sync enabled repos'''
145 + options = kwargs.get('options', None)
146 + selected = self._get_repos(True)
147 + if options.get('return-messages', False):
148 + return self.rmessage(self._sync(selected), 'sync')
149 + return self._sync(selected)
150 +
151 +
152 + def all_repos(self, **kwargs):
153 + '''Sync all repos defined in repos.conf'''
154 + selected = self._get_repos(auto_sync_only=False)
155 + options = kwargs.get('options', None)
156 + if options.get('return-messages', False):
157 + return self.rmessage(
158 + self._sync(selected),
159 + 'sync')
160 + return self._sync(selected)
161 +
162 +
163 + def repo(self, **kwargs):
164 + '''Sync the specified repo'''
165 + options = kwargs.get('options', None)
166 + if options:
167 + repos = options.get('repo', '')
168 + return_messages = options.get('return-messages', False)
169 + else:
170 + return_messages = False
171 + if isinstance(repos, _basestring):
172 + repos = repos.split()
173 + available = self._get_repos(auto_sync_only=False)
174 + selected = self._match_repos(repos, available)
175 + if return_messages:
176 + return self.rmessage(self._sync(selected), 'sync')
177 + return self._sync(selected)
178 +
179 +
180 + @staticmethod
181 + def _match_repos(repos, available):
182 + '''Internal search, matches up the repo.name in repos
183 +
184 + @param repos: list, of repo names to match
185 + @param avalable: list of repo objects to search
186 + @return: list of repo objects that match
187 + '''
188 + selected = []
189 + for repo in available:
190 + if repo.name in repos:
191 + selected.append(repo)
192 + return selected
193 +
194 +
195 + def _get_repos(self, auto_sync_only=True):
196 + selected_repos = []
197 + unknown_repo_names = []
198 + missing_sync_type = []
199 + if self.emerge_config.args:
200 + for repo_name in self.emerge_config.args:
201 + print("_get_repos(): repo_name =", repo_name)
202 + try:
203 + repo = self.emerge_config.target_config.settings.repositories[repo_name]
204 + except KeyError:
205 + unknown_repo_names.append(repo_name)
206 + else:
207 + selected_repos.append(repo)
208 + if repo.sync_type is None:
209 + missing_sync_type.append(repo)
210 +
211 + if unknown_repo_names:
212 + writemsg_level("!!! %s\n" % _("Unknown repo(s): %s") %
213 + " ".join(unknown_repo_names),
214 + level=logging.ERROR, noiselevel=-1)
215 +
216 + if missing_sync_type:
217 + writemsg_level("!!! %s\n" %
218 + _("Missing sync-type for repo(s): %s") %
219 + " ".join(repo.name for repo in missing_sync_type),
220 + level=logging.ERROR, noiselevel=-1)
221 +
222 + if unknown_repo_names or missing_sync_type:
223 + print("missing or unknown repos... returning")
224 + return []
225 +
226 + else:
227 + selected_repos.extend(self.emerge_config.target_config.settings.repositories)
228 + #print("_get_repos(), selected =", selected_repos)
229 + if auto_sync_only:
230 + return self._filter_auto(selected_repos)
231 + return selected_repos
232 +
233 +
234 + def _filter_auto(self, repos):
235 + selected = []
236 + for repo in repos:
237 + if repo.auto_sync in ['yes', 'true']:
238 + selected.append(repo)
239 + return selected
240 +
241 +
242 + def _sync(self, selected_repos):
243 + if not selected_repos:
244 + print("_sync(), nothing to sync... returning")
245 + return [('None', os.EX_OK)]
246 + # Portage needs to ensure a sane umask for the files it creates.
247 + os.umask(0o22)
248 + portage._sync_mode = True
249 +
250 + sync_manager = get_syncer(self.emerge_config.target_config.settings, emergelog)
251 + retvals = []
252 + for repo in selected_repos:
253 + print("syncing repo:", repo.name)
254 + if repo.sync_type is not None:
255 + returncode = sync_manager.sync(self.emerge_config, repo)
256 + #if returncode != os.EX_OK:
257 + retvals.append((repo.name, returncode))
258 +
259 + # Reload the whole config.
260 + portage._sync_mode = False
261 + self._reload_config()
262 + self._do_pkg_moves()
263 + self._check_updates()
264 + display_news_notification(self.emerge_config.target_config,
265 + self.emerge_config.opts)
266 + if retvals:
267 + return retvals
268 + return [('None', os.EX_OK)]
269 +
270 +
271 + def _do_pkg_moves(self):
272 + if self.emerge_config.opts.get('--package-moves') != 'n' and \
273 + _global_updates(self.emerge_config.trees,
274 + self.emerge_config.target_config.mtimedb["updates"],
275 + quiet=("--quiet" in self.emerge_config.opts)):
276 + self.emerge_config.target_config.mtimedb.commit()
277 + # Reload the whole config.
278 + self._reload_config()
279 +
280 +
281 + def _check_updates(self):
282 + mybestpv = self.emerge_config.target_config.trees['porttree'].dbapi.xmatch(
283 + "bestmatch-visible", portage.const.PORTAGE_PACKAGE_ATOM)
284 + mypvs = portage.best(
285 + self.emerge_config.target_config.trees['vartree'].dbapi.match(
286 + portage.const.PORTAGE_PACKAGE_ATOM))
287 +
288 + chk_updated_cfg_files(self.emerge_config.target_config.root,
289 + portage.util.shlex_split(
290 + self.emerge_config.target_config.settings.get("CONFIG_PROTECT", "")))
291 +
292 + if mybestpv != mypvs and "--quiet" not in self.emerge_config.opts:
293 + print()
294 + print(warn(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended")
295 + print(warn(" * ")+"that you update portage now, before any other packages are updated.")
296 + print()
297 + print(warn(" * ")+"To update portage, run 'emerge --oneshot portage' now.")
298 + print()
299 +
300 +
301 + def _reload_config(self):
302 + '''Reload the whole config from scratch.'''
303 + load_emerge_config(emerge_config=self.emerge_config)
304 + adjust_configs(self.emerge_config.opts, self.emerge_config.trees)
305 +
306 +
307 + def rmessage(self, rvals, action):
308 + '''Creates emaint style messages to return to the task handler'''
309 + messages = []
310 + for rval in rvals:
311 + messages.append("Action: %s for repo: %s, returned code = %s"
312 + % (action, rval[0], rval[1]))
313 + return messages