Ejemplo n.º 1
0
def test_raw_specs_with_only_file_owners_glob(rule_runner: RuleRunner) -> None:
    rule_runner.write_files({
        "demo/f1.txt":
        "",
        "demo/f2.txt":
        "",
        "demo/BUILD":
        dedent("""\
                file_generator(name='generator', sources=['*.txt'])
                nonfile_generator(name='nonfile')
                target(name='not-generator', sources=['*.txt'])
                target(name='skip-me', sources=['*.txt'])
                target(name='bad-tag', sources=['*.txt'], tags=['skip'])
                """),
    })
    rule_runner.set_options(["--tag=-skip", "--exclude-target-regexp=skip-me"])
    all_unskipped_addresses = [
        Address("demo", target_name="not-generator"),
        Address("demo", target_name="generator", relative_file_path="f1.txt"),
        Address("demo", target_name="generator", relative_file_path="f2.txt"),
    ]

    assert (resolve_raw_specs_with_only_file_owners(
        rule_runner, [FileGlobSpec("demo/*.txt")]) == all_unskipped_addresses)
    # We should deduplicate between glob and literal specs.
    assert (resolve_raw_specs_with_only_file_owners(
        rule_runner,
        [FileGlobSpec("demo/*.txt"),
         FileLiteralSpec("demo/f1.txt")],
    ) == all_unskipped_addresses)
Ejemplo n.º 2
0
def test_raw_specs_with_only_file_owners_no_owner(
        rule_runner: RuleRunner) -> None:
    rule_runner.set_options(["--owners-not-found-behavior=error"])
    rule_runner.write_files({"no_owners/f.txt": ""})
    # Error for literal specs.
    with pytest.raises(ExecutionError) as exc:
        resolve_raw_specs_with_only_file_owners(
            rule_runner, [FileLiteralSpec("no_owners/f.txt")])
    assert "No owning targets could be found for the file `no_owners/f.txt`" in str(
        exc.value)

    # Do not error for glob specs.
    assert not resolve_raw_specs_with_only_file_owners(
        rule_runner, [FileGlobSpec("no_owners/*.txt")])
Ejemplo n.º 3
0
    def parse_spec(self, spec: str) -> AddressSpec | FilesystemSpec:
        """Parse the given spec into an `AddressSpec` or `FilesystemSpec` object.

        :raises: CmdLineSpecParser.BadSpecError if the address selector could not be parsed.
        """
        if spec.endswith("::"):
            spec_path = spec[:-len("::")]
            return DescendantAddresses(
                directory=self._normalize_spec_path(spec_path))
        if spec.endswith(":"):
            spec_path = spec[:-len(":")]
            return SiblingAddresses(
                directory=self._normalize_spec_path(spec_path))
        if ":" in spec or "#" in spec:
            tgt_parts = spec.split(":", maxsplit=1)
            path_component = tgt_parts[0]
            if len(tgt_parts) == 1:
                target_component = None
                generated_parts = path_component.split("#", maxsplit=1)
                if len(generated_parts) == 1:
                    generated_component = None
                else:
                    path_component, generated_component = generated_parts
            else:
                generated_parts = tgt_parts[1].split("#", maxsplit=1)
                if len(generated_parts) == 1:
                    target_component = generated_parts[0]
                    generated_component = None
                else:
                    target_component, generated_component = generated_parts
            return AddressLiteralSpec(
                path_component=self._normalize_spec_path(path_component),
                target_component=target_component,
                generated_component=generated_component,
            )
        if spec.startswith("!"):
            return FileIgnoreSpec(spec[1:])
        if "*" in spec:
            return FileGlobSpec(spec)
        if PurePath(spec).suffix:
            return FileLiteralSpec(self._normalize_spec_path(spec))
        spec_path = self._normalize_spec_path(spec)
        if spec_path == ".":
            return DirLiteralSpec("")
        # Some paths that look like dirs can actually be files without extensions.
        if Path(self._root_dir, spec_path).is_file():
            return FileLiteralSpec(spec_path)
        return DirLiteralSpec(spec_path)
