Bug 1384400 - Add input to output mappings to mozpack.FileRegistry. r=gps

This is necessary because the existing manifests don't expose full
dependency information.  I needed to avoid the existing dependency
files because those code paths need to know the output destination of
the manifest in order to parse the Make dependency files; trying to
adapt this system is more complicated than just preprocessing each
file to extract dependency information directly.

MozReview-Commit-ID: 5m0SEqmhJMM

--HG--
extra : rebase_source : 1ff6a1a51bc76efa78eb564cd8e572777dace0f6
This commit is contained in:
Nick Alexander 2017-07-25 12:28:31 -07:00
Родитель c6bd9e5a77
Коммит 8f1ac5b651
2 изменённых файлов: 55 добавлений и 0 удалений

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

@ -16,6 +16,7 @@ from mozpack.files import (
import mozpack.path as mozpath
import errno
from collections import (
defaultdict,
Counter,
OrderedDict,
)
@ -153,6 +154,34 @@ class FileRegistry(object):
'''
return set(k for k, v in self._required_directories.items() if v > 0)
def output_to_inputs_tree(self):
'''
Return a dictionary mapping each output path to the set of its
required input paths.
All paths are normalized.
'''
tree = {}
for output, file in self:
output = mozpath.normpath(output)
tree[output] = set(mozpath.normpath(f) for f in file.inputs())
return tree
def input_to_outputs_tree(self):
'''
Return a dictionary mapping each input path to the set of
impacted output paths.
All paths are normalized.
'''
tree = defaultdict(set)
for output, file in self:
output = mozpath.normpath(output)
for input in file.inputs():
input = mozpath.normpath(input)
tree[input].add(output)
return dict(tree)
class FileRegistrySubtree(object):
'''A proxy class to give access to a subtree of an existing FileRegistry.

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

@ -234,6 +234,12 @@ class BaseFile(object):
'''
return None
def inputs(self):
'''
Return an iterable of the input file paths that impact this output file.
'''
raise NotImplementedError('BaseFile.inputs() not implemented.')
class File(BaseFile):
'''
@ -261,6 +267,9 @@ class File(BaseFile):
def size(self):
return os.stat(self.path).st_size
def inputs(self):
return (self.path,)
class ExecutableFile(File):
'''
@ -474,6 +483,9 @@ class ExistingFile(BaseFile):
errors.fatal("Required existing file doesn't exist: %s" %
dest.path)
def inputs(self):
return ()
class PreprocessedFile(BaseFile):
'''
@ -490,6 +502,17 @@ class PreprocessedFile(BaseFile):
self.silence_missing_directive_warnings = \
silence_missing_directive_warnings
def inputs(self):
pp = Preprocessor(defines=self.defines, marker=self.marker)
pp.setSilenceDirectiveWarnings(self.silence_missing_directive_warnings)
with open(self.path, 'rU') as input:
with open(os.devnull, 'w') as output:
pp.processFile(input=input, output=output)
# This always yields at least self.path.
return pp.includes
def copy(self, dest, skip_if_older=True):
'''
Invokes the preprocessor to create the destination file.
@ -565,6 +588,9 @@ class GeneratedFile(BaseFile):
def size(self):
return len(self.content)
def inputs(self):
return ()
class DeflatedFile(BaseFile):
'''