Bug 1229241 - Support merging HierarchicalStringLists. r=gps
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 27 Nov 2015 21:47:32 +0900
changeset 308992 63bfa84f09aa6f7f510b44bc813e562e8456573e
parent 308991 7b183b8a6116a5f5d65eeccbab97ced59910ef79
child 308993 88981a083ec91e7ff8b6cd3f91b91cb9d1246240
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs1229241
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1229241 - Support merging HierarchicalStringLists. r=gps
python/mozbuild/mozbuild/frontend/reader.py
python/mozbuild/mozbuild/test/test_util.py
python/mozbuild/mozbuild/util.py
--- a/python/mozbuild/mozbuild/frontend/reader.py
+++ b/python/mozbuild/mozbuild/frontend/reader.py
@@ -31,16 +31,17 @@ import types
 from collections import (
     defaultdict,
     OrderedDict,
 )
 from io import StringIO
 
 from mozbuild.util import (
     EmptyValue,
+    HierarchicalStringList,
     memoize,
     ReadOnlyDefaultDict,
 )
 
 from mozbuild.testing import (
     TEST_MANIFESTS,
     REFTEST_FLAVORS,
     WEB_PATFORM_TESTS_FLAVORS,
@@ -410,17 +411,17 @@ class MozbuildSandbox(Sandbox):
             # This is gross, but allows the merge to happen. Eventually, the
             # merging will go away and template contexts emitted independently.
             klass = self._context.__class__
             self._context.__class__ = TemplateContext
             # The sandbox will do all the necessary checks for these merges.
             for key, value in context.items():
                 if isinstance(value, dict):
                     self[key].update(value)
-                elif isinstance(value, list):
+                elif isinstance(value, (list, HierarchicalStringList)):
                     self[key] += value
                 else:
                     self[key] = value
             self._context.__class__ = klass
 
             for p in context.all_paths:
                 self._context.add_source(p)
 
--- a/python/mozbuild/mozbuild/test/test_util.py
+++ b/python/mozbuild/mozbuild/test/test_util.py
@@ -287,16 +287,43 @@ class TestHierarchicalStringList(unittes
             ('', ['root1', 'root2', 'root3']),
             ('child1', ['child11', 'child12', 'child13']),
             ('child1/grandchild1', ['grandchild111', 'grandchild112']),
             ('child1/grandchild2', ['grandchild121', 'grandchild122']),
             ('child2/grandchild1', ['grandchild211', 'grandchild212',
                                     'grandchild213', 'grandchild214']),
         ])
 
+    def test_merge(self):
+        l1 = HierarchicalStringList()
+        l1 += ['root1', 'root2', 'root3']
+        l1.child1 += ['child11', 'child12', 'child13']
+        l1.child1.grandchild1 += ['grandchild111', 'grandchild112']
+        l1.child1.grandchild2 += ['grandchild121', 'grandchild122']
+        l1.child2.grandchild1 += ['grandchild211', 'grandchild212']
+        l1.child2.grandchild1 += ['grandchild213', 'grandchild214']
+        l2 = HierarchicalStringList()
+        l2.child1 += ['child14', 'child15']
+        l2.child1.grandchild2 += ['grandchild123']
+        l2.child3 += ['child31', 'child32']
+
+        l1 += l2
+        els = list((path, list(seq)) for path, seq in l1.walk())
+        self.assertEqual(els, [
+            ('', ['root1', 'root2', 'root3']),
+            ('child1', ['child11', 'child12', 'child13', 'child14',
+                        'child15']),
+            ('child1/grandchild1', ['grandchild111', 'grandchild112']),
+            ('child1/grandchild2', ['grandchild121', 'grandchild122',
+                                    'grandchild123']),
+            ('child2/grandchild1', ['grandchild211', 'grandchild212',
+                                    'grandchild213', 'grandchild214']),
+            ('child3', ['child31', 'child32']),
+        ])
+
 
 class TestStrictOrderingOnAppendList(unittest.TestCase):
     def test_init(self):
         l = StrictOrderingOnAppendList()
         self.assertEqual(len(l), 0)
 
         l = StrictOrderingOnAppendList(['a', 'b', 'c'])
         self.assertEqual(len(l), 3)
--- a/python/mozbuild/mozbuild/util.py
+++ b/python/mozbuild/mozbuild/util.py
@@ -549,18 +549,23 @@ class HierarchicalStringList(object):
         if name.startswith('__'):
             return object.__getattr__(self, name)
         return self._get_exportvariable(name)
 
     def __delattr__(self, name):
         raise MozbuildDeletionError('Unable to delete attributes for this object')
 
     def __iadd__(self, other):
-        self._check_list(other)
-        self._strings += other
+        if isinstance(other, HierarchicalStringList):
+            self._strings += other._strings
+            for c in other._children:
+                self[c] += other[c]
+        else:
+            self._check_list(other)
+            self._strings += other
         return self
 
     def __getitem__(self, name):
         return self._get_exportvariable(name)
 
     def __setitem__(self, name, value):
         self._set_exportvariable(name, value)