public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-portage-dev] [PATCH] Add --sync-submodule <glsa|news|profiles> (534070)
@ 2014-12-31  8:07 Zac Medico
  2015-01-05 13:52 ` Alexander Berntsen
  2015-01-07  4:53 ` Brian Dolbec
  0 siblings, 2 replies; 6+ messages in thread
From: Zac Medico @ 2014-12-31  8:07 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Zac Medico

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 <glsa|news|profiles>"
+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 <glsa|news|profiles>"
+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



^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-01-08  4:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-31  8:07 [gentoo-portage-dev] [PATCH] Add --sync-submodule <glsa|news|profiles> (534070) Zac Medico
2015-01-05 13:52 ` Alexander Berntsen
2015-01-07  4:53 ` Brian Dolbec
2015-01-07  9:31   ` Zac Medico
2015-01-07 10:08     ` [gentoo-portage-dev] [PATCH] Use _SUBMODULE_PATH_MAP keys for option choices Zac Medico
2015-01-08  4:31       ` Brian Dolbec

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox