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 id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs863091
milestone23.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 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()