Ejemplo n.º 4
0
    def parse_spec(self, spec: str) -> tuple[Spec, bool]:
        """Parse the given spec string and also return `true` if it's an ignore.

        :raises: CmdLineSpecParser.BadSpecError if the address selector could not be parsed.
        """
        is_ignore = False
        if spec.startswith("-"):
            is_ignore = True
            spec = spec[1:]

        (
            (
                path_component,
                target_component,
                generated_component,
                parameters,
            ),
            wildcard,
        ) = native_engine.address_spec_parse(spec)

        if wildcard == "::":
            return RecursiveGlobSpec(
                directory=self._normalize_spec_path(path_component)), is_ignore
        if wildcard == ":":
            return DirGlobSpec(
                directory=self._normalize_spec_path(path_component)), is_ignore
        if target_component or generated_component or parameters:
            return (
                AddressLiteralSpec(
                    path_component=self._normalize_spec_path(path_component),
                    target_component=target_component,
                    generated_component=generated_component,
                    parameters=FrozenDict(sorted(parameters)),
                ),
                is_ignore,
            )
        if "*" in path_component:
            return FileGlobSpec(spec), is_ignore
        if PurePath(spec).suffix:
            return FileLiteralSpec(self._normalize_spec_path(spec)), is_ignore
        spec_path = self._normalize_spec_path(spec)
        if spec_path == ".":
            return DirLiteralSpec(""), is_ignore
        # Some paths that look like dirs can actually be files without extensions.
        if Path(self._root_dir, spec_path).is_file():
            return FileLiteralSpec(spec_path), is_ignore
        return DirLiteralSpec(spec_path), is_ignore
Ejemplo n.º 5
0
def test_filtered_targets(rule_runner: RuleRunner) -> None:
    rule_runner.write_files({
        "addr_specs/f1.txt":
        "",
        "addr_specs/f2.txt":
        "",
        "addr_specs/BUILD":
        dedent("""\
                file_generator(
                    sources=["*.txt"],
                    tags=["a"],
                    overrides={"f2.txt": {"tags": ["b"]}},
                )
                nonfile_generator(name="nonfile", tags=["b"])

                target(name='t', tags=["a"])
                """),
        "fs_specs/f1.txt":
        "",
        "fs_specs/f2.txt":
        "",
        "fs_specs/BUILD":
        dedent("""\
                file_generator(
                    sources=["*.txt"],
                    tags=["a"],
                    overrides={"f2.txt": {"tags": ["b"]}},
                )

                target(name='t', sources=["f1.txt"], tags=["a"])
                """),
    })
    specs = RawSpecs(
        recursive_globs=(RecursiveGlobSpec("addr_specs"), ),
        file_globs=(FileGlobSpec("fs_specs/*.txt"), ),
        filter_by_global_options=True,
        description_of_origin="tests",
    )

    def check(tags_option: str | None, expected: set[Address]) -> None:
        if tags_option:
            rule_runner.set_options([f"--tag={tags_option}"])
        addresses = rule_runner.request(Addresses, [specs])
        result = rule_runner.request(FilteredTargets, [addresses])
        assert {t.address for t in result} == expected

    addr_f1 = Address("addr_specs", relative_file_path="f1.txt")
    addr_f2 = Address("addr_specs", relative_file_path="f2.txt")
    addr_gen = Address("addr_specs",
                       target_name="nonfile",
                       generated_name="gen")
    addr_direct = Address("addr_specs", target_name="t")

    fs_f1 = Address("fs_specs", relative_file_path="f1.txt")
    fs_f2 = Address("fs_specs", relative_file_path="f2.txt")
    fs_direct = Address("fs_specs", target_name="t")

    all_a_tags = {addr_f1, addr_direct, fs_f1, fs_direct}
    all_b_tags = {addr_gen, addr_f2, fs_f2}

    check(None, {*all_a_tags, *all_b_tags})
    check("a", all_a_tags)
    check("b", all_b_tags)
    check("-a", all_b_tags)
    check("-b", all_a_tags)
Ejemplo n.º 6
0
def file_glob(val: str) -> FileGlobSpec:
    return FileGlobSpec(val)