Bug 863091 - Make auto clobbering opt-in rather than opt-out; r=glandium
authorEd Morley <emorley@mozilla.com>
Thu, 25 Apr 2013 13:41:17 +0100
changeset 140807 b49b5f42be79bf9290a0beca397e4ec7fbe054f4
parent 140806 5696aa5b935410e65c61b0d15d4a25be99ae8c6b
child 140808 ba934ac9fc6bdb2e91882600ab2d2088cbdf096b
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersglandium
bugs863091
milestone23.0a1
Bug 863091 - Make auto clobbering opt-in rather than opt-out; r=glandium To avoid surprises for devs building locally, auto clobbering is now opt-in, via the use of |mk_add_options AUTOCLOBBER=1| in the mozconfig. Our automation uses build/mozconfig.common which specifies this, so auto clobber will remain enabled for our buildbot machines.
build/mozconfig.common
client.mk
python/mozbuild/mozbuild/controller/clobber.py
python/mozbuild/mozbuild/test/controller/test_clobber.py
--- a/build/mozconfig.common
+++ b/build/mozconfig.common
@@ -4,8 +4,10 @@
 
 # Common mozconfig for all users
 #
 # Add options to this file that will be inherited by all in-tree mozconfigs.
 # This is useful for eg try builds with nondefault options that apply to all
 # architectures, though note that if you want to override options set in
 # another mozconfig file, you'll need to use mozconfig.common.override instead
 # of this file.
+
+mk_add_options AUTOCLOBBER=1
--- a/client.mk
+++ b/client.mk
@@ -103,18 +103,18 @@ define CR
 
 endef
 
 # As $(shell) doesn't preserve newlines, use sed to replace them with an
 # unlikely sequence (||), which is then replaced back to newlines by make
 # before evaluation.
 $(eval $(subst ||,$(CR),$(shell _PYMAKE=$(.PYMAKE) $(TOPSRCDIR)/$(MOZCONFIG_LOADER) $(TOPSRCDIR) 2> $(TOPSRCDIR)/.mozconfig.out | sed 's/$$/||/')))
 
-ifdef NO_AUTOCLOBBER
-export NO_AUTOCLOBBER=1
+ifdef AUTOCLOBBER
+export AUTOCLOBBER=1
 endif
 
 # Automatically add -jN to make flags if not defined. N defaults to number of cores.
 ifeq (,$(findstring -j,$(MOZ_MAKE_FLAGS)))
   cores=$(shell $(PYTHON) -c 'import multiprocessing; print(multiprocessing.cpu_count())')
   MOZ_MAKE_FLAGS += -j$(cores)
 endif
 
--- a/python/mozbuild/mozbuild/controller/clobber.py
+++ b/python/mozbuild/mozbuild/controller/clobber.py
@@ -92,17 +92,17 @@ class Clobberer(object):
         if not os.path.exists(self.topobjdir):
             os.makedirs(self.topobjdir)
 
         if not os.path.exists(self.obj_clobber):
             # Simply touch the file.
             with open(self.obj_clobber, 'a'):
                 pass
 
