Skip to content

Commit

Permalink
fixed inheritance not merging values
Browse files Browse the repository at this point in the history
  • Loading branch information
toumorokoshi committed Feb 2, 2015
1 parent 40500fc commit 1f66ad6
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 60 deletions.
49 changes: 26 additions & 23 deletions docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ This is all you need to run uranium. Let's run them now:

.. code-block:: yaml
$ ./uranium
installing virtualenv...
setting up uranium...
done!
[HH:MM:SS] ================
[HH:MM:SS] STARTING URANIUM
[HH:MM:SS] ================
[HH:MM:SS] installing eggs...
[HH:MM:SS] ================
[HH:MM:SS] URANIUM FINISHED
[HH:MM:SS] ================
$ ./uranium
installing virtualenv...
setting up uranium...
done!
[HH:MM:SS] ================
[HH:MM:SS] STARTING URANIUM
[HH:MM:SS] ================
[HH:MM:SS] installing eggs...
[HH:MM:SS] ================
[HH:MM:SS] URANIUM FINISHED
[HH:MM:SS] ================
And congrats, you've had your first Uranium run! Of course, all this
did was run virtualenv and install Uranium. Now let's get some real
Expand All @@ -74,18 +74,21 @@ you can add a couple new section to the uranium file:
And let's run uranium again:

$ ./uranium
setting up uranium...
done!
[HH:MM:SS] ================
[HH:MM:SS] STARTING URANIUM
[HH:MM:SS] ================
[HH:MM:SS] installing eggs...
[HH:MM:SS] WARNING: Unable to install develop egg at /tmp/uranium-tut: Directory '/tmp/uranium-tut' is not installable. File 'setup.py' not found.
[HH:MM:SS] Adding requirement nose==1.3.4...
[HH:MM:SS] ================
[HH:MM:SS] URANIUM FINISHED
[HH:MM:SS] ================

.. code-block::
$ ./uranium
setting up uranium...
done!
[HH:MM:SS] ================
[HH:MM:SS] STARTING URANIUM
[HH:MM:SS] ================
[HH:MM:SS] installing eggs...
[HH:MM:SS] WARNING: Unable to install develop egg at /tmp/uranium-tut: Directory '/tmp/uranium-tut' is not installable. File 'setup.py' not found.
[HH:MM:SS] Adding requirement nose==1.3.4...
[HH:MM:SS] ================
[HH:MM:SS] URANIUM FINISHED
[HH:MM:SS] ================
Note the:

Expand Down
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.47',
version='0.0.48',
description='a build system for python',
long_description='a build system for python',
author='Yusuke Tsutsumi',
Expand Down
4 changes: 2 additions & 2 deletions uranium/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from virtualenv import make_environment_relocatable
from .uranium import Uranium
from .virtualenv_manager import install_virtualenv
from .config import load_config_from_file
from .config import Config
import os
import sys

Expand All @@ -41,7 +41,7 @@ def main(argv=sys.argv[1:]):

def _get_uranium(uranium_file):
root = os.path.abspath(os.curdir)
config = load_config_from_file(uranium_file)
config = Config.load_from_path(uranium_file)
return Uranium(config, root)


Expand Down
79 changes: 51 additions & 28 deletions uranium/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,25 @@
INHERITANCE_KEY = "inherits"


def load_config_from_string(string):
config_dict = yaml.load(string) or {}
return Config(config_dict)


def load_config_from_file_handle(file_handle):
return load_config_from_string(file_handle.read())


def load_config_from_file(file_path):
with open(file_path) as fh:
return load_config_from_file_handle(fh)


def load_config_from_url(url):
content = requests.get(url).content
return load_config_from_string(content)


