diff --git a/python/mozbuild/mozbuild/test/test_util.py b/python/mozbuild/mozbuild/test/test_util.py index 3599a8cf3321..5fcfc93d0106 100644 --- a/python/mozbuild/mozbuild/test/test_util.py +++ b/python/mozbuild/mozbuild/test/test_util.py @@ -20,11 +20,13 @@ from mozunit import ( ) from mozbuild.util import ( + expand_variables, FileAvoidWrite, group_unified_files, hash_file, memoize, memoized_property, + pair, resolve_target_to_make, MozbuildDeletionError, HierarchicalStringList, @@ -720,5 +722,43 @@ class TestGroupUnifiedFiles(unittest.TestCase): self.assertEqual(mapping[1][1], sorted_files[5:10]) self.assertEqual(mapping[2][1], sorted_files[10:]) + +class TestMisc(unittest.TestCase): + def test_pair(self): + self.assertEqual( + list(pair([1, 2, 3, 4, 5, 6])), + [(1, 2), (3, 4), (5, 6)] + ) + + self.assertEqual( + list(pair([1, 2, 3, 4, 5, 6, 7])), + [(1, 2), (3, 4), (5, 6), (7, None)] + ) + + def test_expand_variables(self): + self.assertEqual( + expand_variables('$(var)', {'var': 'value'}), + 'value' + ) + + self.assertEqual( + expand_variables('$(a) and $(b)', {'a': '1', 'b': '2'}), + '1 and 2' + ) + + self.assertEqual( + expand_variables('$(a) and $(undefined)', {'a': '1', 'b': '2'}), + '1 and ' + ) + + self.assertEqual( + expand_variables('before $(string) between $(list) after', { + 'string': 'abc', + 'list': ['a', 'b', 'c'] + }), + 'before abc between a b c after' + ) + + if __name__ == '__main__': main() diff --git a/python/mozbuild/mozbuild/util.py b/python/mozbuild/mozbuild/util.py index c76ac80dbde9..e2f7dc9148d2 100644 --- a/python/mozbuild/mozbuild/util.py +++ b/python/mozbuild/mozbuild/util.py @@ -14,6 +14,7 @@ import functools import hashlib import itertools import os +import re import stat import sys import time @@ -934,3 +935,36 @@ def group_unified_files(files, unified_prefix, unified_suffix, files)): just_the_filenames = list(filter_out_dummy(unified_group)) yield '%s%d.%s' % (unified_prefix, i, unified_suffix), just_the_filenames + + +def pair(iterable): + '''Given an iterable, returns an iterable pairing its items. + + For example, + list(pair([1,2,3,4,5,6])) + returns + [(1,2), (3,4), (5,6)] + ''' + i = iter(iterable) + return itertools.izip_longest(i, i) + + +VARIABLES_RE = re.compile('\$\((\w+)\)') + + +def expand_variables(s, variables): + '''Given a string with $(var) variable references, replace those references + with the corresponding entries from the given `variables` dict. + + If a variable value is not a string, it is iterated and its items are + joined with a whitespace.''' + result = '' + for s, name in pair(VARIABLES_RE.split(s)): + result += s + value = variables.get(name) + if not value: + continue + if not isinstance(value, types.StringTypes): + value = ' '.join(value) + result += value + return result