示例#1
0
    def test_filesystem_specs(self) -> None:
        # Literal file arg.
        sources_field1_all_sources = SOURCES1.source_file_absolute_paths
        sources_field1_slice = slice(0, 1)
        sources_field1 = self.mock_sources_field_with_origin(
            SOURCES1,
            origin=FilesystemLiteralSpec(sources_field1_all_sources[0]))

        # Glob file arg that matches the entire `sources`.
        sources_field2_all_sources = SOURCES2.source_file_absolute_paths
        sources_field2_slice = slice(0, len(sources_field2_all_sources))
        sources_field2_origin = FilesystemResolvedGlobSpec(
            f"{SOURCES2.source_root}/*.py",
            files=tuple(sources_field2_all_sources))
        sources_field2 = self.mock_sources_field_with_origin(
            SOURCES2, origin=sources_field2_origin)

        # Glob file arg that only matches a subset of the `sources` _and_ includes resolved
        # files not owned by the target.
        sources_field3_all_sources = SOURCES3.source_file_absolute_paths
        sources_field3_slice = slice(0, 1)
        sources_field3_origin = FilesystemResolvedGlobSpec(
            f"{SOURCES3.source_root}/*.java",
            files=tuple(
                PurePath(SOURCES3.source_root, name).as_posix() for name in
                [SOURCES3.source_files[0], "other_target.java", "j.tmp.java"]),
        )
        sources_field3 = self.mock_sources_field_with_origin(
            SOURCES3, origin=sources_field3_origin)

        def assert_file_args_resolved(
            sources_field_with_origin: Tuple[SourcesField, OriginSpec],
            all_sources: List[str],
            expected_slice: slice,
        ) -> None:
            assert self.get_all_source_files([sources_field_with_origin
                                              ]) == all_sources
            assert (self.get_specified_source_files(
                [sources_field_with_origin]) == all_sources[expected_slice])

        assert_file_args_resolved(sources_field1, sources_field1_all_sources,
                                  sources_field1_slice)
        assert_file_args_resolved(sources_field2, sources_field2_all_sources,
                                  sources_field2_slice)
        assert_file_args_resolved(sources_field3, sources_field3_all_sources,
                                  sources_field3_slice)

        combined_sources_fields = [
            sources_field1, sources_field2, sources_field3
        ]
        assert self.get_all_source_files(combined_sources_fields) == sorted([
            *sources_field1_all_sources, *sources_field2_all_sources,
            *sources_field3_all_sources
        ])
        assert self.get_specified_source_files(
            combined_sources_fields) == sorted([
                *sources_field1_all_sources[sources_field1_slice],
                *sources_field2_all_sources[sources_field2_slice],
                *sources_field3_all_sources[sources_field3_slice],
            ])
    def test_filesystem_specs(self) -> None:
        # Literal file arg.
        target1_all_sources = self.SOURCES1.source_file_absolute_paths
        target1_slice = slice(0, 1)
        target1 = self.mock_target(self.SOURCES1,
                                   origin=FilesystemLiteralSpec(
                                       target1_all_sources[0]))

        # Glob file arg that matches the entire target's `sources`.
        target2_all_sources = self.SOURCES2.source_file_absolute_paths
        target2_slice = slice(0, len(target2_all_sources))
        target2_origin = FilesystemResolvedGlobSpec(
            f"{self.SOURCES2.source_root}/*.py",
            files=tuple(target2_all_sources))
        target2 = self.mock_target(self.SOURCES2, origin=target2_origin)

        # Glob file arg that only matches a subset of the target's `sources` _and_ includes resolved
        # files not owned by the target.
        target3_all_sources = self.SOURCES3.source_file_absolute_paths
        target3_slice = slice(0, 1)
        target3_origin = FilesystemResolvedGlobSpec(
            f"{self.SOURCES3.source_root}/*.java",
            files=tuple(
                PurePath(self.SOURCES3.source_root, name).as_posix()
                for name in [
                    self.SOURCES3.source_files[0], "other_target.java",
                    "j.tmp.java"
                ]),
        )
        target3 = self.mock_target(self.SOURCES3, origin=target3_origin)

        def assert_file_args_resolved(target: TargetAdaptorWithOrigin,
                                      all_sources: List[str],
                                      expected_slice: slice) -> None:
            assert self.get_all_source_files([target]) == all_sources
            assert self.get_specified_source_files(
                [target]) == all_sources[expected_slice]

        assert_file_args_resolved(target1, target1_all_sources, target1_slice)
        assert_file_args_resolved(target2, target2_all_sources, target2_slice)
        assert_file_args_resolved(target3, target3_all_sources, target3_slice)

        combined_targets = [target1, target2, target3]
        assert self.get_all_source_files(combined_targets) == sorted(
            [*target1_all_sources, *target2_all_sources, *target3_all_sources])
        assert self.get_specified_source_files(combined_targets) == sorted([
            *target1_all_sources[target1_slice],
            *target2_all_sources[target2_slice],
            *target3_all_sources[target3_slice],
        ])
