diff --git a/rel-eng/releasers.conf b/rel-eng/releasers.conf index 4772987..52594b1 100644 --- a/rel-eng/releasers.conf +++ b/rel-eng/releasers.conf @@ -1,19 +1,19 @@ [yum-f15-x86_64] +releaser = tito.release.YumRepoReleaser builder = tito.builder.MockBuilder builder.mock = fedora-15-x86_64 -releaser = tito.release.YumRepoMockReleaser rsync = fedorapeople.org:/srv/repos/candlepin/subscription-manager/fedora-15/x86_64/ [yum-f16-x86_64] +releaser = tito.release.YumRepoReleaser builder = tito.builder.MockBuilder builder.mock = fedora-16-x86_64 -releaser = tito.release.YumRepoMockReleaser rsync = fedorapeople.org:/srv/repos/candlepin/subscription-manager/fedora-16/x86_64/ [yum-el6-x86_64] +releaser = tito.release.YumRepoReleaser builder = tito.builder.MockBuilder builder.mock = epel-6-x86_64 -releaser = tito.release.YumRepoMockReleaser rsync = fedorapeople.org:/srv/repos/candlepin/subscription-manager/epel-6/x86_64/ diff --git a/src/tito/builder.py b/src/tito/builder.py index 78a472d..a605ddf 100644 --- a/src/tito/builder.py +++ b/src/tito/builder.py @@ -23,6 +23,7 @@ from distutils.version import LooseVersion as loose_version from tito.common import * from tito.release import * +from tito.exception import TitoException class Builder(object): """ @@ -32,6 +33,7 @@ class Builder(object): which require other unusual behavior can subclass this to inject the desired behavior. """ + REQUIRED_ARGS = [] def __init__(self, name=None, version=None, tag=None, build_dir=None, pkg_config=None, global_config=None, user_config=None, @@ -155,6 +157,13 @@ class Builder(object): # Set to path to srpm once we build one. self.srpm_location = None + self._check_required_args() + + def _check_required_args(self): + for arg in self.REQUIRED_ARGS: + if arg not in self.args: + raise TitoException("Builder missing required argument: %s" % + arg) def run(self, options): """ @@ -806,6 +815,7 @@ class MockBuilder(Builder): Uses the mock tool to create a chroot for building packages for a different OS version than you may be currently using. """ + REQUIRED_ARGS = ['mock'] def __init__(self, name=None, version=None, tag=None, build_dir=None, pkg_config=None, global_config=None, user_config=None, diff --git a/src/tito/cli.py b/src/tito/cli.py index f67be92..4890bcf 100644 --- a/src/tito/cli.py +++ b/src/tito/cli.py @@ -329,6 +329,15 @@ class BuildModule(BaseCliModule): self.parser.add_option("--release", dest="release", action="store_true", help="DEPRECATED: please use 'tito release' instead.") + self.parser.add_option("--builder", dest="builder", + help="Override the normal builder by specifying a full class " + "path or one of the pre-configured shortcuts.") + + self.parser.add_option("--builder-arg", dest="builder_args", + action="append", + help="Custom arguments specific to a particular builder." + " (key=value)") + self.parser.add_option("--list-tags", dest="list_tags", action="store_true", help="List tags for which we build this package", @@ -372,12 +381,12 @@ class BuildModule(BaseCliModule): self.pkg_config = self._read_project_config(package_name, build_dir, self.options.tag, self.options.no_cleanup) - # TODO: - args = {} + args = self._parse_builder_args() builder = create_builder(package_name, build_tag, build_version, self.options, self.pkg_config, - build_dir, self.global_config, self.user_config, args) + build_dir, self.global_config, self.user_config, args, + builder_class=self.options.builder) return builder.run(self.options) def _validate_options(self): @@ -386,6 +395,30 @@ class BuildModule(BaseCliModule): if self.options.test and self.options.tag: error_out("Cannot build test version of specific tag.") + def _parse_builder_args(self): + """ + Builder args are sometimes needed for builders that require runtime + data. + + On the CLI this is specified with multiple uses of: + + --builder-arg key=value + + This method parses any --builder-arg's given and splits the key/value + pairs out into a dict. + """ + args = {} + if self.options.builder_args is None: + return args + + try: + for pair in self.options.builder_args: + key,value = pair.split("=") + args[key] = value + except ValueError: + error_out("Error parsing a --builder-arg, be sure to use key=value") + return args + class ReleaseModule(BaseCliModule): diff --git a/src/tito/common.py b/src/tito/common.py index 831cd3b..0a9f277 100644 --- a/src/tito/common.py +++ b/src/tito/common.py @@ -24,6 +24,15 @@ DEFAULT_BUILDER = "default_builder" DEFAULT_TAGGER = "default_tagger" GLOBALCONFIG_SECTION = "globalconfig" + +# Define some shortcuts to fully qualified Builder classes to make things +# a little more concise for CLI users. Mock is probably the only one this +# is relevant for at this time. +BUILDER_SHORTCUTS = { + 'mock': 'tito.builder.MockBuilder' +} + + def extract_bzs(output): """ Parses the output of CVS diff or a series of git commit log entries, @@ -90,6 +99,10 @@ def create_builder(package_name, build_tag, build_version, options, used by other objects without actually having run() called. """ + # Allow some shorter names for builders for CLI users. + if builder_class in BUILDER_SHORTCUTS: + builder_class = BUILDER_SHORTCUTS[builder_class] + if builder_class is None: if pkg_config.has_option("buildconfig", "builder"): builder_class = get_class_by_name(pkg_config.get("buildconfig", diff --git a/src/tito/release.py b/src/tito/release.py index 0b46b88..1807073 100644 --- a/src/tito/release.py +++ b/src/tito/release.py @@ -190,7 +190,7 @@ class Releaser(object): return new_files, copied_files, old_files -class YumRepoMockReleaser(Releaser): +class YumRepoReleaser(Releaser): """ A releaser which will rsync down a yum repo, build the desired packages, plug them in, update the repodata, and push the yum repo back out.