class Config(ResolveDict,
DevelopEggs, Eggs, Indexes,
Parts, Phases, Versions):
"""
The config object that store configuration.
The general though behind the implementation is to subdivide
The general thought behind the implementation is to subdivide
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)
def __init__(self, raw_values):
"""
it's not reccomended to call this constructor directly,
because it doesn't include resolving inheritance.
please use load_from_path or load_from_string instead.
"""
super(Config, self).__init__(raw_values, None)
self._resolve_values = self
self._initialize()
Expand All @@ -67,9 +52,23 @@ def validate(self):

@staticmethod
def load_from_path(path):
if path.startswith('http://'):
return load_config_from_url(path)
return load_config_from_file(path)
values = _load_values_from_path(path)
return Config._return_with_inheritance(values)

@staticmethod
def load_from_string(content):
values = _load_values_from_string(content)
return Config._return_with_inheritance(values)

@staticmethod
def load_from_dict(d):
return Config._return_with_inheritance(d)

@staticmethod
def _return_with_inheritance(raw_values):
to_dict = {}
_set_values(to_dict, raw_values)
return Config(to_dict)

def _initialize(self):
self._invoke_bases('_initialize')
Expand All @@ -93,8 +92,8 @@ def _set_values(to_dict, raw_options):
if inheritance_list:

for inherited_path in inheritance_list:
inherited_values = Config.load_from_path(inherited_path)
_recursive_merge(to_dict, inherited_values.data)
inherited_values = _load_values_from_path(inherited_path)
_set_values(to_dict, inherited_values)

_recursive_merge(to_dict, raw_options)

Expand All @@ -105,3 +104,27 @@ def _recursive_merge(to_dict, from_dict):
to_dict[key] = value
elif isinstance(to_dict[key], dict) and isinstance(value, dict):
_recursive_merge(to_dict[key], value)


def _load_values_from_path(path):
if path.startswith('http://'):
return _load_values_from_url(path)
return _load_values_from_file(path)


def _load_values_from_string(string):
return yaml.load(string) or {}


def _load_values_from_file_handle(file_handle):
return _load_values_from_string(file_handle.read())


def _load_values_from_file(file_path):
with open(file_path) as fh:
return _load_values_from_file_handle(fh)


def _load_values_from_url(url):
content = requests.get(url).content
return _load_values_from_string(content)
4 changes: 2 additions & 2 deletions uranium/tests/config/test_load.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from uranium.config import load_config_from_string
from uranium.config import Config


class TestConfigLoad(object):

def test_load_empty_string(self):
""" make sure that loading an empty string works """
load_config_from_string("")
Config.load_from_string("")
31 changes: 31 additions & 0 deletions uranium/tests/config/test_recursive_merge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from uranium.config import _recursive_merge
from nose.tools import eq_


def get_from():
return {
'phases': {
'before-eggs': ['zpv']
}
}


def get_to():
return {
'phases': {
'after-eggs': ['test']
}
}


class TestRecursiveMerge(object):

def setUp(self):
self.result = get_to()
_recursive_merge(self.result, get_from())

def test_recursive_merge(self):
eq_(self.result['phases'], {
'before-eggs': ['zpv'],
'after-eggs': ['test']
})
8 changes: 4 additions & 4 deletions uranium/tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import httpretty
import os
from uranium import config as u_config
from uranium.config import Config
from uranium.config import Part
from nose.tools import ok_, eq_

Expand All @@ -14,7 +14,7 @@ def setUp(self):
self.old_dir = os.path.abspath(os.curdir)
os.chdir(TEST_DIR)
uranium_file = os.path.join(TEST_DIR, 'uranium.yaml')
self.config = u_config.load_config_from_file(uranium_file)
self.config = Config.load_from_path(uranium_file)

def test_inheritance(self):
"""
Expand Down Expand Up @@ -46,7 +46,7 @@ def test_inheritance_web():
- "http://example.com/base.yaml"
"""

config = u_config.load_config_from_string(INHERITS_YAML)
config = Config.load_from_string(INHERITS_YAML)
eq_(config.get("index"), "http://localpypi.local",
"index should have been loaded from base found online")

Expand All @@ -64,6 +64,6 @@ def test_get_part():
}
}
}
config = u_config.Config(config_dict)
config = Config(config_dict)
part = config.get_part('test')
eq_(part, Part('test', config_dict['parts']['test']))

0 comments on commit 1f66ad6

Please sign in to comment.