Bug 1312520 - Extract the logic for combining defaults and individual section defnitions in the manifestparser to a standalone function. r=ahal draft
authorChris Manchester <cmanchester@mozilla.com>
Mon, 24 Oct 2016 19:24:05 -0700
changeset 428947 37618a19d16fc90962cdc51f247fd6137b199a93
parent 428946 0a582ed5121974a6f0d577e9bef9f8b851f25691
child 428948 07e91f2fd68a81c084f219e246544ed1f4c3c38c
push id33436
push userbmo:cmanchester@mozilla.com
push dateMon, 24 Oct 2016 20:11:53 +0000
reviewersahal
bugs1312520
milestone52.0a1
Bug 1312520 - Extract the logic for combining defaults and individual section defnitions in the manifestparser to a standalone function. r=ahal MozReview-Commit-ID: CQNFboRhsOs
testing/mozbase/manifestparser/manifestparser/expression.py
testing/mozbase/manifestparser/manifestparser/ini.py
--- a/testing/mozbase/manifestparser/manifestparser/expression.py
+++ b/testing/mozbase/manifestparser/manifestparser/expression.py
@@ -1,17 +1,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import re
 import sys
 import traceback
 
-__all__ = ['parse', 'ParseError', 'ExpressionParser']
+__all__ = ['parse', 'ParseError', 'ExpressionParser', 'combine_fields']
 
 # expr.py
 # from:
 # http://k0s.org/mozilla/hg/expressionparser
 # http://hg.mozilla.org/users/tmielczarek_mozilla.com/expressionparser
 
 # Implements a top-down parser/evaluator for simple boolean expressions.
 # ideas taken from http://effbot.org/zone/simple-top-down-parsing.htm
@@ -317,8 +317,33 @@ def parse(text, **values):
     Parse and evaluate a boolean expression.
     :param text: The expression to parse, as a string.
     :param values: A dict containing a name to value mapping for identifiers
                    referenced in *text*.
     :rtype: the final value of the expression.
     :raises: :py:exc::ParseError: will be raised if parsing fails.
     """
     return ExpressionParser(text, values).parse()
+
+
+def combine_fields(global_vars, local_vars):
+    """
+    Combine the given manifest entries according to the semantics of specific fields.
+    This is used to combine manifest level defaults with a per-test definition.
+    """
+    if not global_vars:
+        return local_vars
+    if not local_vars:
+        return global_vars
+    field_patterns = {
+        'skip-if': '(%s) || (%s)',
+        'support-files': '%s %s',
+    }
+    final_mapping = global_vars.copy()
+    for field_name, value in local_vars.items():
+        if field_name not in field_patterns or field_name not in global_vars:
+            final_mapping[field_name] = value
+            continue
+        global_value = global_vars[field_name]
+        pattern = field_patterns[field_name]
+        final_mapping[field_name] = pattern % (
+            global_value.split('#')[0], value.split('#')[0])
+    return final_mapping
--- a/testing/mozbase/manifestparser/manifestparser/ini.py
+++ b/testing/mozbase/manifestparser/manifestparser/ini.py
@@ -1,13 +1,14 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
+from .expression import combine_fields
 
 __all__ = ['read_ini']
 
 
 def read_ini(fp, variables=None, default='DEFAULT', defaults_only=False,
              comments=';#', separators=('=', ':'), strict=True,
              handle_defaults=True):
     """
@@ -107,30 +108,11 @@ def read_ini(fp, variables=None, default
         root = os.path.join(os.path.dirname(fp.name),
                             variables['server-root'])
         variables['server-root'] = os.path.abspath(root)
 
     # return the default section only if requested
     if defaults_only:
         return [(default, variables)]
 
-    # Interpret the variables in the context of inherited defaults if
-    # requested.
-    def interpret_variables(global_dict, local_dict):
-        if not handle_defaults:
-            return local_dict
-
-        variables = global_dict.copy()
-
-        # These variables are combinable when they appear both in default
-        # and per-entry.
-        for field_name, pattern in (('skip-if', '(%s) || (%s)'),
-                                    ('support-files', '%s %s')):
-            local_value, global_value = local_dict.get(field_name), variables.get(field_name)
-            if local_value and global_value:
-                local_dict[field_name] = pattern % (
-                    global_value.split('#')[0], local_value.split('#')[0])
-        variables.update(local_dict)
-
-        return variables
-
-    sections = [(i, interpret_variables(variables, j)) for i, j in sections]
+    global_vars = variables if handle_defaults else {}
+    sections = [(i, combine_fields(global_vars, j)) for i, j in sections]
     return sections