add --ini and --section options to maven-build and wrapper-rpm

Support use of a .ini file to pass parameters to maven-build and wrapper-rpm.
This commit is contained in:
Mike Bonnet 2014-10-21 14:24:32 -04:00 committed by Mike McLean
parent df316c0c6f
commit 1e8b7211ee
2 changed files with 166 additions and 91 deletions

View file

@ -1071,6 +1071,11 @@ def handle_maven_build(options, session, args):
parser.add_option("-M", "--maven-option", action="append",
dest="maven_options", metavar="OPTION", default=[],
help=_("Pass a command-line option to Maven"))
parser.add_option("--ini", action="append",
dest="inis", metavar="CONFIG", default=[],
help=_("Pass build parameters via a .ini file"))
parser.add_option("-s", "--section",
help=_("Get build parameters from this section of the .ini"))
parser.add_option("--debug", action="store_true",
help=_("Run Maven build in debug mode"))
parser.add_option("--specfile", action="store", metavar="URL",
@ -1086,9 +1091,12 @@ def handle_maven_build(options, session, args):
parser.add_option("--background", action="store_true",
help=_("Run the build at a lower priority"))
(build_opts, args) = parser.parse_args(args)
if len(args) != 2:
parser.error(_("Exactly two arguments (a build target and a SCM URL) are required"))
assert False
if build_opts.inis:
if len(args)!= 1:
parser.error(_("Exactly one argument (a build target) is required"))
else:
if len(args) != 2:
parser.error(_("Exactly two arguments (a build target and a SCM URL) are required"))
activate_session(session)
target = args[0]
build_target = session.getBuildTarget(target)
@ -1099,34 +1107,25 @@ def handle_maven_build(options, session, args):
parser.error(_("Unknown destination tag: %s" % build_target['dest_tag_name']))
if dest_tag['locked'] and not build_opts.scratch:
parser.error(_("Destination tag %s is locked" % dest_tag['name']))
source = args[1]
if '://' not in source:
parser.error(_("Invalid SCM URL: %s" % source))
assert False
opts = {}
if build_opts.inis:
try:
params = koji.util.parse_maven_param(build_opts.inis, scratch=build_opts.scratch,
section=build_opts.section)
except ValueError, e:
parser.error(e.args[0])
opts = params.values()[0]
if opts.pop('type', 'maven') != 'maven':
parser.error(_("Section %s does not contain a maven-build config") % params.keys()[0])
source = opts.pop('scmurl')
else:
source = args[1]
if '://' not in source:
parser.error(_("Invalid SCM URL: %s" % source))
opts = koji.util.maven_opts(build_opts, scratch=build_opts.scratch)
if build_opts.debug:
build_opts.maven_options.append('--debug')
for key in ('skip_tag', 'scratch', 'specfile', 'patches', 'goals', 'profiles', 'packages', 'jvm_options', 'maven_options'):
val = getattr(build_opts, key)
if val:
opts[key] = val
props = {}
for prop in build_opts.properties:
fields = prop.split('=', 1)
if len(fields) != 2:
fields.append(None)
props[fields[0]] = fields[1]
if props:
opts['properties'] = props
envs = {}
for env in build_opts.envs:
fields = env.split('=', 1)
if len(fields) != 2:
parser.error(_("Environment variables must be in NAME=VALUE format"))
assert False
envs[fields[0]] = fields[1]
if envs:
opts['envs'] = envs
opts.setdefault('maven_options', []).append('--debug')
if build_opts.skip_tag:
opts['skip_tag'] = True
priority = None
if build_opts.background:
#relative to koji.PRIO_DEFAULT
@ -1146,22 +1145,47 @@ def handle_wrapper_rpm(options, session, args):
usage += _("\n(Specify the --help global option for a list of other help options)")
parser = OptionParser(usage=usage)
parser.add_option("--create-build", action="store_true", help=_("Create a new build to contain wrapper rpms"))
parser.add_option("--ini", action="append",
dest="inis", metavar="CONFIG", default=[],
help=_("Pass build parameters via a .ini file"))
parser.add_option("-s", "--section",
help=_("Get build parameters from this section of the .ini"))
parser.add_option("--skip-tag", action="store_true", help=_("If creating a new build, don't tag it"))
parser.add_option("--scratch", action="store_true", help=_("Perform a scratch build"))
parser.add_option("--nowait", action="store_true", help=_("Don't wait on build"))
parser.add_option("--background", action="store_true", help=_("Run the build at a lower priority"))
(build_opts, args) = parser.parse_args(args)
if len(args) < 3:
parser.error(_("You must provide a build target, a build ID or NVR, and a SCM URL to a specfile fragment"))
assert False
if build_opts.inis:
if len(args)!= 1:
parser.error(_("Exactly one argument (a build target) is required"))
else:
if len(args) < 3:
parser.error(_("You must provide a build target, a build ID or NVR, and a SCM URL to a specfile fragment"))
activate_session(session)
target = args[0]
build_id = args[1]
if build_id.isdigit():
build_id = int(build_id)
url = args[2]
if build_opts.inis:
try:
params = koji.util.parse_maven_param(build_opts.inis, scratch=build_opts.scratch,
section=build_opts.section)
except ValueError, e:
parser.error(e.args[0])
opts = params.values()[0]
if opts.get('type') != 'wrapper':
parser.error(_("Section %s does not contain a wrapper-rpm config") % params.keys()[0])
url = opts['scmurl']
package = opts['buildrequires'][0]
target_info = session.getBuildTarget(target, strict=True)
latest_builds = session.getLatestBuilds(target_info['dest_tag'], package=package)
if not latest_builds:
parser.error(_("No build of %s in %s") % (package, target_info['dest_tag_name']))
build_id = latest_builds[0]['nvr']
else:
build_id = args[1]
if build_id.isdigit():
build_id = int(build_id)
url = args[2]
priority = None
if build_opts.background:
priority = 5

View file

@ -460,65 +460,81 @@ def tsort(parts):
raise ValueError, 'total ordering not possible'
return result
def _maven_params(config, package, scratch=False):
params = {}
for name, value in config.items(package):
value = value.strip()
if not value:
continue
if name in ['scmurl', 'patches', 'specfile']:
# single-valued options
pass
elif name in ['buildrequires', 'goals', 'profiles', 'packages',
'jvm_options', 'maven_options']:
# multi-valued options
value = value.split()
elif name == 'properties':
props = {}
for prop in value.splitlines():
fields = prop.split('=', 1)
if len(fields) != 2:
fields.append(None)
props[fields[0]] = fields[1]
value = props
elif name == 'envs':
envs = {}
for env in value.splitlines():
fields = env.split('=', 1)
if len(fields) != 2:
raise ValueError, "Environment variables must be in NAME=VALUE format"
envs[fields[0]] = fields[1]
value = envs
elif name == 'type':
continue
else:
raise ValueError, "Unknown option: %s" % name
params[name] = value
return params
class MavenConfigOptAdapter(object):
"""
Wrap a ConfigParser so it looks like a optparse.Values instance
used by maven-build.
"""
MULTILINE = ['properties', 'envs']
MULTIVALUE = ['goals', 'profiles', 'packages',
'jvm_options', 'maven_options', 'buildrequires']
def _wrapper_params(config, package, scratch=False):
def __init__(self, conf, section):
self._conf = conf
self._section = section
def __getattr__(self, name):
if self._conf.has_option(self._section, name):
value = self._conf.get(self._section, name)
if name in self.MULTIVALUE:
value = value.split()
elif name in self.MULTILINE:
value = value.splitlines()
return value
raise AttributeError, name
def maven_opts(values, chain=False, scratch=False):
"""
Convert the argument (an optparse.Values object) to a dict of build options
suitable for passing to maven-build or maven-chain.
"""
opts = {}
for key in ('scmurl', 'patches', 'specfile', 'goals', 'profiles', 'packages',
'jvm_options', 'maven_options'):
val = getattr(values, key, None)
if val:
opts[key] = val
props = {}
for prop in getattr(values, 'properties', []):
fields = prop.split('=', 1)
if len(fields) != 2:
fields.append(None)
props[fields[0]] = fields[1]
if props:
opts['properties'] = props
envs = {}
for env in getattr(values, 'envs', []):
fields = env.split('=', 1)
if len(fields) != 2:
raise ValueError, "Environment variables must be in NAME=VALUE format"
envs[fields[0]] = fields[1]
if envs:
opts['envs'] = envs
if chain:
val = getattr(values, 'buildrequires', [])
if val:
opts['buildrequires'] = val
if scratch and not chain:
opts['scratch'] = True
return opts
def maven_params(config, package, chain=False, scratch=False):
values = MavenConfigOptAdapter(config, package)
return maven_opts(values, chain=chain, scratch=scratch)
def wrapper_params(config, package, chain=False, scratch=False):
params = {}
for name, value in config.items(package):
if name == 'scmurl':
pass
elif name == 'buildrequires':
value = value.split()
if len(value) != 1:
raise ValueError, "A wrapper-rpm must depend on exactly one package"
elif name == 'type':
pass
else:
raise ValueError, "Unknown option: %s" % name
params[name] = value
values = MavenConfigOptAdapter(config, package)
params['type'] = getattr(values, 'type', None)
params['scmurl'] = getattr(values, 'scmurl', None)
params['buildrequires'] = getattr(values, 'buildrequires', [])
if not scratch:
params['create_build'] = True
return params
def parse_maven_chain(confs, scratch=False):
def parse_maven_params(confs, chain=False, scratch=False):
"""
Parse maven-chain config.
confs is a list of paths to config files.
Parse .ini files that contain parameters to launch a Maven build.
Return a map whose keys are package names and values are config parameters.
"""
@ -536,14 +552,49 @@ def parse_maven_chain(confs, scratch=False):
if config.has_option(package, 'type'):
buildtype = config.get(package, 'type')
if buildtype == 'maven':
params = _maven_params(config, package, scratch)
params = maven_params(config, package, chain=chain, scratch=scratch)
elif buildtype == 'wrapper':
params = _wrapper_params(config, package, scratch)
params = wrapper_params(config, package, chain=chain, scratch=scratch)
if len(params.get('buildrequires')) != 1:
raise ValueError, "A wrapper-rpm must depend on exactly one package"
else:
raise ValueError, "Unsupported build type: %s" % buildtype
if not 'scmurl' in params:
raise ValueError, "%s is missing the scmurl parameter" % package
builds[package] = params
if not builds:
raise ValueError, "No sections found in: %s" % ', '.join(confs)
return builds
def parse_maven_param(confs, chain=False, scratch=False, section=None):
"""
Parse .ini files that contain parameters to launch a Maven build.
Return a map that contains a single entry corresponding to the given
section of the .ini file. If the config file only contains a single
section, section does not need to be specified.
"""
if not isinstance(confs, (list, tuple)):
confs = [confs]
builds = parse_maven_params(confs, chain=chain, scratch=scratch)
if section:
if section in builds:
builds = {section: builds[section]}
else:
raise ValueError, "Section %s does not exist in: %s" % (section, ', '.join(confs))
elif len(builds) > 1:
raise ValueError, "Multiple sections in: %s, you must specify the section" % ', '.join(confs)
return builds
def parse_maven_chain(confs, scratch=False):
"""
Parse maven-chain config.
confs is a path to a config file or a list of paths to config files.
Return a map whose keys are package names and values are config parameters.
"""
builds = parse_maven_params(confs, chain=True, scratch=scratch)
depmap = {}
for package, params in builds.items():
depmap[package] = set(params.get('buildrequires', []))