Add ability to extend builders via builder drivers

There are times where you may want to extend or modify the way that
giftwrap builds packages. Short of submitting a pull request or
(worse) forking the repository, there was no easy way to do so.

This change introduces builder drivers with stevedore. By merely adding
entry points in the 'giftwrap.builder.drivers', additional
implementations are now possible.
This commit is contained in:
Craig Tracey 2015-11-03 21:43:34 -05:00
parent 931ce3f12c
commit f2d79a0db9
6 changed files with 59 additions and 5 deletions

3
CHANGELOG.md Normal file
View File

@ -0,0 +1,3 @@
2.1.0
-----
- feature: add builder drivers using stevedore

View File

@ -19,9 +19,12 @@ import os
import threading
from giftwrap.gerrit import GerritReview
from stevedore.driver import DriverManager
from stevedore.extension import ExtensionManager
from abc import abstractmethod, ABCMeta
BUILDER_DRIVER_NAMESPACE = 'giftwrap.builder.drivers'
LOG = logging.getLogger(__name__)
@ -34,6 +37,12 @@ class Builder(object):
self._spec = spec
self._thread_exit = []
@staticmethod
def builder_names(ext_mgr=None):
if not ext_mgr:
ext_mgr = ExtensionManager(BUILDER_DRIVER_NAMESPACE)
return ext_mgr.names()
def _get_venv_pip_path(self, venv_path):
return os.path.join(venv_path, 'bin/pip')
@ -182,5 +191,8 @@ class BuilderFactory:
@staticmethod
def create_builder(builder_type, build_spec):
targetclass = "%sBuilder" % builder_type.capitalize()
return globals()[targetclass](build_spec)
driver_mgr = DriverManager(namespace=BUILDER_DRIVER_NAMESPACE,
name=builder_type,
invoke_args=(build_spec,),
invoke_on_load=True)
return driver_mgr.driver

View File

@ -19,7 +19,7 @@ import logging
import signal
import sys
from giftwrap.builders import BuilderFactory
from giftwrap.builders import Builder, BuilderFactory
from giftwrap.build_spec import BuildSpec
from giftwrap.color import ColorStreamHandler
@ -80,7 +80,7 @@ def main():
description='build giftwrap packages')
build_subcmd.add_argument('-m', '--manifest', required=True)
build_subcmd.add_argument('-v', '--version')
build_subcmd.add_argument('-t', '--type', choices=('docker', 'package'),
build_subcmd.add_argument('-t', '--type', choices=Builder.builder_names(),
required=True)
build_subcmd.add_argument('-s', '--synchronous', dest='parallel',
action='store_false')

View File

@ -0,0 +1,34 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2015, Craig Tracey
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import unittest2 as unittest
from giftwrap.builders import Builder, BUILDER_DRIVER_NAMESPACE
from stevedore import extension
class TestBuilder(unittest.TestCase):
def test_default_drivers(self):
drivers = Builder.builder_names()
self.assertEqual(drivers, ['docker', 'package'])
def test_additional_drivers(self):
em = extension.ExtensionManager(BUILDER_DRIVER_NAMESPACE)
em.extensions.append(extension.Extension('test', None, None, None))
drivers = Builder.builder_names(em)
self.assertEqual(drivers, ['docker', 'package', 'test'])

View File

@ -9,3 +9,4 @@ requests
pygerrit
docker-py
virtualenv
stevedore

View File

@ -1,6 +1,6 @@
[metadata]
name = giftwrap
version = 2.0.0
version = 2.1.0
summary = giftwrap - A tool to build full-stack native system packages.
description-file =
README.md
@ -23,6 +23,10 @@ setup-hooks =
console_scripts =
giftwrap = giftwrap.shell:main
giftwrap.builder.drivers =
package = giftwrap.builders.package_builder:PackageBuilder
docker = giftwrap.builders.docker_builder:DockerBuilder
[files]
packages =
giftwrap