示例#3
0
async def addresses_with_origins_from_filesystem_specs(
    filesystem_specs: FilesystemSpecs, global_options: GlobalOptions,
) -> AddressesWithOrigins:
    """Find the owner(s) for each FilesystemSpec while preserving the original FilesystemSpec those
    owners come from.

    This will merge FilesystemSpecs that come from the same owning target into a single
    FilesystemMergedSpec.
    """
    pathglobs_per_include = (
        filesystem_specs.path_globs_for_spec(
            spec, global_options.options.owners_not_found_behavior.to_glob_match_error_behavior(),
        )
        for spec in filesystem_specs.includes
    )
    snapshot_per_include = await MultiGet(
        Get[Snapshot](PathGlobs, pg) for pg in pathglobs_per_include
    )
    owners_per_include = await MultiGet(
        Get[Owners](OwnersRequest(sources=snapshot.files)) for snapshot in snapshot_per_include
    )
    addresses_to_specs: DefaultDict[
        Address, List[Union[FilesystemLiteralSpec, FilesystemResolvedGlobSpec]]
    ] = defaultdict(list)
    for spec, snapshot, owners in zip(
        filesystem_specs.includes, snapshot_per_include, owners_per_include
    ):
        if (
            global_options.options.owners_not_found_behavior != OwnersNotFoundBehavior.ignore
            and isinstance(spec, FilesystemLiteralSpec)
            and not owners.addresses
        ):
            file_path = PurePath(spec.to_spec_string())
            msg = (
                f"No owning targets could be found for the file `{file_path}`.\n\nPlease check "
                f"that there is a BUILD file in `{file_path.parent}` with a target whose `sources` field "
                f"includes `{file_path}`. See https://pants.readme.io/docs/targets for more "
                "information on target definitions.\n"
                "If you would like to ignore un-owned files, please pass `--owners-not-found-behavior=ignore`."
            )
            if global_options.options.owners_not_found_behavior == OwnersNotFoundBehavior.warn:
                logger.warning(msg)
            else:
                raise ResolveError(msg)
        # We preserve what literal files any globs resolved to. This allows downstream goals to be
        # more precise in which files they operate on.
        origin: Union[FilesystemLiteralSpec, FilesystemResolvedGlobSpec] = (
            spec
            if isinstance(spec, FilesystemLiteralSpec)
            else FilesystemResolvedGlobSpec(glob=spec.glob, files=snapshot.files)
        )
        for address in owners.addresses:
            addresses_to_specs[address].append(origin)
    return AddressesWithOrigins(
        AddressWithOrigin(
            address, specs[0] if len(specs) == 1 else FilesystemMergedSpec.create(specs)
        )
        for address, specs in addresses_to_specs.items()
    )