Exemple #1
0
def test_multiple_resolves(rule_runner: RuleRunner) -> None:
    rule_runner.write_files({
        "BUILD":
        dedent("""\
                jvm_artifact(
                    name='hamcrest',
                    group='org.hamcrest',
                    artifact='hamcrest-core',
                    version="1.3",
                    resolve=parametrize("a", "b"),
                )

                jvm_artifact(
                    name='opentest4j',
                    group='org.opentest4j',
                    artifact='opentest4j',
                    version='1.2.0',
                    resolve="a",
                )

                jvm_artifact(
                    name='apiguardian-api',
                    group='org.apiguardian',
                    artifact='apiguardian-api',
                    version='1.1.0',
                    resolve="b",
                )
                """),
    })
    rule_runner.set_options(["--jvm-resolves={'a': 'a.lock', 'b': 'b.lock'}"],
                            env_inherit={"PATH"})

    result = rule_runner.request(UserGenerateLockfiles,
                                 [RequestedJVMUserResolveNames(["a", "b"])])
    hamcrest_core = ArtifactRequirement(
        Coordinate("org.hamcrest", "hamcrest-core", "1.3"))
    assert set(result) == {
        GenerateJvmLockfile(
            artifacts=ArtifactRequirements([
                hamcrest_core,
                ArtifactRequirement(
                    Coordinate("org.opentest4j", "opentest4j", "1.2.0")),
            ]),
            resolve_name="a",
            lockfile_dest="a.lock",
        ),
        GenerateJvmLockfile(
            artifacts=ArtifactRequirements([
                ArtifactRequirement(
                    Coordinate("org.apiguardian", "apiguardian-api", "1.1.0")),
                hamcrest_core,
            ]),
            resolve_name="b",
            lockfile_dest="b.lock",
        ),
    }
Exemple #2
0
async def setup_user_lockfile_requests(
    requested: RequestedJVMUserResolveNames,
    all_targets: AllTargets,
    jvm_subsystem: JvmSubsystem,
) -> UserGenerateLockfiles:
    resolve_to_artifacts: Mapping[
        str, OrderedSet[ArtifactRequirement]] = defaultdict(OrderedSet)
    for tgt in sorted(all_targets, key=lambda t: t.address):
        if not tgt.has_field(JvmArtifactResolveField):
            continue
        artifact = ArtifactRequirement.from_jvm_artifact_target(tgt)
        resolve = tgt[JvmResolveField].normalized_value(jvm_subsystem)
        resolve_to_artifacts[resolve].add(artifact)

    # Generate a JVM lockfile request for each requested resolve. This step also allows other backends to
    # validate the proposed set of artifact requirements for each resolve.
    jvm_lockfile_requests = await MultiGet(
        Get(
            GenerateJvmLockfile,
            _ValidateJvmArtifactsRequest(
                artifacts=ArtifactRequirements(
                    resolve_to_artifacts.get(resolve, ())),
                resolve_name=resolve,
            ),
        ) for resolve in requested)

    return UserGenerateLockfiles(jvm_lockfile_requests)
Exemple #3
0
    def jvm_lockfile(self, request) -> JVMLockfileFixture:
        mark = request.node.get_closest_marker("jvm_lockfile")

        definition = JVMLockfileFixtureDefinition.from_kwargs(mark.kwargs)

        # Load the lockfile.
        lockfile_path = request.node.path.parent / definition.lockfile_rel_path
        lockfile_contents = lockfile_path.read_bytes()
        lockfile = CoursierResolvedLockfile.from_serialized(lockfile_contents)

        # Check the lockfile's requirements against the requirements in the lockfile.
        # Fail the test if the lockfile needs to be regenerated.
        artifact_reqs = ArtifactRequirements([
            ArtifactRequirement(coordinate)
            for coordinate in definition.coordinates
        ])
        if not lockfile.metadata:
            raise ValueError(
                f"Expected JVM lockfile {definition.lockfile_rel_path} to have metadata."
            )
        if not lockfile.metadata.is_valid_for(artifact_reqs,
                                              LockfileContext.TOOL):
            raise ValueError(
                f"Lockfile fixture {definition.lockfile_rel_path} is not valid. "
                "Please re-generate it using: "
                f"{bin_name()} internal-generate-test-lockfile-fixtures ::")

        return JVMLockfileFixture(lockfile, lockfile_contents.decode(),
                                  artifact_reqs)
Exemple #4
0
async def resolve_scala_library_for_resolve(
    request: ScalaRuntimeForResolveRequest,
    jvm_artifact_targets: AllJvmArtifactTargets,
    jvm: JvmSubsystem,
    scala_subsystem: ScalaSubsystem,
) -> ScalaRuntimeForResolve:

    scala_version = scala_subsystem.version_for_resolve(request.resolve_name)

    for tgt in jvm_artifact_targets:
        if tgt[JvmResolveField].normalized_value(jvm) != request.resolve_name:
            continue

        artifact = ArtifactRequirement.from_jvm_artifact_target(tgt)
        if (
            artifact.coordinate.group != SCALA_LIBRARY_GROUP
            or artifact.coordinate.artifact != SCALA_LIBRARY_ARTIFACT
        ):
            continue

        if artifact.coordinate.version != scala_version:
            raise ConflictingScalaLibraryVersionInResolveError(
                request.resolve_name, scala_version, artifact.coordinate
            )

        return ScalaRuntimeForResolve(tgt.address)

    raise MissingScalaLibraryInResolveError(request.resolve_name, scala_version)
Exemple #5
0
async def gather_lockfile_fixtures() -> RenderedJVMLockfileFixtures:
    configs = await Get(CollectedJVMLockfileFixtureConfigs,
                        CollectFixtureConfigsRequest())
    rendered_fixtures = []
    for config in configs:
        artifact_reqs = ArtifactRequirements([
            ArtifactRequirement(coordinate)
            for coordinate in config.definition.coordinates
        ])
        lockfile = await Get(CoursierResolvedLockfile, ArtifactRequirements,
                             artifact_reqs)
        serialized_lockfile = JVMLockfileMetadata.new(
            artifact_reqs
        ).add_header_to_lockfile(
            lockfile.to_serialized(),
            regenerate_command=
            f"{bin_name()} {InternalGenerateTestLockfileFixturesSubsystem.name} ::",
            delimeter="#",
        )

        lockfile_path = os.path.join(os.path.dirname(config.test_file_path),
                                     config.definition.lockfile_rel_path)
        rendered_fixtures.append(
            RenderedJVMLockfileFixture(
                content=serialized_lockfile,
                path=lockfile_path,
            ))

    return RenderedJVMLockfileFixtures(rendered_fixtures)
Exemple #6
0
def test_generate_lockfile(rule_runner: RuleRunner) -> None:
    artifacts = ArtifactRequirements([
        ArtifactRequirement(Coordinate("org.hamcrest", "hamcrest-core", "1.3"))
    ])
    result = rule_runner.request(
        GenerateLockfileResult,
        [
            GenerateJvmLockfile(artifacts=artifacts,
                                resolve_name="test",
                                lockfile_dest="lock.txt")
        ],
    )
    digest_contents = rule_runner.request(DigestContents, [result.digest])
    assert len(digest_contents) == 1

    expected = CoursierResolvedLockfile(
        entries=(CoursierLockfileEntry(
            coord=Coordinate(
                group="org.hamcrest",
                artifact="hamcrest-core",
                version="1.3",
            ),
            file_name="org.hamcrest_hamcrest-core_1.3.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                fingerprint=
                "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9",
                serialized_bytes_length=45024,
            ),
        ), ),
        metadata=JVMLockfileMetadata.new(artifacts),
    )
    assert CoursierResolvedLockfile.from_serialized(
        digest_contents[0].content) == expected
