From 8a6061bfb9a3e4a98c11ad385eee45710af81e3f Mon Sep 17 00:00:00 2001 From: Mazz Mosley Date: Fri, 21 Aug 2015 17:07:37 +0100 Subject: [PATCH] __init__ takes service name and dict Moving service name and dict out of the function make_service_dict and into __init__. We always call make_service_dict with those so let's put them in the initialiser. Slightly cleaner design intent. The whole purpose of the ServiceLoader is to take a service name&service dictionary then validate, process and return service dictionaries ready to be created. This is also another step towards cleaning the code up so we can interpolate and validate an extended dictionary. Signed-off-by: Mazz Mosley --- compose/config/config.py | 42 +++++++++++++++++++--------------- tests/integration/testcases.py | 2 +- tests/unit/config_test.py | 6 ++++- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/compose/config/config.py b/compose/config/config.py index b7697f002..9d90bd614 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -142,8 +142,12 @@ def load(config_details): service_dicts = [] for service_name, service_dict in list(processed_config.items()): - loader = ServiceLoader(working_dir=working_dir, filename=filename) - service_dict = loader.make_service_dict(service_name, service_dict) + loader = ServiceLoader( + working_dir=working_dir, + filename=filename, + service_name=service_name, + service_dict=service_dict) + service_dict = loader.make_service_dict() validate_paths(service_dict) service_dicts.append(service_dict) @@ -151,7 +155,7 @@ def load(config_details): class ServiceLoader(object): - def __init__(self, working_dir, filename, already_seen=None): + def __init__(self, working_dir, filename, service_name, service_dict, already_seen=None): if working_dir is None: raise Exception("No working_dir passed to ServiceLoader()") @@ -162,17 +166,19 @@ class ServiceLoader(object): else: self.filename = filename self.already_seen = already_seen or [] + self.service_dict = service_dict.copy() + self.service_dict['name'] = service_name def detect_cycle(self, name): if self.signature(name) in self.already_seen: raise CircularReference(self.already_seen + [self.signature(name)]) - def make_service_dict(self, name, service_dict): - service_dict = service_dict.copy() - service_dict['name'] = name - service_dict = resolve_environment(service_dict, working_dir=self.working_dir) - service_dict = self.resolve_extends(service_dict) - return process_container_options(service_dict, working_dir=self.working_dir) + def make_service_dict(self): + # service_dict = service_dict.copy() + # service_dict['name'] = name + self.service_dict = resolve_environment(self.service_dict, working_dir=self.working_dir) + self.service_dict = self.resolve_extends(self.service_dict) + return process_container_options(self.service_dict, working_dir=self.working_dir) def resolve_extends(self, service_dict): if 'extends' not in service_dict: @@ -188,11 +194,6 @@ class ServiceLoader(object): other_working_dir = os.path.dirname(other_config_path) other_already_seen = self.already_seen + [self.signature(service_dict['name'])] - other_loader = ServiceLoader( - working_dir=other_working_dir, - filename=other_config_path, - already_seen=other_already_seen, - ) base_service = extends_options['service'] other_config = load_yaml(other_config_path) @@ -204,11 +205,16 @@ class ServiceLoader(object): raise ConfigurationError(msg) other_service_dict = other_config[base_service] - other_loader.detect_cycle(extends_options['service']) - other_service_dict = other_loader.make_service_dict( - service_dict['name'], - other_service_dict, + other_loader = ServiceLoader( + working_dir=other_working_dir, + filename=other_config_path, + service_name=service_dict['name'], + service_dict=other_service_dict, + already_seen=other_already_seen, ) + + other_loader.detect_cycle(extends_options['service']) + other_service_dict = other_loader.make_service_dict() validate_extended_service_dict( other_service_dict, filename=other_config_path, diff --git a/tests/integration/testcases.py b/tests/integration/testcases.py index d9d666d27..58240d5ea 100644 --- a/tests/integration/testcases.py +++ b/tests/integration/testcases.py @@ -31,7 +31,7 @@ class DockerClientTestCase(unittest.TestCase): if 'command' not in kwargs: kwargs['command'] = ["top"] - options = ServiceLoader(working_dir='.', filename=None).make_service_dict(name, kwargs) + options = ServiceLoader(working_dir='.', filename=None, service_name=name, service_dict=kwargs).make_service_dict() labels = options.setdefault('labels', {}) labels['com.docker.compose.test-name'] = self.id() diff --git a/tests/unit/config_test.py b/tests/unit/config_test.py index aa10982b4..f3a4bd306 100644 --- a/tests/unit/config_test.py +++ b/tests/unit/config_test.py @@ -15,7 +15,11 @@ def make_service_dict(name, service_dict, working_dir, filename=None): """ Test helper function to construct a ServiceLoader """ - return config.ServiceLoader(working_dir=working_dir, filename=filename).make_service_dict(name, service_dict) + return config.ServiceLoader( + working_dir=working_dir, + filename=filename, + service_name=name, + service_dict=service_dict).make_service_dict() def service_sort(services):