Bug 1256608 - Hook `open` as seen from moz.configure to add read files to configure's dependencies. draft
authorChris Manchester <cmanchester@mozilla.com>
Wed, 25 Oct 2017 16:17:01 -0700
changeset 686568 603db9fb9605dbb6da3ee96fc732872b74fed695
parent 686540 64bab5cbb9b63808d04babfbcfba3175fd99f69d
child 686569 913ea3a0dac318ab35c558c8082ca55d63c25d19
push id86213
push userbmo:cmanchester@mozilla.com
push dateThu, 26 Oct 2017 01:21:21 +0000
bugs1256608
milestone58.0a1
Bug 1256608 - Hook `open` as seen from moz.configure to add read files to configure's dependencies. MozReview-Commit-ID: 7MC51ma2dXP
moz.configure
python/mozbuild/mozbuild/configure/__init__.py
--- a/moz.configure
+++ b/moz.configure
@@ -518,14 +518,15 @@ def nsis_flags(host):
 
 set_config('MAKENSISU_FLAGS', nsis_flags)
 
 check_prog('7Z', ('7z', '7za'), allow_missing=True, when=target_is_windows)
 
 # Fallthrough to autoconf-based configure
 include('build/moz.configure/old.configure')
 
+@dependable
 @imports('__sandbox__')
 def all_paths():
-    return __sandbox__._all_paths
+    return __sandbox__._all_paths | __sandbox__._read_paths
 
-set_config('ALL_CONFIGURE_PATHS', all_paths())
+set_config('ALL_CONFIGURE_PATHS', all_paths)
 # Please do not add anything after setting ALL_CONFIGURE_PATHS.
--- a/python/mozbuild/mozbuild/configure/__init__.py
+++ b/python/mozbuild/mozbuild/configure/__init__.py
@@ -266,16 +266,17 @@ class ConfigureSandbox(dict):
     }))
 
     def __init__(self, config, environ=os.environ, argv=sys.argv,
                  stdout=sys.stdout, stderr=sys.stderr, logger=None):
         dict.__setitem__(self, '__builtins__', self.BUILTINS)
 
         self._paths = []
         self._all_paths = set()
+        self._read_paths = set()
         self._templates = set()
         # Associate SandboxDependsFunctions to DependsFunctions.
         self._depends = OrderedDict()
         self._seen = set()
         # Store the @imports added to a given function.
         self._imports = {}
 
         self._options = OrderedDict()
@@ -793,26 +794,36 @@ class ConfigureSandbox(dict):
         for _from, _import, _as in self._imports.get(func, ()):
             _from = '%s.' % _from if _from else ''
             if _as:
                 glob[_as] = self._get_one_import('%s%s' % (_from, _import))
             else:
                 what = _import.split('.')[0]
                 glob[what] = self._get_one_import('%s%s' % (_from, what))
 
+    def _sandbox_open(self):
+        # "open" made available to moz.configure so we can add opened files
+        # as dependencies for re-running configure.
+        def _open(*args, **kwargs):
+            rv = open(*args, **kwargs)
+            if len(args) == 1 or 'r' in args[1]:
+                self._read_paths.add(mozpath.abspath(args[0]))
+            return rv
+        return _open
+
     def _get_one_import(self, what):
         # The special `__sandbox__` module gives access to the sandbox
         # instance.
         if what == '__sandbox__':
             return self
         # Special case for the open() builtin, because otherwise, using it
         # fails with "IOError: file() constructor not accessible in
         # restricted mode"
         if what == '__builtin__.open':
-            return lambda *args, **kwargs: open(*args, **kwargs)
+            return self._sandbox_open()
         # Until this proves to be a performance problem, just construct an
         # import statement and execute it.
         import_line = ''
         if '.' in what:
             _from, what = what.rsplit('.', 1)
             import_line += 'from %s ' % _from
         import_line += 'import %s as imported' % what
         glob = {}