Exemple #7
0
def test_vintage_success_with_dep(rule_runner: RuleRunner) -> None:
    rule_runner.write_files({
        "3rdparty/jvm/default.lock":
        JUNIT4_RESOLVED_LOCKFILE.serialize(
            [ArtifactRequirement(coordinate=JUNIT_COORD)]),
        "BUILD":
        dedent(f"""\
                jvm_artifact(
                  name = 'junit_junit',
                  group = '{JUNIT_COORD.group}',
                  artifact = '{JUNIT_COORD.artifact}',
                  version = '{JUNIT_COORD.version}',
                )

                java_sources(
                    name='example-lib',
                )

                junit_tests(
                    name = 'example-test',

                    dependencies = [
                        ':junit_junit',
                        '//:example-lib',
                    ],
                )
                """),
        "ExampleLib.java":
        dedent("""
                package org.pantsbuild.example.lib;

                public class ExampleLib {
                    public static String hello() {
                        return "Hello!";
                    }
                }
                """),
        "ExampleTest.java":
        dedent("""
                package org.pantsbuild.example;

                import org.pantsbuild.example.lib.ExampleLib;
                import junit.framework.TestCase;

                public class ExampleTest extends TestCase {
                   public void testHello(){
                      assertTrue(ExampleLib.hello() == "Hello!");
                   }
                }
                """),
    })

    test_result = run_junit_test(rule_runner, "example-test",
                                 "ExampleTest.java")

    assert test_result.exit_code == 0
    assert re.search(r"Finished:\s+testHello", test_result.stdout) is not None
    assert re.search(r"1 tests successful", test_result.stdout) is not None
    assert re.search(r"1 tests found", test_result.stdout) is not None
Exemple #8
0
def _write_file_dependencies(rule_runner: RuleRunner, junit_deps: Iterable[str], path_to_read: str):
    junit_deps_str = ", ".join(f"'{i}'" for i in junit_deps)

    rule_runner.write_files(
        {
            "3rdparty/jvm/default.lock": JUNIT4_RESOLVED_LOCKFILE.serialize(
                [ArtifactRequirement(coordinate=JUNIT_COORD)]
            ),
            "BUILD": dedent(
                f"""\
                jvm_artifact(
                  name = 'junit_junit',
                  group = '{JUNIT_COORD.group}',
                  artifact = '{JUNIT_COORD.artifact}',
                  version = '{JUNIT_COORD.version}',
                )
                junit_tests(
                    name='example-test',
                    dependencies= [
                        ':junit_junit',
                        {junit_deps_str}
                    ],
                )
                file(
                    name="duck",
                    source="ducks.txt",
                )
                files(
                    name="ducks",
                    sources=["*.txt"],
                )
                relocated_files(
                    name="relocated_ducks",
                    files_targets=[":duck"],
                    src="",
                    dest="ducks",
                )
                """
            ),
            "SimpleTest.java": dedent(
                f"""
                package org.pantsbuild.example;

                import junit.framework.TestCase;
                import java.nio.file.Files;
                import java.nio.file.Path;

                public class SimpleTest extends TestCase {{
                   public void testHello() throws Exception {{
                        assertEquals("lol ducks", Files.readString(Path.of("{path_to_read}")));
                   }}
                }}
                """
            ),
            "ducks.txt": "lol ducks",
        }
    )
Exemple #9
0
def test_resolve_with_a_jar(rule_runner: RuleRunner) -> None:

    rule_runner.write_files({
        "BUILD":
        textwrap.dedent("""\
            jvm_artifact(
              name="jeremy",
              group="jeremy",
              artifact="jeremy",
              version="4.13.2",
              jar="jeremy.jar",
            )
            """),
        "jeremy.jar":
        "hello dave",
    })

    targets = rule_runner.request(Targets, [
        RawSpecs(recursive_globs=(RecursiveGlobSpec(""), ),
                 description_of_origin="tests")
    ])
    jeremy_target = targets[0]

    jar_field = jeremy_target[JvmArtifactJarSourceField]

    requirement = ArtifactRequirement(
        coordinate=Coordinate(
            group="jeremy",
            artifact="jeremy",
            version="4.13.2",
        ),
        jar=jar_field,
    )

    resolved_lockfile = rule_runner.request(
        CoursierResolvedLockfile,
        [ArtifactRequirements([requirement])],
    )

    coordinate = requirement.coordinate
    assert resolved_lockfile == CoursierResolvedLockfile(
        entries=(CoursierLockfileEntry(
            coord=Coordinate(group=coordinate.group,
                             artifact=coordinate.artifact,
                             version=coordinate.version),
            file_name=
            f"{coordinate.group}_{coordinate.artifact}_{coordinate.version}.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                fingerprint=
                "55b9afa8d7776cd6c318eec51f506e9c7f66c247dcec343d4667f5f269714f86",
                serialized_bytes_length=10,
            ),
            pants_address=jar_field.address.spec,
        ), ))
Exemple #10
0
def test_jupiter_simple_failure(rule_runner: RuleRunner) -> None:
    rule_runner.write_files(
        {
            "3rdparty/jvm/default.lock": JUNIT5_RESOLVED_LOCKFILE.serialize(
                [ArtifactRequirement(coordinate=JUPITER_COORD)]
            ),
            "BUILD": dedent(
                f"""\
                jvm_artifact(
                  name = 'org.junit.jupiter_junit-jupiter-api',
                  group = '{JUPITER_COORD.group}',
                  artifact = '{JUPITER_COORD.artifact}',
                  version = '{JUPITER_COORD.version}',
                )
                junit_tests(
                    name='example-test',

                    dependencies= [
                        ':org.junit.jupiter_junit-jupiter-api',
                    ],
                )
                """
            ),
            "SimpleTest.java": dedent(
                """
                package org.pantsbuild.example;

                import static org.junit.jupiter.api.Assertions.assertEquals;
                import org.junit.jupiter.api.Test;

                class SimpleTest {
                    @Test
                    void testHello(){
                      assertEquals("Goodbye!", "Hello!");
                   }
                }
                """
            ),
        }
    )

    test_result = run_junit_test(rule_runner, "example-test", "SimpleTest.java")

    assert test_result.exit_code == 1
    assert test_result.xml_results and test_result.xml_results.files
    assert (
        re.search(
            r"Finished:.*?testHello.*?Exception: org.opentest4j.AssertionFailedError: expected: <Goodbye!> but was: <Hello!>",
            test_result.stdout,
            re.DOTALL,
        )
        is not None
    )
    assert re.search(r"1 tests failed", test_result.stdout) is not None
    assert re.search(r"1 tests found", test_result.stdout) is not None