-    def maybe_do_clobber(self, cwd, allow_auto=True, fh=sys.stderr):
+    def maybe_do_clobber(self, cwd, allow_auto=False, fh=sys.stderr):
         """Perform a clobber if it is required. Maybe.
 
         This is the API the build system invokes to determine if a clobber
         is needed and to automatically perform that clobber if we can.
 
         This returns a tuple of (bool, bool, str). The elements are:
 
           - Whether a clobber was/is required.
@@ -115,25 +115,25 @@ class Clobberer(object):
         cwd = os.path.normpath(cwd)
 
         if not self.clobber_needed():
             print('Clobber not needed.', file=fh)
             self.ensure_objdir_state()
             return False, False, None
 
         # So a clobber is needed. We only perform a clobber if we are
-        # allowed to perform an automatic clobber (the default) and if the
+        # allowed to perform an automatic clobber (off by default) and if the
         # current directory is not under the object directory. The latter is
         # because operating systems, filesystems, and shell can throw fits
         # if the current working directory is deleted from under you. While it
         # can work in some scenarios, we take the conservative approach and
         # never try.
         if not allow_auto:
-            return True, False, self._message(
-                'Automatic clobbering has been disabled.')
+            return True, False, self._message('Automatic clobbering is not '
+                'enabled (add "mk_add_options AUTOCLOBBER=1" to your mozconfig).')
 
         if cwd.startswith(self.topobjdir) and cwd != self.topobjdir:
             return True, False, self._message(
                 'Cannot clobber while the shell is inside the object directory.')
 
         print('Automatically clobbering %s' % self.topobjdir, file=fh)
         try:
             if cwd == self.topobjdir:
@@ -170,17 +170,17 @@ def main(args, env, cwd, fh=sys.stderr):
     topsrcdir, topobjdir = args
 
     if not os.path.isabs(topsrcdir):
         topsrcdir = os.path.abspath(topsrcdir)
 
     if not os.path.isabs(topobjdir):
         topobjdir = os.path.abspath(topobjdir)
 
-    auto = False if env.get('NO_AUTOCLOBBER', False) else True
+    auto = True if env.get('AUTOCLOBBER', False) else False
     clobber = Clobberer(topsrcdir, topobjdir)
     required, performed, message = clobber.maybe_do_clobber(cwd, auto, fh)
 
     if not required or performed:
         return 0
 
     print(message, file=fh)
     return 1
--- a/python/mozbuild/mozbuild/test/controller/test_clobber.py
+++ b/python/mozbuild/mozbuild/test/controller/test_clobber.py
@@ -47,45 +47,45 @@ class TestClobberer(unittest.TestCase):
 
         tmp = os.path.join(self.get_tempdir(), 'topobjdir')
         self.assertFalse(os.path.exists(tmp))
 
         c = Clobberer(self.get_topsrcdir(), tmp)
         self.assertFalse(c.clobber_needed())
 
         # Side-effect is topobjdir is created with CLOBBER file touched.
-        required, performed, reason = c.maybe_do_clobber(os.getcwd())
+        required, performed, reason = c.maybe_do_clobber(os.getcwd(), True)
         self.assertFalse(required)
         self.assertFalse(performed)
         self.assertIsNone(reason)
 
         self.assertTrue(os.path.isdir(tmp))
         self.assertTrue(os.path.exists(os.path.join(tmp, 'CLOBBER')))
 
     def test_objdir_no_clobber_file(self):
         """If CLOBBER does not exist in topobjdir, treat as empty."""
 
         c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
         self.assertFalse(c.clobber_needed())
 
-        required, performed, reason = c.maybe_do_clobber(os.getcwd())
+        required, performed, reason = c.maybe_do_clobber(os.getcwd(), True)
         self.assertFalse(required)
         self.assertFalse(performed)
         self.assertIsNone(reason)
 
         self.assertTrue(os.path.exists(os.path.join(c.topobjdir, 'CLOBBER')))
 
     def test_objdir_clobber_newer(self):
         """If CLOBBER in topobjdir is newer, do nothing."""
 
         c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
         with open(c.obj_clobber, 'a'):
             pass
 
-        required, performed, reason = c.maybe_do_clobber(os.getcwd())
+        required, performed, reason = c.maybe_do_clobber(os.getcwd(), True)
         self.assertFalse(required)
         self.assertFalse(performed)
         self.assertIsNone(reason)
 
     def test_objdir_clobber_older(self):
         """If CLOBBER in topobjdir is older, we clobber."""
 
         c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
@@ -98,23 +98,17 @@ class TestClobberer(unittest.TestCase):
 
         self.assertTrue(os.path.exists(dummy_path))
 
         old_time = os.path.getmtime(c.src_clobber) - 60
         os.utime(c.obj_clobber, (old_time, old_time))
 
         self.assertTrue(c.clobber_needed())
 
-        required, performed, reason = c.maybe_do_clobber(os.getcwd(), False)
-        self.assertTrue(required)
-        self.assertFalse(performed)
-        self.assertIn('Automatic clobbering has been disabled', reason)
-
-        # Now let's actually do it.
-        required, performed, reason = c.maybe_do_clobber(os.getcwd())
+        required, performed, reason = c.maybe_do_clobber(os.getcwd(), True)
         self.assertTrue(required)
         self.assertTrue(performed)
 
         self.assertFalse(os.path.exists(dummy_path))
         self.assertTrue(os.path.exists(c.obj_clobber))
         self.assertGreaterEqual(os.path.getmtime(c.obj_clobber),
             os.path.getmtime(c.src_clobber))
 
@@ -143,17 +137,17 @@ class TestClobberer(unittest.TestCase):
         self.assertTrue(os.path.exists(dummy_file))
         self.assertTrue(os.path.isdir(dummy_dir))
 
         old_time = os.path.getmtime(c.src_clobber) - 60
         os.utime(c.obj_clobber, (old_time, old_time))
 
         self.assertTrue(c.clobber_needed())
 
-        required, performed, reason = c.maybe_do_clobber(c.topobjdir)
+        required, performed, reason = c.maybe_do_clobber(c.topobjdir, True)
         self.assertTrue(required)
         self.assertTrue(performed)
 
         self.assertFalse(os.path.exists(dummy_file))
         self.assertFalse(os.path.exists(dummy_dir))
 
     def test_cwd_under_topobjdir(self):
         """If cwd is under topobjdir, we can't clobber."""
