diff --git a/src/python/pants/engine/build_files.py b/src/python/pants/engine/build_files.py index 0451fb42bd72..2d7b361ceb48 100644 --- a/src/python/pants/engine/build_files.py +++ b/src/python/pants/engine/build_files.py @@ -36,10 +36,6 @@ def _key_func(entry): return key -class BuildDirs(datatype('BuildDirs', ['dependencies'])): - """A list of Stat objects for directories containing build files.""" - - class Specs(Collection.of(Spec)): """A collection of Spec subclasses.""" @@ -209,17 +205,18 @@ def _hydrate(item_type, spec_path, **kwargs): return item -@rule(BuildFileAddresses, - [Select(AddressMapper), - SelectDependencies(AddressFamily, BuildDirs, field_types=(Dir,)), - Select(Specs)]) -def addresses_from_address_families(address_mapper, address_families, specs): +@rule(BuildFileAddresses, [Select(AddressMapper), Select(Specs)]) +def addresses_from_address_families(address_mapper, specs): """Given a list of AddressFamilies matching a list of Specs, return matching Addresses. Raises a AddressLookupError if: - there were no matching AddressFamilies, or - the Spec matches no addresses for SingleAddresses. """ + # Capture a Snapshot covering all paths for these Specs, then group by directory. + snapshot = yield Get(Snapshot, _spec_to_globs(address_mapper, specs)) + dirnames = set(dirname(f.stat.path) for f in snapshot.files) + address_families = yield [Get(AddressFamily, Dir(d)) for d in dirnames] # NB: `@memoized` does not work on local functions. def by_directory(): @@ -281,20 +278,11 @@ def include(address_families, predicate=None): else: raise ValueError('Unrecognized Spec type: {}'.format(spec)) - return BuildFileAddresses(addresses) + yield BuildFileAddresses(addresses) -@rule(BuildDirs, [Select(AddressMapper), Select(Snapshot)]) -def filter_build_dirs(address_mapper, snapshot): - """Given a Snapshot matching a build pattern, return parent directories as BuildDirs.""" - dirnames = set(dirname(f.stat.path) for f in snapshot.files) - return BuildDirs(tuple(Dir(d) for d in dirnames)) - - -@rule(PathGlobs, [Select(AddressMapper), Select(Specs)]) -def spec_to_globs(address_mapper, specs): - """Given a Spec object, return a PathGlobs object for the build files that it matches. - """ +def _spec_to_globs(address_mapper, specs): + """Given a Specs object, return a PathGlobs object for the build files that it matches.""" patterns = set() for spec in specs.dependencies: if type(spec) is DescendantAddresses: @@ -365,8 +353,6 @@ def create_graph_rules(address_mapper, symbol_table): # Spec handling: locate directories that contain build files, and request # AddressFamilies for each of them. addresses_from_address_families, - filter_build_dirs, - spec_to_globs, # Root rules representing parameters that might be provided via root subjects. RootRule(Address), RootRule(BuildFileAddress),