Exemple #11
0
def test_vintage_simple_failure(rule_runner: RuleRunner) -> None:
    rule_runner.write_files(
        {
            "3rdparty/jvm/default.lock": JUNIT4_RESOLVED_LOCKFILE.serialize(
                [ArtifactRequirement(coordinate=JUNIT_COORD)]
            ),
            "BUILD": dedent(
                f"""\
                jvm_artifact(
                  name = 'junit_junit',
                  group = '{JUNIT_COORD.group}',
                  artifact = '{JUNIT_COORD.artifact}',
                  version = '{JUNIT_COORD.version}',
                )
                junit_tests(
                    name='example-test',

                    dependencies= [
                        ':junit_junit',
                    ],
                )
                """
            ),
            "SimpleTest.java": dedent(
                """
                package org.pantsbuild.example;

                import org.junit.Test;
                import static org.junit.Assert.*;

                public class SimpleTest {
                   @Test
                   public void helloTest(){
                      assertTrue("Goodbye!" == "Hello!");
                   }
                }
                """
            ),
        }
    )

    test_result = run_junit_test(rule_runner, "example-test", "SimpleTest.java")

    assert test_result.exit_code == 1
    assert (
        re.search(
            r"Finished:.*?helloTest.*?Exception: java.lang.AssertionError",
            test_result.stdout,
            re.DOTALL,
        )
        is not None
    )
    assert re.search(r"1 tests failed", test_result.stdout) is not None
    assert re.search(r"1 tests found", test_result.stdout) is not None
Exemple #12
0
async def gather_coordinates_for_jvm_lockfile(
    request: GatherJvmCoordinatesRequest, ) -> ArtifactRequirements:
    # Separate `artifact_inputs` by whether the strings parse as an `Address` or not.
    requirements: set[ArtifactRequirement] = set()
    candidate_address_inputs: set[AddressInput] = set()
    bad_artifact_inputs = []
    for artifact_input in request.artifact_inputs:
        # Try parsing as a `Coordinate` first since otherwise `AddressInput.parse` will try to see if the
        # group name is a file on disk.
        if 2 <= artifact_input.count(":") <= 3:
            try:
                maybe_coord = Coordinate.from_coord_str(
                    artifact_input).as_requirement()
                requirements.add(maybe_coord)
                continue
            except Exception:
                pass

        try:
            address_input = AddressInput.parse(
                artifact_input,
                description_of_origin=f"the option `{request.option_name}`")
            candidate_address_inputs.add(address_input)
        except Exception:
            bad_artifact_inputs.append(artifact_input)

    if bad_artifact_inputs:
        raise ValueError(
            "The following values could not be parsed as an address nor as a JVM coordinate string. "
            f"The problematic inputs supplied to the `{request.option_name}` option were: "
            f"{', '.join(bad_artifact_inputs)}.")

    # Gather coordinates from the provided addresses.
    addresses = await MultiGet(
        Get(Address, AddressInput, ai) for ai in candidate_address_inputs)
    all_supplied_targets = await Get(Targets, Addresses(addresses))
    other_targets = []
    for tgt in all_supplied_targets:
        if JvmArtifactFieldSet.is_applicable(tgt):
            requirements.add(ArtifactRequirement.from_jvm_artifact_target(tgt))
        else:
            other_targets.append(tgt)

    if other_targets:
        raise ValueError(
            softwrap(f"""
                The following addresses reference targets that are not `jvm_artifact` targets.
                Please only supply the addresses of `jvm_artifact` for the `{request.option_name}`
                option. The problematic addresses are: {', '.join(str(tgt.address) for tgt in other_targets)}.
                """))

    return ArtifactRequirements(requirements)
Exemple #13
0
def test_vintage_scala_simple_success(rule_runner: RuleRunner) -> None:
    rule_runner.write_files(
        {
            "3rdparty/jvm/default.lock": JUNIT4_RESOLVED_LOCKFILE.serialize(
                [ArtifactRequirement(coordinate=JUNIT_COORD)]
            ),
            "BUILD": dedent(
                f"""\
                jvm_artifact(
                  name = 'junit_junit',
                  group = '{JUNIT_COORD.group}',
                  artifact = '{JUNIT_COORD.artifact}',
                  version = '{JUNIT_COORD.version}',
                )

                scala_junit_tests(
                    name='example-test',
                    dependencies= [
                        ':junit_junit',
                    ],
                )
                """
            ),
            "SimpleTest.scala": dedent(
                """
                package org.pantsbuild.example

                import junit.framework.TestCase
                import junit.framework.Assert._

                class SimpleTest extends TestCase {
                   def testHello(): Unit = {
                      assertTrue("Hello!" == "Hello!")
                   }
                }
                """
            ),
        }
    )

    test_result = run_junit_test(rule_runner, "example-test", "SimpleTest.scala")

    assert test_result.exit_code == 0
    assert re.search(r"Finished:\s+testHello", test_result.stdout) is not None
    assert re.search(r"1 tests successful", test_result.stdout) is not None
    assert re.search(r"1 tests found", test_result.stdout) is not None
Exemple #14
0
async def collect_thirdparty_modules(
    request: ThirdpartyModulesRequest,
    classpath_entry_request: ClasspathEntryRequestFactory,
) -> ThirdpartyModules:
    coarsened_targets = await Get(CoarsenedTargets, Addresses,
                                  request.addresses)
    resolve = await Get(CoursierResolveKey, CoarsenedTargets,
                        coarsened_targets)
    lockfile = await Get(CoursierResolvedLockfile, CoursierResolveKey, resolve)

    applicable_lockfile_entries: dict[CoursierLockfileEntry,
                                      CoarsenedTarget] = {}
    for ct in coarsened_targets.coarsened_closure():
        for tgt in ct.members:
            if not JvmArtifactFieldSet.is_applicable(tgt):
                continue

            artifact_requirement = ArtifactRequirement.from_jvm_artifact_target(
                tgt)
            entry = get_entry_for_coord(lockfile,
                                        artifact_requirement.coordinate)
            if not entry:
                _logger.warning(
                    f"No lockfile entry for {artifact_requirement.coordinate} in resolve {resolve.name}."
                )
                continue
            applicable_lockfile_entries[entry] = ct

    classpath_entries = await MultiGet(
        Get(
            ClasspathEntry,
            ClasspathEntryRequest,
            classpath_entry_request.for_targets(component=target,
                                                resolve=resolve),
        ) for target in applicable_lockfile_entries.values())

    resolve_digest = await Get(
        Digest, MergeDigests(cpe.digest for cpe in classpath_entries))

    return ThirdpartyModules(
        resolve,
        dict(zip(applicable_lockfile_entries, classpath_entries)),
        resolve_digest,
    )
Exemple #15
0
def test_resolve_with_broken_url(rule_runner: RuleRunner) -> None:

    coordinate = ArtifactRequirement(
        coordinate=Coordinate(
            group="org.hamcrest",
            artifact="hamcrest-core",
            version=
            "1.3_inexplicably_wrong",  # if the group/artifact/version is real, coursier will fallback
        ),
        url="https://this_url_does_not_work",
    )

    expected_exception_msg = r".*this_url_does_not_work not found under https.*"

    with pytest.raises(ExecutionError, match=expected_exception_msg):
        rule_runner.request(
            CoursierResolvedLockfile,
            [ArtifactRequirements([coordinate])],
        )
