Clarify/document some parameter processing, particular around groups
that specify they only apply to particular repositories (via the
"for_repos" config value).
Lots of comments added to clarify the processing/handling.
* tools/hook-scripts/mailer/mailer.py:
(main): pass REPOS_DIR rather than REPOS to the Config constructor.
It only needs the directory, not the repository object.
(Config.__init__): accept the REPOS_DIR instead of a Repository
object. Rename GLOBAL_PARAMS to DEFAULT_PARAMS for consistency in
some later naming. Omit saving the (old) GLOBAL_PARAMS concept, as
nobody ever uses that. Pass the DEFAULT_PARAMS into prep_groups(),
and update to pass REPOS_DIR.
(Config._prep_groups): revise params to take REPOS_DIR and
DEFAULT_PARAMS (instead of using the old dropped-off globals).
Add new repos_params() function to look for a "for_repos" config
value to see if this group/section applies to the repository
specified by REPOS_DIR. Replaces two similar hunks of code in this
method. Use repos_params() for the self._default_params and each
group/section found in the configuration file.
git-svn-id: https://svn.apache.org/repos/asf/subversion/trunk@1917632 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/tools/hook-scripts/mailer/mailer.py b/tools/hook-scripts/mailer/mailer.py
index 6844838..2e8f19f 100755
--- a/tools/hook-scripts/mailer/mailer.py
+++ b/tools/hook-scripts/mailer/mailer.py
@@ -109,7 +109,7 @@
if cmd == 'commit':
revision = int(cmd_args[0])
repos = Repository(repos_dir, revision, pool)
- cfg = Config(config_fname, repos,
+ cfg = Config(config_fname, repos_dir,
{'author': repos.author,
'repos_basename': os.path.basename(repos.repos_dir)
})
@@ -125,7 +125,7 @@
repos = Repository(repos_dir, revision, pool)
# Override the repos revision author with the author of the propchange
repos.author = author
- cfg = Config(config_fname, repos,
+ cfg = Config(config_fname, repos_dir,
{'author': author,
'repos_basename': os.path.basename(repos.repos_dir)
})
@@ -135,7 +135,7 @@
repos = Repository(repos_dir, 0, pool) ### any old revision will do
# Override the repos revision author with the author of the lock/unlock
repos.author = author
- cfg = Config(config_fname, repos,
+ cfg = Config(config_fname, repos_dir,
{'author': author,
'repos_basename': os.path.basename(repos.repos_dir)
})
@@ -1251,7 +1251,7 @@
# set of groups.
_predefined = ('general', 'defaults', 'maps')
- def __init__(self, fname, repos, global_params):
+ def __init__(self, fname, repos_dir, default_params):
cp = configparser.ConfigParser()
cp.read(fname)
@@ -1277,14 +1277,11 @@
if not hasattr(self, 'maps'):
self.maps = _sub_section()
- # these params are always available, although they may be overridden
- self._global_params = global_params.copy()
-
# prepare maps. this may remove sections from consideration as a group.
self._prep_maps()
# process all the group sections.
- self._prep_groups(repos)
+ self._prep_groups(repos_dir, default_params)
def is_set(self, option):
"""Return None if the option is not set; otherwise, its value is returned.
@@ -1371,46 +1368,59 @@
for sectname in mapsections:
self._groups.remove(sectname)
-
- def _prep_groups(self, repos):
+ def _prep_groups(self, repos_dir, default_params):
self._group_re = [ ]
- repos_dir = os.path.abspath(repos.repos_dir)
+ ### does it arrive as an abspath?
+ repos_dir = os.path.abspath(repos_dir)
+
+ def repos_params(section_name, defaults):
+ "Build key/value params for this section, based on current repos."
+
+ section = getattr(self, section_name) # should exist
+ if hasattr(section, 'for_repos'):
+ match = re.match(section.for_repos, repos_dir)
+ if not match:
+ # The FOR_REPOS selector does not apply to this repository.
+ return None # no params at all
+
+ # Extract key/value pairs from the regex match of this
+ # repository, and merge them into the default params.
+ # Make sure to copy() to avoid mutation of the argument.
+ return defaults.copy().update(match.groupdict())
+
+ # There are no repository-specific key/value params, to add.
+ return defaults
# compute the default repository-based parameters. start with some
# basic parameters, then bring in the regex-based params.
- self._default_params = self._global_params
-
- try:
- match = re.match(self.defaults.for_repos, repos_dir)
- if match:
- self._default_params = self._default_params.copy()
- self._default_params.update(match.groupdict())
- except AttributeError:
- # there is no self.defaults.for_repos
- pass
+ # Note: use the defaults, even if selected-against by FOR_REPOS
+ self._default_params = (repos_params('defaults', default_params)
+ or default_params)
# select the groups that apply to this repository
for group in self._groups:
- sub = getattr(self, group)
- params = self._default_params
- if hasattr(sub, 'for_repos'):
- match = re.match(sub.for_repos, repos_dir)
- if not match:
+ params = repos_params(group, self._default_params)
+ if params is None:
+ # There was a FOR_REPOS, but this repos does not match.
+ # Thus, ignore this param group.
continue
- params = params.copy()
- params.update(match.groupdict())
+
+ sub = getattr(self, group)
# if a matching rule hasn't been given, then use the empty string
# as it will match all paths
for_paths = getattr(sub, 'for_paths', '')
+
+ # Build an optional regex to exclude some change paths.
exclude_paths = getattr(sub, 'exclude_paths', None)
if exclude_paths:
exclude_paths_re = re.compile(exclude_paths)
else:
exclude_paths_re = None
- # check search_logmsg re
+ # Build an optional regex to extract key/value pairs from the
+ # log message to augment the params.
search_logmsg = getattr(sub, 'search_logmsg', None)
if search_logmsg is not None:
search_logmsg_re = re.compile(search_logmsg)