@@ -164,24 +158,24 @@ class TestClobberer(unittest.TestCase):
             pass
 
         old_time = os.path.getmtime(c.src_clobber) - 60
         os.utime(c.obj_clobber, (old_time, old_time))
 
         d = os.path.join(c.topobjdir, 'dummy_dir')
         os.mkdir(d)
 
-        required, performed, reason = c.maybe_do_clobber(d)
+        required, performed, reason = c.maybe_do_clobber(d, True)
         self.assertTrue(required)
         self.assertFalse(performed)
         self.assertIn('Cannot clobber while the shell is inside', reason)
 
 
-    def test_mozconfig_overrides_auto_clobber(self):
-        """If NO_AUTOCLOBBER is in the environment, don't auto clobber."""
+    def test_mozconfig_opt_in(self):
+        """Auto clobber iff AUTOCLOBBER is in the environment."""
 
         topsrcdir = self.get_topsrcdir()
         topobjdir = self.get_tempdir()
 
         obj_clobber = os.path.join(topobjdir, 'CLOBBER')
         with open(obj_clobber, 'a'):
             pass
 
@@ -189,20 +183,31 @@ class TestClobberer(unittest.TestCase):
         with open(dummy_file, 'a'):
             pass
 
         self.assertTrue(os.path.exists(dummy_file))
 
         old_time = os.path.getmtime(os.path.join(topsrcdir, 'CLOBBER')) - 60
         os.utime(obj_clobber, (old_time, old_time))
 
+        # Check auto clobber is off by default
         env = dict(os.environ)
-        env['NO_AUTOCLOBBER'] = '1'
+        if env.get('AUTOCLOBBER', False):
+            del env['AUTOCLOBBER']
 
         s = StringIO()
         status = clobber([topsrcdir, topobjdir], env, os.getcwd(), s)
         self.assertEqual(status, 1)
-        self.assertIn('Automatic clobbering has been disabled', s.getvalue())
+        self.assertIn('Automatic clobbering is not enabled', s.getvalue())
         self.assertTrue(os.path.exists(dummy_file))
 
+        # Check auto clobber opt-in works
+        env['AUTOCLOBBER'] = '1'
+
+        s = StringIO()
+        status = clobber([topsrcdir, topobjdir], env, os.getcwd(), s)
+        self.assertEqual(status, 1)
+        self.assertIn('Successfully completed auto clobber', s.getvalue())
+        self.assertFalse(os.path.exists(dummy_file))
+
 
 if __name__ == '__main__':
     main()