Bug 1417309 - Fix mozbuild.context.Path.join when the path was created in an included moz.build file. r?build draft
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 05 Oct 2017 14:08:54 +0900
changeset 698008 506a82a7e10298ae42774a0510cb93e7326d11d4
parent 698007 6c0c39a8bbf0712c78c36e593b5871a3aa2023c3
child 698009 d079edc94aa5014926cabf67dc210dfb423b0a03
push id89172
push userbmo:mh+mozilla@glandium.org
push dateWed, 15 Nov 2017 05:25:33 +0000
reviewersbuild
bugs1417309
milestone59.0a1
Bug 1417309 - Fix mozbuild.context.Path.join when the path was created in an included moz.build file. r?build When the directory traversal code, or the backend code operates on Path instances, the context in which they were created may have changed since the instanced have been created. And when they use Path.join, which relies on the current state of the context, they may not get the expected result if the Path was created in an included moz.build file. The result is that some variables, like DIRS, didn't work properly when they're set from an included moz.build file and use relative paths. This fixes it.
python/mozbuild/mozbuild/frontend/context.py
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -571,17 +571,27 @@ class Path(ContextDerivedValue, unicode)
         assert self.__class__ != Path
         self.context = context
         self.srcdir = context.srcdir
 
     def join(self, *p):
         """ContextDerived equivalent of mozpath.join(self, *p), returning a
         new Path instance.
         """
-        return Path(self.context, mozpath.join(self, *p))
+        # self.srcdir might be different from context.srcdir (as in,
+        # context.srcdir changed after self was created, which can happen
+        # when using include().
+        cls = self.context.__class__
+        class DummyContext(cls):
+            srcdir = self.srcdir
+        try:
+            self.context.__class__ = DummyContext
+            return Path(self.context, mozpath.join(self, *p))
+        finally:
+            self.context.__class__ = cls
 
     def __cmp__(self, other):
         if isinstance(other, Path) and self.srcdir != other.srcdir:
             return cmp(self.full_path, other.full_path)
         return cmp(unicode(self), other)
 
     # __cmp__ is not enough because unicode has __eq__, __ne__, etc. defined
     # and __cmp__ is only used for those when they don't exist.