diff --git a/giftwrap/builders/__init__.py b/giftwrap/builders/__init__.py index 5ebd7c2..a269f60 100644 --- a/giftwrap/builders/__init__.py +++ b/giftwrap/builders/__init__.py @@ -18,6 +18,8 @@ import logging import os import threading +import requests + from giftwrap.gerrit import GerritReview from stevedore.driver import DriverManager from stevedore.extension import ExtensionManager @@ -36,6 +38,7 @@ class Builder(object): self._temp_src_dir = None self._spec = spec self._thread_exit = [] + self._constraints = [] @staticmethod def builder_names(ext_mgr=None): @@ -55,6 +58,30 @@ class Builder(object): "Error was: %s", e) return [] + def _get_constraints(self): + cfiles = [] + try: + for count, constraint_url in \ + enumerate(self._spec.settings.constraints, 1): + response = requests.get(constraint_url) + + # Raise an error if we got a bad URL + response.raise_for_status() + + constraints = response.text.encode('utf-8') + cfilepath = os.path.join(self._temp_dir, + 'constraints-%s.txt' % count) + + with open(cfilepath, 'w') as cfile: + cfile.write(constraints) + + cfiles.append(cfilepath) + + return cfiles + + except Exception as e: + raise Exception("Unable to construct constraints. Error: %s" % e) + def _build_project(self, project): try: self._prepare_project_build(project) @@ -105,6 +132,9 @@ class Builder(object): self._temp_src_dir = os.path.join(self._temp_dir, 'src') LOG.debug("Temporary working directory: %s", self._temp_dir) + # get constraints paths + self._constraints = self._get_constraints() + threads = [] for project in spec.projects: if spec.settings.parallel_build: diff --git a/giftwrap/builders/docker_builder.py b/giftwrap/builders/docker_builder.py index db90711..7fc4629 100644 --- a/giftwrap/builders/docker_builder.py +++ b/giftwrap/builders/docker_builder.py @@ -84,8 +84,11 @@ class DockerBuilder(Builder): def _install_pip_dependencies(self, venv_path, dependencies): pip_path = self._get_venv_pip_path(venv_path) + install = "install" + for constraint in self._constraints: + install = "%s -c %s" % (install, constraint) for dependency in dependencies: - self._execute("%s install %s" % (pip_path, dependency)) + self._execute("%s %s %s" % (pip_path, install, dependency)) def _copy_sample_config(self, src_clone_dir, project): src_config = os.path.join(src_clone_dir, 'etc') @@ -96,7 +99,10 @@ class DockerBuilder(Builder): def _install_project(self, venv_path, src_clone_dir): pip_path = self._get_venv_pip_path(venv_path) - self._execute("%s install %s" % (pip_path, src_clone_dir)) + install = "install" + for constraint in self._constraints: + install = "%s -c %s" % (install, constraint) + self._execute("%s %s %s" % (pip_path, install, src_clone_dir)) def _finalize_project_build(self, project): self._commands.append("rm -rf %s" % self._temp_dir) diff --git a/giftwrap/builders/package_builder.py b/giftwrap/builders/package_builder.py index 12d2cf0..f482885 100644 --- a/giftwrap/builders/package_builder.py +++ b/giftwrap/builders/package_builder.py @@ -70,8 +70,11 @@ class PackageBuilder(Builder): def _install_pip_dependencies(self, venv_path, dependencies): pip_path = self._get_venv_pip_path(venv_path) + install = "install" + for constraint in self._constraints: + install = "%s -c %s" % (install, constraint) for dependency in dependencies: - self._execute("%s install %s" % (pip_path, dependency)) + self._execute("%s %s %s" % (pip_path, install, dependency)) def _copy_sample_config(self, src_clone_dir, project): src_config = os.path.join(src_clone_dir, 'etc') @@ -87,7 +90,10 @@ class PackageBuilder(Builder): def _install_project(self, venv_path, src_clone_dir): pip_path = self._get_venv_pip_path(venv_path) - self._execute("%s install %s" % (pip_path, src_clone_dir)) + install = "install" + for constraint in self._constraints: + install = "%s -c %s" % (install, constraint) + self._execute("%s %s %s" % (pip_path, install, src_clone_dir)) def _finalize_project_build(self, project): # build the package diff --git a/giftwrap/settings.py b/giftwrap/settings.py index d6962e1..d74b708 100644 --- a/giftwrap/settings.py +++ b/giftwrap/settings.py @@ -31,9 +31,11 @@ class Settings(object): package_name_format=None, version=None, base_path=None, install_path=None, gerrit_dependencies=True, force_overwrite=False, output_dir=None, include_config=True, - parallel_build=True): + parallel_build=True, constraints=[]): if not version: raise Exception("'version' is a required settings") + if not isinstance(constraints, list): + raise Exception("'constraints' is required to be a list") self.build_type = build_type self._package_name_format = package_name_format self.version = version @@ -44,6 +46,7 @@ class Settings(object): self._output_dir = output_dir self.include_config = include_config self.parallel_build = parallel_build + self.constraints = constraints @property def package_name_format(self): diff --git a/giftwrap/tests/test_settings.py b/giftwrap/tests/test_settings.py index 000b747..bd55615 100644 --- a/giftwrap/tests/test_settings.py +++ b/giftwrap/tests/test_settings.py @@ -22,7 +22,8 @@ from giftwrap import settings SAMPLE_SETTINGS = { 'package_name_format': 'my-package-name', 'version': '1.2', - 'base_path': '/basepath' + 'base_path': '/basepath', + 'constraints': ['http://example.txt'], } @@ -35,6 +36,7 @@ class TestSettings(unittest.TestCase): self.assertEquals('my-package-name', s.package_name_format) self.assertEquals('1.2', s.version) self.assertEquals('/basepath', s.base_path) + self.assertEquals('http://example.txt', s.constraints[0]) def test_factory_has_default_base_path(self): settings_dict = {'version': 'version'} @@ -48,3 +50,10 @@ class TestSettings(unittest.TestCase): with self.assertRaises(Exception): settings.Settings.factory(settings_dict) + + def test_factory_raises_when_constraints_invalid(self): + settings_dict = SAMPLE_SETTINGS + settings_dict['constraints'] = 'notalist' + + with self.assertRaises(Exception): + settings.Settings.factory(settings_dict)