From 1bf38c5cfbe70194599ae2ca4cc4f57c6572e6da Mon Sep 17 00:00:00 2001 From: Tim Cuthbertson Date: Mon, 19 May 2014 20:13:57 +1000 Subject: [PATCH] Add compile:pin-components attribute to version tag of implementation template --- build.py | 23 ++++++++++++++++++ tests/pinned-version/main.py | 4 ++++ tests/pinned-version/pinned-version.xml | 25 ++++++++++++++++++++ tests/testcompile.py | 42 +++++++++++++++++++++++++++++---- 4 files changed, 89 insertions(+), 5 deletions(-) create mode 100755 tests/pinned-version/main.py create mode 100644 tests/pinned-version/pinned-version.xml diff --git a/build.py b/build.py index ef584f1..4c1d10d 100644 --- a/build.py +++ b/build.py @@ -7,6 +7,7 @@ from logging import info, warn from xml.dom import minidom, XMLNS_NAMESPACE from optparse import OptionParser import tempfile +import itertools from zeroinstall import SafeException from zeroinstall.injector import model, namespaces, run @@ -497,6 +498,28 @@ def write_sample_feed(buildenv, master_feed, src_impl): if impl_template.content: impl_elem.appendChild(doc.createTextNode(impl_template.content)) + for version_elem in itertools.chain( + impl_elem.getElementsByTagName('version'), + ): + pin_components = version_elem.getAttributeNS(XMLNS_0COMPILE, "pin-components") + if pin_components: + pin_components = int(pin_components) + iface = version_elem.parentNode.getAttribute("interface") + assert iface + dep_impl = buildenv.chosen_impl(iface) + impl_version = model.parse_version(dep_impl.attrs.get('version')) + + pinned_components = [impl_version[0][:pin_components]] + # (for -pre versions) + min_version = min(pinned_components, impl_version) + + # clone and increment + max_version = [pinned_components[0][:]] + max_version[0][-1] += 1 + + version_elem.setAttribute("not-before", model.format_version(min_version)) + version_elem.setAttribute("before", model.format_version(max_version)) + if set_arch: group.setAttributeNS(None, 'arch', buildenv.target_arch) diff --git a/tests/pinned-version/main.py b/tests/pinned-version/main.py new file mode 100755 index 0000000..019b902 --- /dev/null +++ b/tests/pinned-version/main.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from __future__ import print_function +import sys +print('.'.join(map(str, sys.version_info[:2]))) diff --git a/tests/pinned-version/pinned-version.xml b/tests/pinned-version/pinned-version.xml new file mode 100644 index 0000000..8a2e50e --- /dev/null +++ b/tests/pinned-version/pinned-version.xml @@ -0,0 +1,25 @@ + + + + pinned-version + testing + + Test compiling a program with a pinned dependency. + + + + + + + + + + + + + + + + + + diff --git a/tests/testcompile.py b/tests/testcompile.py index 653c5b7..2896756 100755 --- a/tests/testcompile.py +++ b/tests/testcompile.py @@ -21,6 +21,7 @@ local_bad_version = os.path.join(mydir, 'bad-version.xml') local_hello_path = os.path.join(mydir, 'hello2', 'hello2.xml') local_cprog_command_path = os.path.join(mydir, 'cprog', 'cprog-command.xml') local_cprog_path = os.path.join(mydir, 'cprog', 'cprog.xml') +local_pinned_path = os.path.join(mydir, 'pinned-version', 'pinned-version.xml') top_build_deps = os.path.join(mydir, 'top-build-deps.xml') compile_bin = os.path.join(mydir, '0compile-coverage') @@ -48,11 +49,12 @@ def run(*args, **kwargs): raise Exception("Exit status %d:\n%s" % (code, got)) expected = kwargs.get('expect', '') - if expected: - if expected.lower() not in got.lower(): - raise Exception("Expected '%s', got '%s'" % (expected, got)) - elif got: - raise Exception("Expected nothing, got '%s'" % got) + if expected is not None: # pass None to explicily suppress check + if expected: + if expected.lower() not in got.lower(): + raise Exception("Expected '%s', got '%s'" % (expected, got)) + elif got: + raise Exception("Expected nothing, got '%s'" % got) # Detect accidental network access os.environ['http_proxy'] = 'localhost:1111' @@ -248,6 +250,36 @@ class TestCompile(unittest.TestCase): def testBuildDeps(self): compile('autocompile', top_build_deps, expect = "build-deps.xml 0.1 requires 3 <= version < 3", expect_status = 1) + def testPinVersions(self): + dest = os.path.join(self.tmpdir, 'pinned_version') + compile('setup', local_pinned_path, dest, expect = 'Created directory') + os.chdir(dest) + compile('build', expect=None) + env = support.BuildEnv() + python_version = subprocess.check_output(launch_command + [env.local_iface_file]).strip() + major, minor = map(int, python_version.split(".")) + version_limit = "%d.%d" % (major, minor+1) + + def check_feed(path): + ''' + Check that the feed has the restriction: + + ''' + from xml.dom import minidom + with open(path) as f: + dom = minidom.parse(f) + version_tags = dom.documentElement.getElementsByTagName('version') + assert len(version_tags) == 1, version_tags + version_tag = version_tags[0] + + self.assertEquals(version_tag.getAttribute("not-before"), python_version) + self.assertEquals(version_tag.getAttribute("before"), version_limit) + + check_feed(env.local_iface_file) + + compile('publish', 'http://localhost/downloads', expect=None) + check_feed('pinned-version-0.1.xml') + suite = unittest.makeSuite(TestCompile) if __name__ == '__main__': unittest.main() -- 2.11.4.GIT