зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1397406 - Add a helper function to retrieve a BuildReader; r=dustin
The code for obtaining a BuildReader for evaluating moz.build files is generic and non-trivial. We already had a custom implementation for `mach file-info` that implemented support for Mercurial integration. Bug 1383880 will introduce a second consumer. So this commit factors out the "obtain a BuildReader" logic into a reusable function on our base MozbuildObject class. This makes it easily available to various parts of the build system and mach commands. As part of the change, we detect when ``.`` is being used as the revision and verify the working directory is clean. This behavior can be disabled via argument if unwanted. But it's useful by default to ensure consumers aren't expecting to read uncommitted changes. MozReview-Commit-ID: LeYFqAb3HAe --HG-- extra : rebase_source : d5ed4e4f5570a58a68853188de2225cd4e64ab3a
This commit is contained in:
Родитель
2cf6305161
Коммит
069ee9c5d6
|
@ -17,6 +17,7 @@ from mach.mixin.process import ProcessExecutionMixin
|
|||
from mozversioncontrol import (
|
||||
get_repository_from_build_config,
|
||||
get_repository_object,
|
||||
InvalidRepoPath,
|
||||
)
|
||||
|
||||
from .backend.configenvironment import ConfigEnvironment
|
||||
|
@ -298,6 +299,80 @@ class MozbuildObject(ProcessExecutionMixin):
|
|||
|
||||
return get_repository_object(self.topsrcdir)
|
||||
|
||||
def mozbuild_reader(self, config_mode='build', vcs_revision=None,
|
||||
vcs_check_clean=True):
|
||||
"""Obtain a ``BuildReader`` for evaluating moz.build files.
|
||||
|
||||
Given arguments, returns a ``mozbuild.frontend.reader.BuildReader``
|
||||
that can be used to evaluate moz.build files for this repo.
|
||||
|
||||
``config_mode`` is either ``build`` or ``empty``. If ``build``,
|
||||
``self.config_environment`` is used. This requires a configured build
|
||||
system to work. If ``empty``, an empty config is used. ``empty`` is
|
||||
appropriate for file-based traversal mode where ``Files`` metadata is
|
||||
read.
|
||||
|
||||
If ``vcs_revision`` is defined, it specifies a version control revision
|
||||
to use to obtain files content. The default is to use the filesystem.
|
||||
This mode is only supported with Mercurial repositories.
|
||||
|
||||
If ``vcs_revision`` is not defined and the version control checkout is
|
||||
sparse, this implies ``vcs_revision='.'``.
|
||||
|
||||
If ``vcs_revision`` is ``.`` (denotes the parent of the working
|
||||
directory), we will verify that the working directory is clean unless
|
||||
``vcs_check_clean`` is False. This prevents confusion due to uncommitted
|
||||
file changes not being reflected in the reader.
|
||||
"""
|
||||
from mozbuild.frontend.reader import (
|
||||
default_finder,
|
||||
BuildReader,
|
||||
EmptyConfig,
|
||||
)
|
||||
from mozpack.files import (
|
||||
MercurialRevisionFinder,
|
||||
)
|
||||
|
||||
if config_mode == 'build':
|
||||
config = self.config_environment
|
||||
elif config_mode == 'empty':
|
||||
config = EmptyConfig(self.topsrcdir)
|
||||
else:
|
||||
raise ValueError('unknown config_mode value: %s' % config_mode)
|
||||
|
||||
try:
|
||||
repo = self.repository
|
||||
except InvalidRepoPath:
|
||||
repo = None
|
||||
|
||||
if repo and not vcs_revision and repo.sparse_checkout_present():
|
||||
vcs_revision = '.'
|
||||
|
||||
if vcs_revision is None:
|
||||
finder = default_finder
|
||||
else:
|
||||
# If we failed to detect the repo prior, check again to raise its
|
||||
# exception.
|
||||
if not repo:
|
||||
self.repository
|
||||
assert False
|
||||
|
||||
if repo.name != 'hg':
|
||||
raise Exception('do not support VCS reading mode for %s' %
|
||||
repo.name)
|
||||
|
||||
if vcs_revision == '.' and vcs_check_clean:
|
||||
with repo:
|
||||
if not repo.working_directory_clean():
|
||||
raise Exception('working directory is not clean; '
|
||||
'refusing to use a VCS-based finder')
|
||||
|
||||
finder = MercurialRevisionFinder(self.topsrcdir, rev=vcs_revision,
|
||||
recognize_repo_paths=True)
|
||||
|
||||
return BuildReader(config, finder=finder)
|
||||
|
||||
|
||||
@memoized_property
|
||||
def python3(self):
|
||||
"""Obtain info about a Python 3 executable.
|
||||
|
|
|
@ -159,18 +159,8 @@ class MozbuildFileCommands(MachCommandBase):
|
|||
return 1
|
||||
|
||||
|
||||
def _get_reader(self, finder):
|
||||
from mozbuild.frontend.reader import (
|
||||
BuildReader,
|
||||
EmptyConfig,
|
||||
)
|
||||
|
||||
config = EmptyConfig(self.topsrcdir)
|
||||
return BuildReader(config, finder=finder)
|
||||
|
||||
def _get_files_info(self, paths, rev=None):
|
||||
from mozbuild.frontend.reader import default_finder
|
||||
from mozpack.files import FileFinder, MercurialRevisionFinder
|
||||
reader = self.mozbuild_reader(config_mode='empty', vcs_revision=rev)
|
||||
|
||||
# Normalize to relative from topsrcdir.
|
||||
relpaths = []
|
||||
|
@ -181,24 +171,6 @@ class MozbuildFileCommands(MachCommandBase):
|
|||
|
||||
relpaths.append(mozpath.relpath(a, self.topsrcdir))
|
||||
|
||||
repo = None
|
||||
if rev:
|
||||
hg_path = os.path.join(self.topsrcdir, '.hg')
|
||||
if not os.path.exists(hg_path):
|
||||
raise InvalidPathException('a Mercurial repo is required '
|
||||
'when specifying a revision')
|
||||
|
||||
repo = self.topsrcdir
|
||||
|
||||
# We need two finders because the reader's finder operates on
|
||||
# absolute paths.
|
||||
finder = FileFinder(self.topsrcdir)
|
||||
if repo:
|
||||
reader_finder = MercurialRevisionFinder(repo, rev=rev,
|
||||
recognize_repo_paths=True)
|
||||
else:
|
||||
reader_finder = default_finder
|
||||
|
||||
# Expand wildcards.
|
||||
# One variable is for ordering. The other for membership tests.
|
||||
# (Membership testing on a list can be slow.)
|
||||
|
@ -211,13 +183,12 @@ class MozbuildFileCommands(MachCommandBase):
|
|||
allpaths.append(p)
|
||||
continue
|
||||
|
||||
if repo:
|
||||
if rev:
|
||||
raise InvalidPathException('cannot use wildcard in version control mode')
|
||||
|
||||
for path, f in finder.find(p):
|
||||
for path, f in reader.finder.find(p):
|
||||
if path not in all_paths_set:
|
||||
all_paths_set.add(path)
|
||||
allpaths.append(path)
|
||||
|
||||
reader = self._get_reader(finder=reader_finder)
|
||||
return reader.files_info(allpaths)
|
||||
|
|
Загрузка…
Ссылка в новой задаче