From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 4FF111389E2 for ; Wed, 31 Dec 2014 08:07:40 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id B3BACE088A; Wed, 31 Dec 2014 08:07:39 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id D0C2FE0885 for ; Wed, 31 Dec 2014 08:07:38 +0000 (UTC) Received: from localhost.localdomain (ip70-181-96-121.oc.oc.cox.net [70.181.96.121]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: zmedico) by smtp.gentoo.org (Postfix) with ESMTPSA id DB56C340509; Wed, 31 Dec 2014 08:07:37 +0000 (UTC) From: Zac Medico To: gentoo-portage-dev@lists.gentoo.org Cc: Zac Medico Subject: [gentoo-portage-dev] [PATCH] Add --sync-submodule (534070) Date: Wed, 31 Dec 2014 00:07:19 -0800 Message-Id: <1420013239-22660-1-git-send-email-zmedico@gentoo.org> X-Mailer: git-send-email 2.0.5 Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-portage-dev@lists.gentoo.org Reply-to: gentoo-portage-dev@lists.gentoo.org X-Archives-Salt: 50d5126a-9214-4b3e-9d78-1d63ba72cd8c X-Archives-Hash: ee279de6c84b7b797154116f06674fee This adds support for a new --sync-submodule option to both emerge and emaint. When this option is used with the sync action, only the selected submodules are synced. Each submodule is referenced using an abstract identifier, which serves to hide the implementation details involving the precise locations of specific submodules within each repository. Currently, --sync-submodule has no effect for sync protocols other than rsync, but the new SyncBase._get_submodule_paths() method will be useful for implementing support in other SyncBase subclasses. X-Gentoo-Bug: 534070 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=534070 --- man/emaint.1 | 9 ++++++++- man/emerge.1 | 7 +++++++ pym/_emerge/main.py | 7 +++++++ pym/portage/emaint/main.py | 12 +++++++++++- pym/portage/emaint/modules/sync/__init__.py | 10 ++++++++++ pym/portage/emaint/modules/sync/sync.py | 19 +++++++++++++++---- pym/portage/module.py | 15 +++++++++++++++ pym/portage/sync/modules/rsync/rsync.py | 16 +++++++++++++++- pym/portage/sync/syncbase.py | 14 +++++++++++++- 9 files changed, 101 insertions(+), 8 deletions(-) diff --git a/man/emaint.1 b/man/emaint.1 index f02bc68..67e05f1 100644 --- a/man/emaint.1 +++ b/man/emaint.1 @@ -1,4 +1,4 @@ -.TH "EMAINT" "1" "Nov 2008" "Portage VERSION" "Portage" +.TH "EMAINT" "1" "Dec 2014" "Portage VERSION" "Portage" .SH NAME emaint \- performs system health checks and maintenance .SH SYNOPSIS @@ -71,6 +71,13 @@ Sync all repositories which have a sync\-uri specified. (sync command only) .TP .B \-r, \-\-repo REPO Sync the repository specified. (sync command only) +.TP +.BR "\-\-sync-submodule " +Restrict sync to the specified submodule(s). This option may be +specified multiple times, in order to sync multiple submodules. +Currently, this option has no effect for sync protocols other +than rsync. +(sync command only) .SH "REPORTING BUGS" Please report bugs via http://bugs.gentoo.org/ .SH AUTHORS diff --git a/man/emerge.1 b/man/emerge.1 index faa1f33..3d4042c 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -836,6 +836,13 @@ remaining packages and any that have unsatisfied dependencies or are masked will be automatically dropped. Also see the related \fB\-\-keep\-going\fR option. .TP +.BR "\-\-sync\-submodule " +Restrict sync to the specified submodule(s). This option may be +specified multiple times, in order to sync multiple submodules. +Currently, this option has no effect for sync protocols other +than rsync. +(--sync action only) +.TP .BR "\-\-tree " (\fB\-t\fR) Shows the dependency tree for the given target by indenting dependencies. This is only really useful in combination with \fB\-\-emptytree\fR or diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py index 7c707f9..695a732 100644 --- a/pym/_emerge/main.py +++ b/pym/_emerge/main.py @@ -633,6 +633,13 @@ def parse_opts(tmpcmdline, silent=False): "choices" : true_y_or_n }, + "--sync-submodule": { + "help" : ("Restrict sync to the specified submodule(s)." + " (--sync action only)"), + "choices" : ("glsa", "news", "profiles"), + "action" : "append", + }, + "--use-ebuild-visibility": { "help" : "use unbuilt ebuild metadata for visibility checks on built packages", "choices" : true_y_or_n diff --git a/pym/portage/emaint/main.py b/pym/portage/emaint/main.py index fea4832..25a7706 100644 --- a/pym/portage/emaint/main.py +++ b/pym/portage/emaint/main.py @@ -34,6 +34,7 @@ class OptionItem(object): self.action = opt.get('action') self.type = opt.get('type') self.dest = opt.get('dest') + self.choices = opt.get('choices') @property def pargs(self): @@ -58,6 +59,8 @@ class OptionItem(object): kwargs['type'] = self.type if self.dest is not None: kwargs['dest'] = self.dest + if self.choices is not None: + kwargs['choices'] = self.choices return kwargs def usage(module_controller): @@ -89,7 +92,10 @@ def module_opts(module_controller, module): opts = DEFAULT_OPTIONS for opt in sorted(opts): optd = opts[opt] - opto = " %s, %s" % (optd['short'], optd['long']) + if 'short' in optd: + opto = " %s, %s" % (optd['short'], optd['long']) + else: + opto = " %s" % (optd['long'],) _usage += '%s %s\n' % (opto.ljust(15), optd['help']) _usage += '\n' return _usage @@ -174,6 +180,10 @@ def emaint_main(myargv): if desc: for opt in desc: parser_options.append(OptionItem(desc[opt])) + desc = module_controller.get_opt_descriptions(mod) + if desc: + for opt in desc: + parser_options.append(OptionItem(desc[opt])) for opt in parser_options: parser.add_argument(*opt.pargs, **opt.kwargs) diff --git a/pym/portage/emaint/modules/sync/__init__.py b/pym/portage/emaint/modules/sync/__init__.py index 32469b5..bc6dc5f 100644 --- a/pym/portage/emaint/modules/sync/__init__.py +++ b/pym/portage/emaint/modules/sync/__init__.py @@ -37,6 +37,16 @@ module_spec = { 'dest': 'auto', 'func': 'auto_sync', }, + }, + 'opt_desc': { + 'sync-submodule': { + "long": "--sync-submodule", + "help": ("(sync module only): Restrict sync " + "to the specified submodule(s)"), + "choices": ("glsa", "news", "profiles"), + "action": "append", + "dest": "sync_submodule", + }, } } } diff --git a/pym/portage/emaint/modules/sync/sync.py b/pym/portage/emaint/modules/sync/sync.py index 77c685c..c6aef95 100644 --- a/pym/portage/emaint/modules/sync/sync.py +++ b/pym/portage/emaint/modules/sync/sync.py @@ -90,7 +90,8 @@ class SyncRepos(object): return_messages = options.get('return-messages', False) else: return_messages = False - return self._sync(selected, return_messages) + return self._sync(selected, return_messages, + emaint_opts=options) def all_repos(self, **kwargs): @@ -101,7 +102,8 @@ class SyncRepos(object): return_messages = options.get('return-messages', False) else: return_messages = False - return self._sync(selected, return_messages) + return self._sync(selected, return_messages, + emaint_opts=options) def repo(self, **kwargs): @@ -123,7 +125,8 @@ class SyncRepos(object): if return_messages: return msgs return - return self._sync(selected, return_messages) + return self._sync(selected, return_messages, + emaint_opts=options) @staticmethod @@ -189,7 +192,15 @@ class SyncRepos(object): return selected - def _sync(self, selected_repos, return_messages): + def _sync(self, selected_repos, return_messages, + emaint_opts=None): + + if emaint_opts is not None: + for k, v in emaint_opts.items(): + if v is not None: + k = "--" + k.replace("_", "-") + self.emerge_config.opts[k] = v + msgs = [] if not selected_repos: msgs.append("Emaint sync, nothing to sync... returning") diff --git a/pym/portage/module.py b/pym/portage/module.py index a78bb2e..e40a548 100644 --- a/pym/portage/module.py +++ b/pym/portage/module.py @@ -179,3 +179,18 @@ class Modules(object): raise InvalidModuleName("Module name '%s' was invalid or not" %modname + "found") return desc + + def get_opt_descriptions(self, modname): + """Retrieves the module class exported options descriptions + + @type modname: string + @param modname: the module class name + @type dictionary + @return: the modules class exported options descriptions + """ + if modname and modname in self.module_names: + desc = self._modules[modname].get('opt_desc') + else: + raise InvalidModuleName( + "Module name '%s' was invalid or not found" % modname) + return desc diff --git a/pym/portage/sync/modules/rsync/rsync.py b/pym/portage/sync/modules/rsync/rsync.py index 74c10e7..900351d 100644 --- a/pym/portage/sync/modules/rsync/rsync.py +++ b/pym/portage/sync/modules/rsync/rsync.py @@ -488,7 +488,21 @@ class RsyncSync(SyncBase): exitcode = SERVER_OUT_OF_DATE elif (servertimestamp == 0) or (servertimestamp > timestamp): # actual sync - command = rsynccommand + [syncuri+"/", self.repo.location] + command = rsynccommand[:] + submodule_paths = self._get_submodule_paths() + if submodule_paths: + # The only way to select multiple directories to + # sync, without calling rsync multiple times, is + # to use --relative. + command.append("--relative") + for path in submodule_paths: + # /./ is special syntax supported with the + # rsync --relative option. + command.append(syncuri + "/./" + path) + command.append(self.repo.location) + else: + command.extend([syncuri + "/", self.repo.location]) + exitcode = None try: exitcode = portage.process.spawn(command, diff --git a/pym/portage/sync/syncbase.py b/pym/portage/sync/syncbase.py index 94d4aab..fcde51f 100644 --- a/pym/portage/sync/syncbase.py +++ b/pym/portage/sync/syncbase.py @@ -12,6 +12,11 @@ import os import portage from portage.util import writemsg_level +_SUBMODULE_PATH_MAP = { + 'glsa': 'metadata/glsa', + 'news': 'metadata/news', + 'profiles': 'profiles', +} class SyncBase(object): '''Base Sync class for subclassing''' @@ -57,7 +62,6 @@ class SyncBase(object): self.xterm_titles = self.options.get('xterm_titles', False) self.spawn_kwargs = self.options.get('spawn_kwargs', None) - def exists(self, **kwargs): '''Tests whether the repo actually exists''' if kwargs: @@ -100,3 +104,11 @@ class SyncBase(object): # and portdb properly account for its existence. ''' pass + + def _get_submodule_paths(self): + paths = [] + emerge_config = self.options.get('emerge_config') + if emerge_config is not None: + for name in emerge_config.opts.get('--sync-submodule', []): + paths.append(_SUBMODULE_PATH_MAP[name]) + return tuple(paths) -- 2.0.5