Bug 974281 - Do not clobber msvc directory by default; r=ted

The "remove_objdir" method has been rewritten to support partial
clobber. It still defaults to full clobber. But the "full" argument
can be passed as False to limit to a partial clobber where currently
the "msvc" directory (contains Visual Studio files) is not clobbered.

On Windows, there might be a regression with this change because
we'll be invoking N winrm.exe processes and new processes have
a non-trivial overhead on Windows. However, it is hopefully unlikely
that new processes are more overhead than deleting hundreds of thousands
of files.

MozReview-Commit-ID: 7yeMttztwic

--HG--
extra : rebase_source : 646992be199e1059f0b09cf8bed3334085293fe0
This commit is contained in:
Gregory Szorc 2016-03-11 15:11:33 -08:00
Родитель 303d2ef97a
Коммит 4a0f2d02bc
2 изменённых файлов: 40 добавлений и 9 удалений

Просмотреть файл

@ -4,6 +4,7 @@
from __future__ import absolute_import, print_function, unicode_literals
import errno
import json
import logging
import mozpack.path as mozpath
@ -298,15 +299,43 @@ class MozbuildObject(ProcessExecutionMixin):
except:
return False
def remove_objdir(self):
"""Remove the entire object directory."""
def remove_objdir(self, full=True):
"""Remove the object directory.
if sys.platform.startswith('win') and self.have_winrm():
subprocess.check_call(['winrm', '-rf', self.topobjdir])
else:
# We use mozfile because it is faster than shutil.rmtree().
``full`` controls whether to fully delete the objdir. If False,
some directories (e.g. Visual Studio Project Files) will not be
deleted.
"""
# Top-level files and directories to not clobber by default.
no_clobber = {
'msvc',
}
if full:
# mozfile doesn't like unicode arguments (bug 818783).
mozfileremove(self.topobjdir.encode('utf-8'))
paths = [self.topobjdir.encode('utf-8')]
else:
try:
paths = []
for p in os.listdir(self.topobjdir):
if p not in no_clobber:
paths.append(os.path.join(self.topobjdir, p).encode('utf-8'))
except OSError as e:
if e.errno != errno.ENOENT:
raise
return
procs = []
for p in sorted(paths):
path = os.path.join(self.topobjdir, p)
if sys.platform.startswith('win') and self.have_winrm() and os.path.isdir(path):
procs.append(subprocess.Popen(['winrm', '-rf', path]))
else:
# We use mozfile because it is faster than shutil.rmtree().
mozfileremove(path)
for p in procs:
p.wait()
def get_binary_path(self, what='app', validate_exists=True, where='default'):
"""Obtain the path to a compiled binary for this build configuration.

Просмотреть файл

@ -631,7 +631,9 @@ class Clobber(MachCommandBase):
@CommandArgument('what', default=['objdir'], nargs='*',
help='Target to clobber, must be one of {{{}}} (default objdir).'.format(
', '.join(CLOBBER_CHOICES)))
def clobber(self, what):
@CommandArgument('--full', action='store_true',
help='Perform a full clobber')
def clobber(self, what, full=False):
invalid = set(what) - set(self.CLOBBER_CHOICES)
if invalid:
print('Unknown clobber target(s): {}'.format(', '.join(invalid)))
@ -640,7 +642,7 @@ class Clobber(MachCommandBase):
ret = 0
if 'objdir' in what:
try:
self.remove_objdir()
self.remove_objdir(full=full)
except OSError as e:
if sys.platform.startswith('win'):
if isinstance(e, WindowsError) and e.winerror in (5,32):