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:
parent
df316c0c6f
commit
1e8b7211ee
2 changed files with 166 additions and 91 deletions
98
cli/koji
98
cli/koji
|
|
@ -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
|
||||
|
|
|
|||
159
koji/util.py
159
koji/util.py
|
|
@ -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', []))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue