Skip to content

Commit

Permalink
added version resolver that updates as version dictionary is updated
Browse files Browse the repository at this point in the history
  • Loading branch information
toumorokoshi committed Jan 29, 2015
1 parent 257b931 commit 6f81411
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 19 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
]

setup(name='uranium',
version='0.0.40',
version='0.0.45',
description='a build system for python',
long_description='a build system for python',
author='Yusuke Tsutsumi',
Expand Down
9 changes: 3 additions & 6 deletions uranium/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .phases import Phases
from .versions import Versions
from .resolve_dict import ResolveDict
from .version_resolver import VersionResolver

INHERITANCE_KEY = "inherits"

Expand Down Expand Up @@ -42,13 +43,15 @@ class Config(ResolveDict,
functionality regarding specific subattributes of the config to
mixins.
"""
_resolved_versions = None

def __init__(self, raw_options):
raw_values = {}
_set_values(raw_values, raw_options)
super(Config, self).__init__(raw_values, None)
self._resolve_values = self
self._initialize()
self.resolved_versions = VersionResolver(self.eggs, self.versions)

def get_part(self, part_name):
return Part(part_name, self.parts[part_name])
Expand All @@ -62,12 +65,6 @@ def validate(self):
self._invoke_bases('_validate', warnings, errors)
return warnings, errors

@property
def resolved_versions(self):
versions = copy.copy(self.versions)
versions.update(self.eggs)
return versions

@staticmethod
def load_from_path(path):
if path.startswith('http://'):
Expand Down
35 changes: 35 additions & 0 deletions uranium/config/version_resolver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from collections import Mapping


class VersionResolver(Mapping):

def __init__(self, *dicts):
self._dicts = dicts

def __getitem__(self, key):
for d in self._dicts:
if key in d and d.get(key):
return d[key]
raise KeyError()

def __iter__(self):
keys = set()
for d in self._dicts:
keys.update(set(d.keys()))
return iter(keys)

def __len__(self):
return len(self.__iter__())

def __eq__(self, other):
self_keys = set(self.keys())
other_keys = set(other.keys())

if self_keys ^ other_keys:
return False

for k in self_keys:
if self[k] != other[k]:
return False

return True
18 changes: 15 additions & 3 deletions uranium/pip_manager/req_set.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pip.req import RequirementSet
from collections import Callable


class UraniumRequirementSet(RequirementSet):
Expand All @@ -7,9 +8,6 @@ class UraniumRequirementSet(RequirementSet):
to hook in version pinning from a spec
"""

# we have uranium in the name to ensure no conflicts
uranium_versions = {}

def add_requirement(self, install_req):
if not install_req.editable:
self._uranium_rectify_versions(install_req)
Expand All @@ -24,3 +22,17 @@ def _uranium_rectify_versions(self, install_req):
# because the & operator accepts string
if new_spec:
install_req.req.specifier = old_specifier & new_spec

@property
def uranium_versions(self):
if hasattr(self, '_uranium_versions'):
if isinstance(self._uranium_versions, Callable):
return self._uranium_versions()
else:
return self._uranium_versions
else:
return {}

@uranium_versions.setter
def uranium_versions(self, val):
self._uranium_versions = val
25 changes: 17 additions & 8 deletions uranium/tests/config/test_resolved_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from uranium.tests.utils import get_valid_config
from uranium.config.eggs import KEY as EGGS_KEY
from uranium.config.versions import KEY as VERSIONS_KEY
from nose.tools import eq_
from nose.tools import eq_, ok_


class TestRelovedVersions(object):
Expand All @@ -13,16 +13,25 @@ def setUp(self):
self.config = Config(config)

def test_egg_overrides_versions(self):
self.config[VERSIONS_KEY] = {
self.config[VERSIONS_KEY].update({
'sprinter': '>=1.0.0',
'requests': '>=2.3.0'
}
'requests': '>=2.3.0',
'mock': '==1.0.0',
})

self.config[EGGS_KEY] = {
'sprinter': '>=1.1.1'
}
self.config[EGGS_KEY].update({
'sprinter': '>=1.1.1',
'mock': None
})

eq_(self.config.resolved_versions, {
'sprinter': '>=1.1.1',
'requests': '>=2.3.0'
'requests': '>=2.3.0',
'mock': '==1.0.0'
})

def test_resolved_version_reflects_changes(self):
eq_(self.config.resolved_versions, {})
self.config[EGGS_KEY].update({'sprinter': '>=1.1.1'})
eq_(self.config.resolved_versions,
{'sprinter': '>=1.1.1'})
4 changes: 3 additions & 1 deletion uranium/uranium.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ def __init__(self, config, root):
self._config = config

self._pip = PipManager(index_urls=self._config.indexes,
versions=self.config.resolved_versions)
# this is a lambda to ensure we always
# pick up a newly resolved version
versions=lambda: self.config.resolved_versions)
self._classloader = ClassLoader(self._pip)

self._buildout = BuildoutAdapter(self, self._classloader)
Expand Down

0 comments on commit 6f81411

Please sign in to comment.