Bug 1401309 - [mozversioncontrol] Merge get_modified_files and get_added_files into a single function, r=gps

There's currently a function for getting added files (A) and modified files
(M). We'll also eventually need the ability to get deleted files (D) and any
combination of the above, e.g (AM). Rather than creating a new function for
each possible case, let's have a single function where you can pass in which
modifiers you are interested in. With this patch, if you want all modified and
added files, you can do:

get_changed_files('AM')

By default 'ADM' is used.

This also adds a 'mode' option for git. This allows consumers to return staged
files, unstaged files or both. The default ('unstaged') keeps the current
behaviour in tact.

MozReview-Commit-ID: 9IA1bxaJS80

--HG--
extra : rebase_source : 160f650220ca9a35b4b116bc9fa13f28d84419fa
This commit is contained in:
Andrew Halberstadt 2017-09-20 10:06:11 -04:00
Родитель 8dd527bf64
Коммит 13b127e919
3 изменённых файлов: 41 добавлений и 19 удалений

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

@ -200,7 +200,7 @@ Please check manually and update the vendor script.
in the working copy, since we're going to change some state
on the user.
'''
modified = self.repository.get_modified_files()
modified = self.repository.get_changed_files('M')
if modified:
self.log(logging.ERROR, 'modified_files', {},
'''You have uncommitted changes to the following files:

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

@ -60,7 +60,7 @@ class VendorRust(MozbuildObject):
on the user. Allow changes to Cargo.{toml,lock} since that's
likely to be a common use case.
'''
modified = [f for f in self.repository.get_modified_files() if os.path.basename(f) not in ('Cargo.toml', 'Cargo.lock')]
modified = [f for f in self.repository.get_changed_files('M') if os.path.basename(f) not in ('Cargo.toml', 'Cargo.lock')]
if modified:
self.log(logging.ERROR, 'modified_files', {},
'''You have uncommitted changes to the following files:
@ -296,7 +296,7 @@ license file's hash.
FILESIZE_LIMIT = 100 * 1024
large_files = set()
cumulative_added_size = 0
for f in self.repository.get_added_files():
for f in self.repository.get_changed_files('A'):
path = mozpath.join(self.topsrcdir, f)
size = os.stat(path).st_size
cumulative_added_size += size

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

@ -58,6 +58,7 @@ class Repository(object):
self._tool = get_tool_path(tool)
self._env = os.environ.copy()
self._version = None
self._valid_diff_filter = ('m', 'a', 'd')
def __enter__(self):
return self
@ -98,14 +99,22 @@ class Repository(object):
"""
@abc.abstractmethod
def get_modified_files(self):
'''Return a list of files that are modified in this repository's
working copy.'''
def get_changed_files(self, diff_filter, mode='unstaged'):
"""Return a list of files that are changed in this repository's
working copy.
@abc.abstractmethod
def get_added_files(self):
'''Return a list of files that are added in this repository's
working copy.'''
``diff_filter`` controls which kinds of modifications are returned.
It is a string which may only contain the following characters:
A - Include files that were added
D - Include files that were deleted
M - Include files that were modified
By default, all three will be included.
``mode`` can be one of 'unstaged', 'staged' or 'all'. Only has an
affect on git. Defaults to 'unstaged'.
"""
@abc.abstractmethod
def add_remove_files(self, path):
@ -196,13 +205,21 @@ class HgRepository(Repository):
return False
def get_modified_files(self):
# Use --no-status to print just the filename.
return self._run('status', '--modified', '--no-status').splitlines()
def _format_diff_filter(self, diff_filter):
df = diff_filter.lower()
assert all(f in self._valid_diff_filter for f in df)
# Mercurial uses 'r' to denote removed files whereas git uses 'd'.
if 'd' in df:
df.replace('d', 'r')
return df.lower()
def get_changed_files(self, diff_filter='ADM', mode='unstaged'):
df = self._format_diff_filter(diff_filter)
def get_added_files(self):
# Use --no-status to print just the filename.
return self._run('status', '--added', '--no-status').splitlines()
return self._run('status', '--no-status', '-{}'.format(df)).splitlines()
def add_remove_files(self, path):
args = ['addremove', path]
@ -245,11 +262,16 @@ class GitRepository(Repository):
# Not yet implemented.
return False
def get_modified_files(self):
return self._run('diff', '--diff-filter=M', '--name-only').splitlines()
def get_changed_files(self, diff_filter='ADM', mode='unstaged'):
assert all(f.lower() in self._valid_diff_filter for f in diff_filter)
def get_added_files(self):
return self._run('diff', '--diff-filter=A', '--name-only').splitlines()
cmd = ['diff', '--diff-filter={}'.format(diff_filter.upper()), '--name-only']
if mode == 'staged':
cmd.append('--cached')
elif mode == 'all':
cmd.append('HEAD')
return self._run(*cmd).splitlines()
def add_remove_files(self, path):
self._run('add', path)