Exemple #16
0
def find_jvm_artifacts_or_raise(
    required_coordinates: Iterable[Coordinate | UnversionedCoordinate],
    resolve: str,
    jvm_artifact_targets: AllJvmArtifactTargets,
    jvm: JvmSubsystem,
) -> frozenset[Address]:
    remaining_coordinates: set[Coordinate | UnversionedCoordinate] = set(
        required_coordinates)

    addresses: set[Address] = set()
    for tgt in jvm_artifact_targets:
        if tgt[JvmResolveField].normalized_value(jvm) != resolve:
            continue

        artifact = ArtifactRequirement.from_jvm_artifact_target(tgt)
        found_coordinates: set[Coordinate | UnversionedCoordinate] = set()
        for coordinate in remaining_coordinates:
            if isinstance(coordinate, Coordinate):
                if (artifact.coordinate.group != coordinate.group or
                        artifact.coordinate.artifact != coordinate.artifact):
                    continue
                if artifact.coordinate.version != coordinate.version:
                    raise ConflictingJvmArtifactVersion(
                        group=coordinate.group,
                        artifact=coordinate.artifact,
                        required_version=coordinate.version,
                        found_coordinate=artifact.coordinate,
                    )
            elif isinstance(coordinate, UnversionedCoordinate):
                if (artifact.coordinate.group != coordinate.group or
                        artifact.coordinate.artifact != coordinate.artifact):
                    continue

            found_coordinates.add(coordinate)

        if found_coordinates:
            remaining_coordinates.difference_update(found_coordinates)
            addresses.add(tgt.address)

    if remaining_coordinates:
        raise MissingJvmArtifacts(remaining_coordinates)

    return frozenset(addresses)
Exemple #17
0
async def fetch_with_coursier(
        request: CoursierFetchRequest) -> FallibleClasspathEntry:
    # TODO: Loading this per JvmArtifact.
    lockfile = await Get(CoursierResolvedLockfile, CoursierResolveKey,
                         request.resolve)

    requirement = ArtifactRequirement.from_jvm_artifact_target(
        request.component.representative)

    if lockfile.metadata and not lockfile.metadata.is_valid_for(
        [requirement], LockfileContext.USER):
        raise ValueError(
            f"Requirement `{requirement.to_coord_arg_str()}` has changed since the lockfile "
            f"for {request.resolve.path} was generated. Run `{bin_name()} generate-lockfiles` to update your "
            "lockfile based on the new requirements.")

    # All of the transitive dependencies are exported.
    # TODO: Expose an option to control whether this exports only the root, direct dependencies,
    # transitive dependencies, etc.
    assert len(request.component.members
               ) == 1, "JvmArtifact does not have dependencies."
    root_entry, transitive_entries = lockfile.dependencies(
        request.resolve,
        requirement.coordinate,
    )

    classpath_entries = await MultiGet(
        Get(ClasspathEntry, CoursierLockfileEntry, entry)
        for entry in (root_entry, *transitive_entries))
    exported_digest = await Get(
        Digest, MergeDigests(cpe.digest for cpe in classpath_entries))

    return FallibleClasspathEntry(
        description=str(request.component),
        result=CompileResult.SUCCEEDED,
        output=ClasspathEntry.merge(exported_digest, classpath_entries),
        exit_code=0,
    )
Exemple #18
0
def test_resolve_with_working_url(rule_runner: RuleRunner) -> None:

    requirement = ArtifactRequirement(
        coordinate=Coordinate(
            group="apache-commons-local",
            artifact="commons-collections",
            version="1.0.0_JAR_LOCAL",
        ),
        url=
        "https://repo1.maven.org/maven2/org/apache/commons/commons-collections4/4.2/commons-collections4-4.2.jar",
    )

    resolved_lockfile = rule_runner.request(
        CoursierResolvedLockfile,
        [ArtifactRequirements([requirement])],
    )

    coordinate = requirement.coordinate

    assert resolved_lockfile == CoursierResolvedLockfile(
        entries=(CoursierLockfileEntry(
            coord=Coordinate(group=coordinate.group,
                             artifact=coordinate.artifact,
                             version=coordinate.version),
            file_name=
            f"{coordinate.group}_{coordinate.artifact}_{coordinate.version}.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                fingerprint=
                "6a594721d51444fd97b3eaefc998a77f606dedb03def494f74755aead3c9df3e",
                serialized_bytes_length=752798,
            ),
            remote_url=requirement.url,
            pants_address=None,
        ), ))
Exemple #19
0
def test_compile_with_maven_deps(rule_runner: RuleRunner) -> None:
    joda_coord = Coordinate(group="joda-time",
                            artifact="joda-time",
                            version="2.10.10")
    scala_library_coord = Coordinate(group="org.scala-lang",
                                     artifact="scala-library",
                                     version="2.13.6")
    resolved_joda_lockfile = TestCoursierWrapper.new(entries=(
        CoursierLockfileEntry(
            coord=joda_coord,
            file_name="joda-time-2.10.10.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                fingerprint=
                "dd8e7c92185a678d1b7b933f31209b6203c8ffa91e9880475a1be0346b9617e3",
                serialized_bytes_length=644419,
            ),
        ),
        CoursierLockfileEntry(
            coord=scala_library_coord,
            file_name="org.scala-lang_scala-library_2.13.6.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a",
                5955737,
            ),
        ),
    ))
    rule_runner.write_files({
        "BUILD":
        dedent(f"""\
                jvm_artifact(
                    name = "joda-time_joda-time",
                    group = "{joda_coord.group}",
                    artifact = "{joda_coord.artifact}",
                    version = "{joda_coord.version}",
                )
                scala_sources(
                    name = 'main',
                    dependencies = [":joda-time_joda-time"],
                )
                """),
        "3rdparty/jvm/BUILD":
        DEFAULT_SCALA_LIBRARY_TARGET,
        "3rdparty/jvm/default.lock":
        resolved_joda_lockfile.serialize([
            ArtifactRequirement(joda_coord),
            ArtifactRequirement(scala_library_coord)
        ]),
        "Example.scala":
        dedent("""
                package org.pantsbuild.example

                import org.joda.time.DateTime

                object Main {
                    def main(args: Array[String]): Unit = {
                        val dt = new DateTime()
                        println(dt.getYear)
                    }
                }
                """),
    })
    classpath = rule_runner.request(
        RenderedClasspath,
        [
            CompileScalaSourceRequest(
                component=expect_single_expanded_coarsened_target(
                    rule_runner, Address(spec_path="", target_name="main")),
                resolve=make_resolve(rule_runner),
            )
        ],
    )
    assert classpath.content == {
        ".Example.scala.main.scalac.jar": {
            "META-INF/MANIFEST.MF",
            "org/pantsbuild/example/Main$.class",
            "org/pantsbuild/example/Main.class",
        }
    }
Exemple #20
0

DEFAULT_LOCKFILE = TestCoursierWrapper(
    CoursierResolvedLockfile((CoursierLockfileEntry(
        coord=Coordinate(group="org.scala-lang",
                         artifact="scala-library",
                         version="2.13.6"),
        file_name="org.scala-lang_scala-library_2.13.6.jar",
        direct_dependencies=Coordinates(),
        dependencies=Coordinates(),
        file_digest=FileDigest(
            "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a",
            5955737),
    ), ))).serialize([
        ArtifactRequirement(coordinate=Coordinate(group="org.scala-lang",
                                                  artifact="scala-library",
                                                  version="2.13.6"))
    ])

