From 64447879d2f5a2fe5b8b50819b6620b759715a9d Mon Sep 17 00:00:00 2001 From: Daniel Nephin <dnephin@docker.com> Date: Tue, 17 Nov 2015 12:21:47 -0500 Subject: [PATCH] Reduce complexity of merge_service_dicts Signed-off-by: Daniel Nephin <dnephin@docker.com> --- compose/config/config.py | 75 +++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/compose/config/config.py b/compose/config/config.py index 201266208..6c5654339 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -1,5 +1,6 @@ import codecs import logging +import operator import os import sys from collections import namedtuple @@ -389,56 +390,46 @@ def merge_service_dicts_from_files(base, override): def merge_service_dicts(base, override): - d = base.copy() + d = {} - if 'environment' in base or 'environment' in override: - d['environment'] = merge_environment( - base.get('environment'), - override.get('environment'), - ) + def merge_field(field, merge_func, default=None): + if field in base or field in override: + d[field] = merge_func( + base.get(field, default), + override.get(field, default)) - path_mapping_keys = ['volumes', 'devices'] + merge_field('environment', merge_environment) + merge_field('labels', merge_labels) + merge_image_or_build(base, override, d) - for key in path_mapping_keys: - if key in base or key in override: - d[key] = merge_path_mappings( - base.get(key), - override.get(key), - ) + for field in ['volumes', 'devices']: + merge_field(field, merge_path_mappings) - if 'labels' in base or 'labels' in override: - d['labels'] = merge_labels( - base.get('labels'), - override.get('labels'), - ) + for field in ['ports', 'expose', 'external_links']: + merge_field(field, operator.add, default=[]) - if 'image' in override and 'build' in d: - del d['build'] + for field in ['dns', 'dns_search']: + merge_field(field, merge_list_or_string) - if 'build' in override and 'image' in d: - del d['image'] - - list_keys = ['ports', 'expose', 'external_links'] - - for key in list_keys: - if key in base or key in override: - d[key] = base.get(key, []) + override.get(key, []) - - list_or_string_keys = ['dns', 'dns_search'] - - for key in list_or_string_keys: - if key in base or key in override: - d[key] = to_list(base.get(key)) + to_list(override.get(key)) - - already_merged_keys = ['environment', 'labels'] + path_mapping_keys + list_keys + list_or_string_keys - - for k in set(ALLOWED_KEYS) - set(already_merged_keys): - if k in override: - d[k] = override[k] + already_merged_keys = set(d) | {'image', 'build'} + for field in set(ALLOWED_KEYS) - already_merged_keys: + if field in base or field in override: + d[field] = override.get(field, base.get(field)) return d +def merge_image_or_build(base, override, output): + if 'image' in override: + output['image'] = override['image'] + elif 'build' in override: + output['build'] = override['build'] + elif 'image' in base: + output['image'] = base['image'] + elif 'build' in base: + output['build'] = base['build'] + + def merge_environment(base, override): env = parse_environment(base) env.update(parse_environment(override)) @@ -604,6 +595,10 @@ def expand_path(working_dir, path): return os.path.abspath(os.path.join(working_dir, os.path.expanduser(path))) +def merge_list_or_string(base, override): + return to_list(base) + to_list(override) + + def to_list(value): if value is None: return []