DEFAULT_SCALA_LIBRARY_TARGET = textwrap.dedent("""\
    jvm_artifact(
      name="org.scala-lang_scala-library_2.13.6",
      group="org.scala-lang",
      artifact="scala-library",
      version="2.13.6",
    )
    """)

SCALA_LIB_SOURCE = dedent("""
    package org.pantsbuild.example.lib
Exemple #21
0
    coord=Coordinate(
        group="com.thesamet.scalapb",
        artifact="scalapb-runtime_2.13",
        version="0.11.6",
    ),
    file_name="scalapb-runtime_2.13-0.11.6.jar",
    direct_dependencies=Coordinates([]),
    dependencies=Coordinates([]),
    file_digest=FileDigest(
        "439b613f40b9ac43db4d68de5bef36befc56393d9c9cd002e2b965ce94f6f793",
        2426575,
    ),
), ), ).serialize([
    ArtifactRequirement(
        Coordinate(
            group="com.thesamet.scalapb",
            artifact="scalapb-runtime_2.13",
            version="0.11.6",
        ))
])


@pytest.fixture
def rule_runner() -> RuleRunner:
    rule_runner = RuleRunner(
        rules=[
            *config_files.rules(),
            *classpath.rules(),
            *coursier_fetch_rules(),
            *coursier_setup_rules(),
            *external_tool_rules(),
            *source_files.rules(),
Exemple #22
0
def test_jupiter_success_with_dep(rule_runner: RuleRunner) -> None:
    rule_runner.write_files({
        "3rdparty/jvm/default.lock":
        JUNIT5_RESOLVED_LOCKFILE.serialize(
            [ArtifactRequirement(coordinate=JUPITER_COORD)]),
        "BUILD":
        dedent(f"""\
                jvm_artifact(
                  name = 'org.junit.jupiter_junit-jupiter-api',
                  group = '{JUPITER_COORD.group}',
                  artifact = '{JUPITER_COORD.artifact}',
                  version = '{JUPITER_COORD.version}',
                )

                java_sources(
                    name='example-lib',

                )

                junit_tests(
                    name = 'example-test',

                    dependencies = [
                        ':org.junit.jupiter_junit-jupiter-api',
                        '//:example-lib',
                    ],
                )
                """),
        "ExampleLib.java":
        dedent("""
                package org.pantsbuild.example.lib;

                public class ExampleLib {
                    public static String hello() {
                        return "Hello!";
                    }
                }
                """),
        "SimpleTest.java":
        dedent("""
                package org.pantsbuild.example;

                import static org.junit.jupiter.api.Assertions.assertEquals;
                import org.junit.jupiter.api.Test;
                import org.pantsbuild.example.lib.ExampleLib;

                class SimpleTest {
                    @Test
                    void testHello(){
                      assertEquals(ExampleLib.hello(), "Hello!");
                   }
                }
                """),
    })

    test_result = run_junit_test(rule_runner, "example-test",
                                 "SimpleTest.java")

    assert test_result.exit_code == 0
    assert re.search(r"Finished:\s+testHello", test_result.stdout) is not None
    assert re.search(r"1 tests successful", test_result.stdout) is not None
    assert re.search(r"1 tests found", test_result.stdout) is not None
Exemple #23
0
def test_basic_war_packaging(rule_runner: RuleRunner) -> None:
    servlet_coordinate = Coordinate(group="javax.servlet", artifact="servlet-api", version="2.5")
    rule_runner.write_files(
        {
            "war-test/BUILD": textwrap.dedent(
                """\
            jvm_artifact(
              name="javax.servlet_servlet-api",
              group="javax.servlet",
              artifact="servlet-api",
              version="2.5",
            )

            jvm_war(
              name="war",
              dependencies=[":javax.servlet_servlet-api"],
              descriptor="web.xml",
              content=[":html"],
            )

            files(name="orig_html", sources=["*.html"])
            relocated_files(
              name="html",
              files_targets=[":orig_html"],
              src="war-test",
              dest="",
            )
            """
            ),
            "war-test/web.xml": textwrap.dedent(
                """\
            <web-app>
            </web-app>
            """
            ),
            "war-test/index.html": textwrap.dedent(
                """\
            <html>
            <body>
            <p>This is the home page.</p>
            </html>
            """
            ),
            "3rdparty/jvm/default.lock": TestCoursierWrapper.new(
                (
                    CoursierLockfileEntry(
                        coord=servlet_coordinate,
                        file_name="javax.servlet_servlet-api_2.5.jar",
                        direct_dependencies=Coordinates(),
                        dependencies=Coordinates(),
                        file_digest=FileDigest(
                            "c658ea360a70faeeadb66fb3c90a702e4142a0ab7768f9ae9828678e0d9ad4dc",
                            105112,
                        ),
                    ),
                ),
            ).serialize([ArtifactRequirement(servlet_coordinate)]),
        }
    )

    war_tgt = rule_runner.get_target(Address("war-test", target_name="war"))
    built_package = rule_runner.request(BuiltPackage, [PackageWarFileFieldSet.create(war_tgt)])
    assert built_package.digest != EMPTY_DIGEST
    assert len(built_package.artifacts) == 1
    package = built_package.artifacts[0]
    assert package.relpath == "war-test/war.war"

    contents = rule_runner.request(DigestContents, [built_package.digest])
    assert len(contents) == 1
    zip_bytes = BytesIO(contents[0].content)
    with zipfile.ZipFile(zip_bytes, "r") as zf:
        files = zf.filelist
    filenames = [f.filename for f in files]
    assert sorted(filenames) == [
        "WEB-INF/",
        "WEB-INF/classes/",
        "WEB-INF/lib/",
        "WEB-INF/lib/javax.servlet_servlet-api_2.5.jar",
        "WEB-INF/web.xml",
        "index.html",
    ]
Exemple #24
0
async def scala_bsp_dependency_modules(
    request: ScalaBSPDependencyModulesRequest,
    build_root: BuildRoot,
) -> BSPDependencyModulesResult:
    coarsened_targets = await Get(
        CoarsenedTargets, Addresses([fs.address for fs in request.field_sets]))
    resolve = await Get(CoursierResolveKey, CoarsenedTargets,
                        coarsened_targets)
    lockfile = await Get(CoursierResolvedLockfile, CoursierResolveKey, resolve)

    # TODO: Can this use ClasspathEntryRequest?
    transitive_targets = await Get(
        TransitiveTargets,
        TransitiveTargetsRequest(roots=[
            tgt.address for coarsened_target in coarsened_targets
            for tgt in coarsened_target.members
        ]),
    )

    artifact_requirements = [
        ArtifactRequirement.from_jvm_artifact_target(tgt)
        for tgt in transitive_targets.closure
        if JvmArtifactFieldSet.is_applicable(tgt)
    ]

    applicable_lockfile_entries: set[CoursierLockfileEntry] = set()
    for artifact_requirement in artifact_requirements:
        entry = get_entry_for_coord(lockfile, artifact_requirement.coordinate)
        if not entry:
            _logger.warning(
                f"No lockfile entry for {artifact_requirement.coordinate} in resolve {resolve.name}."
            )
            continue
        applicable_lockfile_entries.add(entry)

    resolve_digest = await Get(
        Digest,
        CreateDigest([
            FileEntry(entry.file_name, entry.file_digest)
            for entry in applicable_lockfile_entries
        ]),
    )

    resolve_digest = await Get(
        Digest, AddPrefix(resolve_digest, f"jvm/resolves/{resolve.name}/lib"))

    modules = [
        DependencyModule(
            name=f"{entry.coord.group}:{entry.coord.artifact}",
            version=entry.coord.version,
            data=MavenDependencyModule(
                organization=entry.coord.group,
                name=entry.coord.artifact,
                version=entry.coord.version,
                scope=None,
                artifacts=(MavenDependencyModuleArtifact(
                    uri=build_root.pathlib_path.joinpath(
                        f".pants.d/bsp/jvm/resolves/{resolve.name}/lib/{entry.file_name}"
                    ).as_uri()), ),
            ),
        ) for entry in applicable_lockfile_entries
    ]

    return BSPDependencyModulesResult(
        modules=tuple(modules),
        digest=resolve_digest,
    )
Exemple #25
0
def test_compile_with_local_scalac_plugin(rule_runner: RuleRunner) -> None:
    acyclic_coord = Coordinate(group="com.lihaoyi",
                               artifact="acyclic_2.13",
                               version="0.2.1")
    scala_library_coord = Coordinate(group="org.scala-lang",
                                     artifact="scala-library",
                                     version="2.13.6")
    rule_runner.write_files({
        "lib/BUILD":
        dedent(f"""\
                jvm_artifact(
                    name = "acyclic_lib",
                    group = "{acyclic_coord.group}",
                    artifact = "{acyclic_coord.artifact}",
                    version = "{acyclic_coord.version}",
                    packages=["acyclic.**"],
                )

                scalac_plugin(
                    name = "acyclic",
                    # TODO: Support relative addresses.
                    artifact = "lib:acyclic_lib",
                )

                scala_sources(
                    scalac_plugins=["acyclic"],
                )
                """),
        "3rdparty/jvm/BUILD":
        DEFAULT_SCALA_LIBRARY_TARGET,
        "3rdparty/jvm/default.lock":
        TestCoursierWrapper.new(entries=(
            CoursierLockfileEntry(
                coord=acyclic_coord,
                file_name="acyclic_2.13-0.2.1.jar",
                direct_dependencies=Coordinates([]),
                dependencies=Coordinates([]),
                file_digest=FileDigest(
                    "4bc4656140ad5e4802fedcdbe920ec7c92dbebf5e76d1c60d35676a314481944",
                    62534,
                ),
            ),
            CoursierLockfileEntry(
                coord=scala_library_coord,
                file_name="org.scala-lang_scala-library_2.13.6.jar",
                direct_dependencies=Coordinates([]),
                dependencies=Coordinates([]),
                file_digest=FileDigest(
                    "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a",
                    5955737,
                ),
            ),
        )).serialize([
            ArtifactRequirement(coordinate=acyclic_coord),
            ArtifactRequirement(scala_library_coord),
        ]),
        "3rdparty/jvm/scalac-plugins.lock":
        TestCoursierWrapper.new(entries=(
            CoursierLockfileEntry(
                coord=acyclic_coord,
                file_name="acyclic_2.13-0.2.1.jar",
                direct_dependencies=Coordinates([]),
                dependencies=Coordinates([]),
                file_digest=FileDigest(
                    "4bc4656140ad5e4802fedcdbe920ec7c92dbebf5e76d1c60d35676a314481944",
                    62534,
                ),
            ),
            CoursierLockfileEntry(
                coord=scala_library_coord,
                file_name="org.scala-lang_scala-library_2.13.6.jar",
                direct_dependencies=Coordinates([]),
                dependencies=Coordinates([]),
                file_digest=FileDigest(
                    "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a",
                    5955737,
                ),
            ),
        )).serialize([
            ArtifactRequirement(coordinate=acyclic_coord),
        ]),
        "lib/A.scala":
        dedent("""
                package lib
                import acyclic.file

                class A {
                  val b: B = null
                }
                """),
        "lib/B.scala":
        dedent("""
                package lib

                class B {
                  val a: A = null
                }
                """),
    })
    rule_runner.set_options(
        args=[],
        env_inherit=PYTHON_BOOTSTRAP_ENV,
    )

    request = CompileScalaSourceRequest(
        component=expect_single_expanded_coarsened_target(
            rule_runner, Address(spec_path="lib",
                                 relative_file_path="A.scala")),
        resolve=make_resolve(rule_runner),
    )
    fallible_result = rule_runner.request(FallibleClasspathEntry, [request])
    assert fallible_result.result == CompileResult.FAILED and fallible_result.stderr
    assert "error: Unwanted cyclic dependency" in fallible_result.stderr
Exemple #26
0
def test_compile_with_multiple_scala_versions(rule_runner: RuleRunner) -> None:
    scala_library_coord_2_12 = Coordinate(group="org.scala-lang",
                                          artifact="scala-library",
                                          version="2.12.15")
    scala_library_coord_2_13 = Coordinate(group="org.scala-lang",
                                          artifact="scala-library",
                                          version="2.13.8")
    rule_runner.write_files({
        "BUILD":
        dedent("""\
                scala_sources(
                    name = 'main_2.12',
                    resolve = "scala2.12",
                )
                scala_sources(
                    name = 'main_2.13',
                    resolve = "scala2.13",
                )
                jvm_artifact(
                  name="org.scala-lang_scala-library_2.12.15",
                  group="org.scala-lang",
                  artifact="scala-library",
                  version="2.12.15",
                  resolve="scala2.12",
                )
                jvm_artifact(
                  name="org.scala-lang_scala-library_2.13.8",
                  group="org.scala-lang",
                  artifact="scala-library",
                  version="2.13.8",
                  resolve="scala2.13",
                )
                """),
        "Example.scala":
        SCALA_LIB_SOURCE,
        "3rdparty/jvm/scala2.12.lock":
        TestCoursierWrapper.new(entries=(CoursierLockfileEntry(
            coord=scala_library_coord_2_12,
            file_name="org.scala-lang_scala-library_2.12.15.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                "e518bb640e2175de5cb1f8e326679b8d975376221f1b547757de429bbf4563f0",
                5443542,
            ),
        ), ), ).serialize([ArtifactRequirement(scala_library_coord_2_12)]),
        "3rdparty/jvm/scala2.13.lock":
        TestCoursierWrapper.new(entries=(CoursierLockfileEntry(
            coord=scala_library_coord_2_13,
            file_name="org.scala-lang_scala-library_2.13.8.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                "a0882b82514190c2bac7d1a459872a75f005fc0f3e88b2bc0390367146e35db7",
                6003601,
            ),
        ), ), ).serialize([ArtifactRequirement(scala_library_coord_2_13)]),
    })
    rule_runner.set_options(
        [
            '--scala-version-for-resolve={"scala2.12":"2.12.15","scala2.13":"2.13.8"}',
            '--jvm-resolves={"scala2.12":"3rdparty/jvm/scala2.12.lock","scala2.13":"3rdparty/jvm/scala2.13.lock"}',
        ],
        env_inherit=PYTHON_BOOTSTRAP_ENV,
    )
    classpath_2_12 = rule_runner.request(
        ClasspathEntry,
        [
            CompileScalaSourceRequest(
                component=expect_single_expanded_coarsened_target(
                    rule_runner, Address(spec_path="",
                                         target_name="main_2.12")),
                resolve=make_resolve(rule_runner, "scala2.12",
                                     "3rdparty/jvm/scala2.12.lock"),
            )
        ],
    )
    entries_2_12 = list(ClasspathEntry.closure([classpath_2_12]))
    filenames_2_12 = sorted(
        itertools.chain.from_iterable(entry.filenames
                                      for entry in entries_2_12))
    assert filenames_2_12 == [
        ".Example.scala.main_2.12.scalac.jar",
        "org.scala-lang_scala-library_2.12.15.jar",
    ]

    classpath_2_13 = rule_runner.request(
        ClasspathEntry,
        [
            CompileScalaSourceRequest(
                component=expect_single_expanded_coarsened_target(
                    rule_runner, Address(spec_path="",
                                         target_name="main_2.13")),
                resolve=make_resolve(rule_runner, "scala2.13",
                                     "3rdparty/jvm/scala2.13.lock"),
            )
        ],
    )
    entries_2_13 = list(ClasspathEntry.closure([classpath_2_13]))
    filenames_2_13 = sorted(
        itertools.chain.from_iterable(entry.filenames
                                      for entry in entries_2_13))
    assert filenames_2_13 == [
        ".Example.scala.main_2.13.scalac.jar",
        "org.scala-lang_scala-library_2.13.8.jar",
    ]
Exemple #27
0
def test_compile_with_multiple_scalac_plugins(rule_runner: RuleRunner) -> None:
    better_monadic_coord = Coordinate(group="com.olegpy",
                                      artifact="better-monadic-for_2.13",
                                      version="0.3.1")
    kind_projector_coord = Coordinate(group="org.typelevel",
                                      artifact="kind-projector_2.13.6",
                                      version="0.13.2")
    scala_compiler_coord = Coordinate(group="org.scala-lang",
                                      artifact="scala-compiler",
                                      version="2.13.6")
    scala_library_coord = Coordinate(group="org.scala-lang",
                                     artifact="scala-library",
                                     version="2.13.6")
    scala_reflect_coord = Coordinate(group="org.scala-lang",
                                     artifact="scala-reflect",
                                     version="2.13.6")
    jna_coord = Coordinate(group="net.java.dev.jna",
                           artifact="jna",
                           version="5.3.1")
    jline_coord = Coordinate(group="org.jline",
                             artifact="jline",
                             version="3.19.0")
    rule_runner.write_files({
        "lib/BUILD":
        dedent(f"""\
                scala_sources()

                jvm_artifact(
                    name="kind-projector-lib",
                    group="{kind_projector_coord.group}",
                    artifact="{kind_projector_coord.artifact}",
                    version="{kind_projector_coord.version}",
                )

                scalac_plugin(
                    name="kind-projector",
                    plugin_name="kind-projector",
                    # TODO: Support relative addresses.
                    artifact="lib:kind-projector-lib",
                )

                jvm_artifact(
                    name="better-monadic-for-lib",
                    group="{better_monadic_coord.group}",
                    artifact="{better_monadic_coord.artifact}",
                    version="{better_monadic_coord.version}",
                )

                scalac_plugin(
                    name="better-monadic-for",
                    plugin_name="bm4",
                    # TODO: Support relative addresses.
                    artifact="lib:better-monadic-for-lib",
                )
                """),
        "3rdparty/jvm/BUILD":
        DEFAULT_SCALA_LIBRARY_TARGET,
        "3rdparty/jvm/default.lock":
        DEFAULT_LOCKFILE,
        "3rdparty/jvm/scalac-plugins.lock":
        TestCoursierWrapper.new(entries=(
            CoursierLockfileEntry(
                coord=better_monadic_coord,
                file_name="com.olegpy_better-monadic-for_2.13_0.3.1.jar",
                direct_dependencies=Coordinates(
                    [scala_compiler_coord, scala_library_coord]),
                dependencies=Coordinates(
                    [scala_compiler_coord, scala_library_coord]),
                file_digest=FileDigest(
                    "fac649fa7de697d1f98d3f814c4b70f5372c547fa41778383e22cee6c16084f5",
                    130370,
                ),
            ),
            CoursierLockfileEntry(
                coord=jna_coord,
                file_name="net.java.dev.jna_jna_5.3.1.jar",
                direct_dependencies=Coordinates([]),
                dependencies=Coordinates([]),
                file_digest=FileDigest(
                    "01cb505c0698d0f7acf3524c7e73acb7dc424a5bae5e9c86ce44075ab32bc4ee",
                    1505196,
                ),
            ),
            CoursierLockfileEntry(
                coord=jline_coord,
                file_name="org.jline_jline_3.19.0.jar",
                direct_dependencies=Coordinates([]),
                dependencies=Coordinates([]),
                file_digest=FileDigest(
                    "c99ddcfa5431cab88d1cd40fd63bec6ab5a3fe2e83877051198539af66592a46",
                    987021,
                ),
            ),
            CoursierLockfileEntry(
                coord=scala_compiler_coord,
                file_name="org.scala-lang_scala-compiler_2.13.6.jar",
                direct_dependencies=Coordinates([
                    jna_coord, jline_coord, scala_library_coord,
                    scala_reflect_coord
                ]),
                dependencies=Coordinates([
                    jna_coord, jline_coord, scala_library_coord,
                    scala_reflect_coord
                ]),
                file_digest=FileDigest(
                    "310d263d622a3d016913e94ee00b119d270573a5ceaa6b21312d69637fd9eec1",
                    12010571,
                ),
            ),
            CoursierLockfileEntry(
                coord=scala_library_coord,
                file_name="org.scala-lang_scala-library_2.13.6.jar",
                direct_dependencies=Coordinates([]),
                dependencies=Coordinates([]),
                file_digest=FileDigest(
                    "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a",
                    5955737,
                ),
            ),
            CoursierLockfileEntry(
                coord=scala_reflect_coord,
                file_name="org.scala-lang_scala-reflect_2.13.6.jar",
                direct_dependencies=Coordinates([scala_library_coord]),
                dependencies=Coordinates([scala_library_coord]),
                file_digest=FileDigest(
                    "f713593809b387c60935bb9a940dfcea53bd0dbf8fdc8d10739a2896f8ac56fa",
                    3769997,
                ),
            ),
            CoursierLockfileEntry(
                coord=kind_projector_coord,
                file_name="org.typelevel_kind-projector_2.13.6_0.13.2.jar",
                direct_dependencies=Coordinates(
                    [scala_compiler_coord, scala_library_coord]),
                dependencies=Coordinates([
                    scala_compiler_coord,
                    scala_reflect_coord,
                    scala_library_coord,
                    jna_coord,
                    jline_coord,
                ]),
                file_digest=FileDigest(
                    "3d713d02bbe0d52b01c22ac11a50970460114f32b339f3ea429d52461d6c39ff",
                    44257,
                ),
            ),
        )).serialize([
            ArtifactRequirement(better_monadic_coord),
            ArtifactRequirement(kind_projector_coord),
        ]),
        "lib/A.scala":
        dedent("""\
                trait Functor[F[_]] {
                  def map[A, B](fa: F[A])(f: A => B): F[B]
                }

                object KindProjectorTest {
                  implicit def eitherFunctor[E]: Functor[Either[E, *]] = new Functor[Either[E, *]] {
                    def map[A, B](fa: Either[E, A])(f: A => B): Either[E, B] = {
                      fa match {
                        case Left(e) => Left(e)
                        case Right(a) => Right(f(a))
                      }
                    }
                  }
                }

                object BetterMonadicForTest {
                  def example: Option[String] = {
                    case class ImplicitTest(id: String)

                    for {
                      x <- Option(42)
                      implicit0(it: ImplicitTest) <- Option(ImplicitTest("eggs"))
                      _ <- Option("dummy")
                      _ = "dummy"
                      _ = assert(implicitly[ImplicitTest] eq it)
                    } yield "ok"
                  }
                }
                """),
    })
    rule_runner.set_options(
        args=[
            "--scalac-plugins-global=['lib:better-monadic-for', 'lib:kind-projector']",
            "--scalac-plugins-global-lockfile=3rdparty/jvm/scalac-plugins.lock",
        ],
        env_inherit=PYTHON_BOOTSTRAP_ENV,
    )

    request = CompileScalaSourceRequest(
        component=expect_single_expanded_coarsened_target(
            rule_runner, Address(spec_path="lib",
                                 relative_file_path="A.scala")),
        resolve=make_resolve(rule_runner),
    )
    rule_runner.request(RenderedClasspath, [request])
Exemple #28
0
                artifact="libthrift",
                version="0.15.0",
            ),
            file_name="libthrift-0.15.0.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                "e9c47420147cbb87a6df08bc36da04e2be1561967b5ef82d2f3ef9ec090d85d0",
                305670,
            ),
        ),
        # Note: The transitive dependencies of libthrift have been intentionally omitted from this resolve.
    ), ).serialize([
        ArtifactRequirement(
            Coordinate(
                group="org.apache.thrift",
                artifact="libthrift",
                version="0.15.0",
            ))
    ])


@pytest.fixture
def rule_runner() -> RuleRunner:
    return RuleRunner(
        rules=[
            *thrift_rules(),
            *apache_thrift_rules(),
            *apache_thrift_java_rules(),
            *source_files.rules(),
            *source_root.rules(),
            *graph.rules(),
Exemple #29
0
async def coursier_fetch_one_coord(
    request: CoursierLockfileEntry, ) -> ClasspathEntry:
    """Run `coursier fetch --intransitive` to fetch a single artifact.

    This rule exists to permit efficient subsetting of a "global" classpath
    in the form of a lockfile.  Callers can determine what subset of dependencies
    from the lockfile are needed for a given target, then request those
    lockfile entries individually.

    By fetching only one entry at a time, we maximize our cache efficiency.  If instead
    we fetched the entire subset that the caller wanted, there would be a different cache
    key for every possible subset.

    This rule also guarantees exact reproducibility.  If all caches have been
    removed, `coursier fetch` will re-download the artifact, and this rule will
    confirm that what was downloaded matches exactly (by content digest) what
    was specified in the lockfile (what Coursier originally downloaded).
    """

    # Prepare any URL- or JAR-specifying entries for use with Coursier
    req: ArtifactRequirement
    if request.pants_address:
        targets = await Get(
            Targets,
            UnparsedAddressInputs([request.pants_address],
                                  owning_address=None,
                                  description_of_origin="TODO(#14468)"),
        )
        req = ArtifactRequirement(request.coord,
                                  jar=targets[0][JvmArtifactJarSourceField])
    else:
        req = ArtifactRequirement(request.coord, url=request.remote_url)

    coursier_resolve_info = await Get(
        CoursierResolveInfo,
        ArtifactRequirements([req]),
    )

    coursier_report_file_name = "coursier_report.json"

    process_result = await Get(
        ProcessResult,
        CoursierFetchProcess(
            args=(
                coursier_report_file_name,
                "--intransitive",
                *coursier_resolve_info.argv,
            ),
            input_digest=coursier_resolve_info.digest,
            output_directories=("classpath", ),
            output_files=(coursier_report_file_name, ),
            description=
            f"Fetching with coursier: {request.coord.to_coord_str()}",
        ),
    )
    report_digest = await Get(
        Digest,
        DigestSubset(process_result.output_digest,
                     PathGlobs([coursier_report_file_name])))
    report_contents = await Get(DigestContents, Digest, report_digest)
    report = json.loads(report_contents[0].content)

    report_deps = report["dependencies"]
    if len(report_deps) == 0:
        raise CoursierError(
            "Coursier fetch report has no dependencies (i.e. nothing was fetched)."
        )
    elif len(report_deps) > 1:
        raise CoursierError(
            "Coursier fetch report has multiple dependencies, but exactly 1 was expected."
        )

    dep = report_deps[0]
    resolved_coord = Coordinate.from_coord_str(dep["coord"])
    if resolved_coord != request.coord:
        raise CoursierError(
            f'Coursier resolved coord "{resolved_coord.to_coord_str()}" does not match requested coord "{request.coord.to_coord_str()}".'
        )

    classpath_dest_name = classpath_dest_filename(dep["coord"], dep["file"])
    classpath_dest = f"classpath/{classpath_dest_name}"

    resolved_file_digest = await Get(
        Digest,
        DigestSubset(process_result.output_digest,
                     PathGlobs([classpath_dest])))
    stripped_digest = await Get(
        Digest, RemovePrefix(resolved_file_digest, "classpath"))
    file_digest = await Get(
        FileDigest,
        ExtractFileDigest(stripped_digest, classpath_dest_name),
    )
    if file_digest != request.file_digest:
        raise CoursierError(
            f"Coursier fetch for '{resolved_coord}' succeeded, but fetched artifact {file_digest} did not match the expected artifact: {request.file_digest}."
        )
    return ClasspathEntry(digest=stripped_digest,
                          filenames=(classpath_dest_name, ))
Exemple #30
0
def test_compile_with_maven_deps(rule_runner: RuleRunner) -> None:
    joda_coord = Coordinate(group="joda-time",
                            artifact="joda-time",
                            version="2.10.10")
    resolved_joda_lockfile = TestCoursierWrapper.new(
        entries=(CoursierLockfileEntry(
            coord=joda_coord,
            file_name="joda-time-2.10.10.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                fingerprint=
                "dd8e7c92185a678d1b7b933f31209b6203c8ffa91e9880475a1be0346b9617e3",
                serialized_bytes_length=644419,
            ),
        ), ))
    rule_runner.write_files({
        "BUILD":
        dedent("""\
                jvm_artifact(
                    name = "joda-time_joda-time",
                    group = "joda-time",
                    artifact = "joda-time",
                    version = "2.10.10",
                )

                java_sources(
                    name = 'main',

                    dependencies = [
                        ':joda-time_joda-time',
                    ]
                )
                """),
        "3rdparty/jvm/default.lock":
        resolved_joda_lockfile.serialize(
            [ArtifactRequirement(coordinate=joda_coord)]),
        "Example.java":
        dedent("""
                package org.pantsbuild.example;

                import org.joda.time.DateTime;

                public class Example {
                    public static void main(String[] args) {
                        DateTime dt = new DateTime();
                        System.out.println(dt.getYear());
                    }
                }
                """),
    })
    request = CompileJavaSourceRequest(
        component=expect_single_expanded_coarsened_target(
            rule_runner, Address(spec_path="", target_name="main")),
        resolve=make_resolve(rule_runner),
    )
    classpath = rule_runner.request(RenderedClasspath, [request])
    assert classpath.content == {
        ".Example.java.main.javac.jar":
        {"org/pantsbuild/example/Example.class"}
    }