示例#1
0
def test_resolve_with_inexact_coord(rule_runner: RuleRunner) -> None:
    resolved_lockfile = rule_runner.request(
        CoursierResolvedLockfile,
        [
            # Note the open-ended coordinate here.  We will still resolve this for the user, but the result
            # will be exact and pinned.  As noted above, this is an especially brittle unit test, but version
            # 4.8 was chosen because it has multiple patch versions and no new versions have been uploaded
            # to 4.8.x in over a decade.
            ArtifactRequirements.from_coordinates(
                [Coordinate(group="junit", artifact="junit", version="4.8+")]),
        ],
    )

    assert resolved_lockfile == CoursierResolvedLockfile(
        entries=(CoursierLockfileEntry(
            coord=Coordinate(group="junit", artifact="junit", version="4.8.2"),
            file_name="junit_junit_4.8.2.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                fingerprint=
                "a2aa2c3bb2b72da76c3e6a71531f1eefdc350494819baf2b1d80d7146e020f9e",
                serialized_bytes_length=237344,
            ),
        ), ))
示例#2
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
示例#3
0
def test_fetch_one_coord_with_classifier(rule_runner: RuleRunner) -> None:
    # Has as a transitive dependency an artifact with both a `classifier` and `packaging`.
    coordinate = Coordinate(group="org.apache.avro",
                            artifact="avro-tools",
                            version="1.11.0")
    resolved_lockfile = rule_runner.request(
        CoursierResolvedLockfile,
        [ArtifactRequirements.from_coordinates([coordinate])],
    )

    entries = [
        e for e in resolved_lockfile.entries if e.coord == Coordinate(
            group="org.apache.avro",
            artifact="trevni-avro",
            version="1.11.0",
            packaging="jar",
            classifier="tests",
            strict=True,
        )
    ]
    assert len(entries) == 1
    entry = entries[0]

    classpath_entry = rule_runner.request(ClasspathEntry, [entry])
    assert classpath_entry.filenames == (
        "org.apache.avro_trevni-avro_jar_tests_1.11.0.jar", )
示例#4
0
async def materialize_scala_runtime_jars(
    request: MaterializeScalaRuntimeJarsRequest,
) -> MaterializeScalaRuntimeJarsResult:
    tool_classpath = await Get(
        ToolClasspath,
        ToolClasspathRequest(
            artifact_requirements=ArtifactRequirements.from_coordinates([
                Coordinate(
                    group="org.scala-lang",
                    artifact="scala-compiler",
                    version=request.scala_version,
                ),
                Coordinate(
                    group="org.scala-lang",
                    artifact="scala-library",
                    version=request.scala_version,
                ),
            ]), ),
    )

    materialized_classpath_digest = await Get(
        Digest,
        AddPrefix(tool_classpath.content.digest,
                  f"jvm/scala-runtime/{request.scala_version}"),
    )
    materialized_classpath = await Get(Snapshot, Digest,
                                       materialized_classpath_digest)
    return MaterializeScalaRuntimeJarsResult(materialized_classpath)
示例#5
0
async def resolve_kotlin_runtime_for_resolve(
    request: KotlinRuntimeForResolveRequest,
    jvm_artifact_targets: AllJvmArtifactTargets,
    jvm: JvmSubsystem,
    kotlin_subsystem: KotlinSubsystem,
) -> KotlinRuntimeForResolve:
    kotlin_version = kotlin_subsystem.version_for_resolve(request.resolve_name)

    # TODO: Nicer exception messages if this fails due to the resolve missing a jar.
    addresses = find_jvm_artifacts_or_raise(
        required_coordinates=[
            Coordinate(
                group="org.jetbrains.kotlin",
                artifact="kotlin-stdlib",
                version=kotlin_version,
            ),
            Coordinate(
                group="org.jetbrains.kotlin",
                artifact="kotlin-reflect",
                version=kotlin_version,
            ),
            Coordinate(
                group="org.jetbrains.kotlin",
                artifact="kotlin-script-runtime",
                version=kotlin_version,
            ),
        ],
        resolve=request.resolve_name,
        jvm_artifact_targets=jvm_artifact_targets,
        jvm=jvm,
    )
    return KotlinRuntimeForResolve(addresses)
示例#6
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,
        ), ))
示例#7
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",
        ),
    }
示例#8
0
def test_jvm_tool_base_extracts_correct_coordinates() -> None:
    rule_runner = RuleRunner(
        rules=[
            *config_files.rules(),
            *coursier_fetch_rules(),
            *coursier_setup_rules(),
            *external_tool_rules(),
            *source_files.rules(),
            *util_rules(),
            *jvm_tool.rules(),
            *lockfile_rules(),
            generate_test_tool_lockfile_request,
            generate_internal_test_tool_lockfile_request,
            SubsystemRule(MockJvmTool),
            QueryRule(GenerateJvmLockfile, (MockJvmToolLockfileSentinel, )),
            QueryRule(GenerateJvmLockfile,
                      (MockInternalToolLockfileSentinel, )),
            QueryRule(DigestContents, (Digest, )),
        ],
        target_types=[JvmArtifactTarget],
    )
    rule_runner.set_options(
        args=[
            "--mock-tool-artifacts=//:junit_junit",
            "--mock-tool-lockfile=/dev/null",
        ],
        env_inherit=PYTHON_BOOTSTRAP_ENV,
    )

    rule_runner.write_files({
        "BUILD":
        textwrap.dedent("""\
            jvm_artifact(
              name="junit_junit",
              group="junit",
              artifact="junit",
              version="4.13.2",
            )
            """)
    })
    lockfile_request = rule_runner.request(GenerateJvmLockfile,
                                           [MockJvmToolLockfileSentinel()])
    coordinates = sorted(i.coordinate for i in lockfile_request.artifacts)
    assert coordinates == [
        Coordinate(group="junit", artifact="junit", version="4.13.2"),
        Coordinate(group="org.hamcrest",
                   artifact="hamcrest-core",
                   version="1.3"),
    ]

    # Ensure that an internal-only tool will not have a lockfile generated.
    default_lockfile_result = rule_runner.request(
        GenerateJvmLockfile, [MockInternalToolLockfileSentinel()])
    assert default_lockfile_result.lockfile_dest == DEFAULT_TOOL_LOCKFILE
示例#9
0
def test_resolve_conflicting(rule_runner: RuleRunner) -> None:
    with engine_error(
            ProcessExecutionFailure,
            contains="Resolution error: Unsatisfied rule Strict(junit:junit)"):
        rule_runner.request(
            CoursierResolvedLockfile,
            [
                ArtifactRequirements.from_coordinates([
                    Coordinate(
                        group="junit", artifact="junit", version="4.8.1"),
                    Coordinate(
                        group="junit", artifact="junit", version="4.8.2"),
                ]),
            ],
        )
示例#10
0
def test_fetch_one_coord_with_mismatched_coord(
        rule_runner: RuleRunner) -> None:
    """This test demonstrates that fetch_one_coord is picky about inexact coordinates.

    Even though the expected jar was downloaded, the coordinate in the lockfile entry was inexact, meaning
    it wasn't an exact string match for the coordinate fetched and reported by Coursier, which is exact.

    This shouldn't happen in practice, because these lockfile entries are ultimately derived from Coursier
    reports which always give exact coordinate strings.
    """
    expected_exception_msg = (
        r'Coursier resolved coord.*?"org.hamcrest:hamcrest-core:1.3".*?'
        r'does not match requested coord.*?"org.hamcrest:hamcrest-core:1.3\+".*?'
    )
    lockfile_entry = CoursierLockfileEntry(
        coord=Coordinate(group="org.hamcrest",
                         artifact="hamcrest-core",
                         version="1.3+"),
        file_name="hamcrest-core-1.3.jar",
        direct_dependencies=Coordinates([]),
        dependencies=Coordinates([]),
        file_digest=FileDigest(
            fingerprint=
            "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9",
            serialized_bytes_length=45024,
        ),
    )
    with pytest.raises(ExecutionError, match=expected_exception_msg):
        rule_runner.request(ClasspathEntry, [lockfile_entry])
示例#11
0
def test_user_repo_order_is_respected(rule_runner: RuleRunner) -> None:
    """Tests that the repo resolution order issue found in #14577 is avoided."""

    jai_core = Coordinate(group="javax.media",
                          artifact="jai_core",
                          version="1.1.3")

    # `repo1.maven.org` has a bogus POM that Coursier hits first
    # `repo.osgeo.org` has a valid POM and should succeed
    rule_runner.set_options(
        args=[
            """--coursier-repos=['https://repo1.maven.org/maven2', 'https://repo.osgeo.org/repository/release']"""
        ],
        env_inherit=PYTHON_BOOTSTRAP_ENV,
    )
    with engine_error(ProcessExecutionFailure):
        rule_runner.request(
            CoursierResolvedLockfile,
            [
                ArtifactRequirements.from_coordinates([jai_core]),
            ],
        )

    rule_runner.set_options(
        args=[
            """--coursier-repos=['https://repo.osgeo.org/repository/release', 'https://repo1.maven.org/maven2']"""
        ],
        env_inherit=PYTHON_BOOTSTRAP_ENV,
    )
    rule_runner.request(
        CoursierResolvedLockfile,
        [
            ArtifactRequirements.from_coordinates([jai_core]),
        ],
    )
示例#12
0
def test_fetch_one_coord_with_transitive_deps(rule_runner: RuleRunner) -> None:
    junit_coord = Coordinate(group="junit", artifact="junit", version="4.13.2")
    classpath_entry = rule_runner.request(
        ClasspathEntry,
        [
            CoursierLockfileEntry(
                coord=junit_coord,
                file_name="junit_junit_4.13.2.jar",
                direct_dependencies=Coordinates([HAMCREST_COORD]),
                dependencies=Coordinates([HAMCREST_COORD]),
                file_digest=FileDigest(
                    fingerprint=
                    "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3",
                    serialized_bytes_length=384581,
                ),
            )
        ],
    )
    assert classpath_entry.filenames == ("junit_junit_4.13.2.jar", )
    file_digest = rule_runner.request(
        FileDigest,
        [ExtractFileDigest(classpath_entry.digest, "junit_junit_4.13.2.jar")])
    assert file_digest == FileDigest(
        fingerprint=
        "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3",
        serialized_bytes_length=384581,
    )
示例#13
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)

    try:
        addresses = find_jvm_artifacts_or_raise(
            required_coordinates=[
                Coordinate(
                    group=SCALA_LIBRARY_GROUP,
                    artifact=SCALA_LIBRARY_ARTIFACT,
                    version=scala_version,
                )
            ],
            resolve=request.resolve_name,
            jvm_artifact_targets=jvm_artifact_targets,
            jvm=jvm,
        )
        return ScalaRuntimeForResolve(addresses)
    except ConflictingJvmArtifactVersion as ex:
        raise ConflictingScalaLibraryVersionInResolveError(
            request.resolve_name, scala_version, ex.found_coordinate)
    except MissingJvmArtifacts:
        raise MissingScalaLibraryInResolveError(request.resolve_name,
                                                scala_version)
示例#14
0
async def resolve_scalapb_runtime_for_resolve(
    request: ScalaPBRuntimeForResolveRequest,
    jvm_artifact_targets: AllJvmArtifactTargets,
    jvm: JvmSubsystem,
    scala_subsystem: ScalaSubsystem,
    scalapb: ScalaPBSubsystem,
) -> ScalaPBRuntimeForResolve:
    scala_version = scala_subsystem.version_for_resolve(request.resolve_name)
    # TODO: Does not handle Scala 3 suffix which is just `_3` nor X.Y.Z versions.
    scala_binary_version, _, _ = scala_version.rpartition(".")
    version = scalapb.version

    try:
        addresses = find_jvm_artifacts_or_raise(
            required_coordinates=[
                Coordinate(
                    group=_SCALAPB_RUNTIME_GROUP,
                    artifact=
                    f"{_SCALAPB_RUNTIME_ARTIFACT}_{scala_binary_version}",
                    version=version,
                )
            ],
            resolve=request.resolve_name,
            jvm_artifact_targets=jvm_artifact_targets,
            jvm=jvm,
        )
        return ScalaPBRuntimeForResolve(addresses)
    except ConflictingJvmArtifactVersion as ex:
        raise ConflictingScalaPBRuntimeVersionInResolveError(
            request.resolve_name, ex.required_version, ex.found_coordinate)
    except MissingJvmArtifacts:
        raise MissingScalaPBRuntimeInResolveError(request.resolve_name,
                                                  version,
                                                  scala_binary_version)
示例#15
0
def test_resolve_with_transitive_deps(rule_runner: RuleRunner) -> None:
    junit_coord = Coordinate(group="junit", artifact="junit", version="4.13.2")
    resolved_lockfile = rule_runner.request(
        CoursierResolvedLockfile,
        [
            ArtifactRequirements.from_coordinates([junit_coord]),
        ],
    )

    assert resolved_lockfile == CoursierResolvedLockfile(entries=(
        CoursierLockfileEntry(
            coord=junit_coord,
            file_name="junit_junit_4.13.2.jar",
            direct_dependencies=Coordinates([HAMCREST_COORD]),
            dependencies=Coordinates([HAMCREST_COORD]),
            file_digest=FileDigest(
                fingerprint=
                "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3",
                serialized_bytes_length=384581,
            ),
        ),
        CoursierLockfileEntry(
            coord=HAMCREST_COORD,
            file_name="org.hamcrest_hamcrest-core_1.3.jar",
            direct_dependencies=Coordinates([]),
            dependencies=Coordinates([]),
            file_digest=FileDigest(
                fingerprint=
                "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9",
                serialized_bytes_length=45024,
            ),
        ),
    ))
示例#16
0
def java_parser_artifact_requirements() -> ArtifactRequirements:
    # Update in concert with the target definition for `java_parser`.
    return ArtifactRequirements.from_coordinates([
        Coordinate(group="com.fasterxml.jackson.core",
                   artifact="jackson-databind",
                   version="2.12.4"),
        Coordinate(
            group="com.fasterxml.jackson.datatype",
            artifact="jackson-datatype-jdk8",
            version="2.12.4",
        ),
        Coordinate(
            group="com.github.javaparser",
            artifact="javaparser-symbol-solver-core",
            version="3.23.0",
        ),
    ], )
示例#17
0
def test_file_deps_success(rule_runner: RuleRunner) -> None:
    scalatest_coord = Coordinate(group="org.scalatest",
                                 artifact="scalatest_2.13",
                                 version="3.2.10")
    rule_runner.write_files({
        "3rdparty/jvm/default.lock":
        importlib.resources.read_text(*Scalatest.default_lockfile_resource),
        "BUILD":
        dedent(f"""\
                jvm_artifact(
                  name = 'org.scalatest_scalatest',
                  group = '{scalatest_coord.group}',
                  artifact = '{scalatest_coord.artifact}',
                  version = '{scalatest_coord.version}',
                )

                scalatest_tests(
                    name='example-test',
                    dependencies= [
                        ':org.scalatest_scalatest',
                        ':ducks',
                    ],
                )

                file(
                    name="ducks",
                    source="ducks.txt",
                )

                """),
        "SimpleSpec.scala":
        dedent("""
                package org.pantsbuild.example;

                import org.scalatest.funspec.AnyFunSpec
                import java.nio.file.Files
                import java.nio.file.Path

                class SimpleSpec extends AnyFunSpec {
                  describe("Ducks") {
                    it("should be ducks") {
                      assert(Files.readString(Path.of("ducks.txt")) == "lol ducks")
                    }
                  }
                }
                """),
        "ducks.txt":
        "lol ducks",
    })

    test_result = run_scalatest_test(rule_runner, "example-test",
                                     "SimpleSpec.scala")

    assert test_result.exit_code == 0
    assert "Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0" in test_result.stdout
    assert test_result.xml_results and test_result.xml_results.files
示例#18
0
    def from_json_dict(cls, entry) -> CoursierLockfileEntry:
        """Construct a CoursierLockfileEntry from its JSON dictionary representation."""

        return cls(
            coord=Coordinate.from_json_dict(entry["coord"]),
            file_name=entry["file_name"],
            direct_dependencies=Coordinates(
                Coordinate.from_json_dict(d)
                for d in entry["directDependencies"]),
            dependencies=Coordinates(
                Coordinate.from_json_dict(d) for d in entry["dependencies"]),
            file_digest=FileDigest(
                fingerprint=entry["file_digest"]["fingerprint"],
                serialized_bytes_length=entry["file_digest"]
                ["serialized_bytes_length"],
            ),
            remote_url=entry.get("remote_url"),
            pants_address=entry.get("pants_address"),
        )
示例#19
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)
示例#20
0
async def fetch_scala_library(request: ScalaLibraryRequest) -> ClasspathEntry:
    tcp = await Get(
        ToolClasspath,
        ToolClasspathRequest(
            artifact_requirements=ArtifactRequirements.from_coordinates([
                Coordinate(
                    group="org.scala-lang",
                    artifact="scala-library",
                    version=request.version,
                ),
            ]), ),
    )

    return ClasspathEntry(tcp.digest, tcp.content.files)
示例#21
0
async def _materialize_scala_runtime_jars(scala_version: str) -> Snapshot:
    tool_classpath = await Get(
        ToolClasspath,
        ToolClasspathRequest(
            artifact_requirements=ArtifactRequirements.from_coordinates([
                Coordinate(
                    group="org.scala-lang",
                    artifact="scala-compiler",
                    version=scala_version,
                ),
                Coordinate(
                    group="org.scala-lang",
                    artifact="scala-library",
                    version=scala_version,
                ),
            ]), ),
    )

    return await Get(
        Snapshot,
        AddPrefix(tool_classpath.content.digest,
                  f"jvm/scala-runtime/{scala_version}"),
    )
示例#22
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,
        ), ))
示例#23
0
def test_fetch_one_coord_with_jar(rule_runner: RuleRunner) -> None:
    coord = Coordinate(group="jeremy", artifact="jeremy", version="4.13.2")
    file_name = f"{coord.group}_{coord.artifact}_{coord.version}.jar"
    rule_runner.write_files({
        "BUILD":
        textwrap.dedent(f"""\
            jvm_artifact(
              name="jeremy",
              group="{coord.group}",
              artifact="{coord.artifact}",
              version="{coord.version}",
              jar="jeremy.jar",
            )
            """),
        "jeremy.jar":
        "hello dave",
    })

    classpath_entry = rule_runner.request(
        ClasspathEntry,
        [
            CoursierLockfileEntry(
                coord=coord,
                file_name=file_name,
                direct_dependencies=Coordinates([]),
                dependencies=Coordinates([]),
                file_digest=FileDigest(
                    fingerprint=
                    "55b9afa8d7776cd6c318eec51f506e9c7f66c247dcec343d4667f5f269714f86",
                    serialized_bytes_length=10,
                ),
                pants_address="//:jeremy",
            )
        ],
    )
    assert classpath_entry.filenames == (file_name, )
    file_digest = rule_runner.request(
        FileDigest,
        [ExtractFileDigest(classpath_entry.digest, file_name)],
    )
    assert file_digest == FileDigest(
        fingerprint=
        "55b9afa8d7776cd6c318eec51f506e9c7f66c247dcec343d4667f5f269714f86",
        serialized_bytes_length=10,
    )
示例#24
0
async def fetch_nailgun() -> Nailgun:
    nailgun = await Get(
        ClasspathEntry,
        CoursierLockfileEntry(
            coord=Coordinate.from_coord_str(
                "com.martiansoftware:nailgun-server:0.9.1"),
            file_name="com.martiansoftware_nailgun-server_0.9.1.jar",
            direct_dependencies=Coordinates(),
            dependencies=Coordinates(),
            file_digest=FileDigest(
                fingerprint=
                "4518faa6bf4bd26fccdc4d85e1625dc679381a08d56872d8ad12151dda9cef25",
                serialized_bytes_length=32927,
            ),
        ),
    )

    return Nailgun(nailgun)
示例#25
0
def test_transitive_excludes(rule_runner: RuleRunner) -> None:
    resolve = rule_runner.request(
        CoursierResolvedLockfile,
        [
            ArtifactRequirements([
                Coordinate(
                    group="com.fasterxml.jackson.core",
                    artifact="jackson-databind",
                    version="2.12.1",
                ).as_requirement().with_extra_excludes(
                    "com.fasterxml.jackson.core:jackson-core")
            ]),
        ],
    )

    entries = resolve.entries
    assert any(i for i in entries if i.coord.artifact == "jackson-databind")
    assert not any(i for i in entries if i.coord.artifact == "jackson-core")
示例#26
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])],
        )
示例#27
0
    def from_kwargs(cls, kwargs) -> JVMLockfileFixtureDefinition:
        lockfile_rel_path = kwargs["path"]
        if not lockfile_rel_path:
            raise ValueError(
                "`path` must be specified as a relative path to a lockfile")

        requirements = kwargs["requirements"] or []
        coordinates: list[Coordinate] = []
        for requirement in requirements:
            if isinstance(requirement, Coordinate):
                coordinates.append(requirement)
            elif isinstance(requirement, str):
                coordinate = Coordinate.from_coord_str(requirement)
                coordinates.append(coordinate)
            else:
                raise ValueError(
                    f"Unsupported type `{type(requirement)}` for JVM coordinate. Expected `Coordinate` or `str`."
                )

        return cls(
            lockfile_rel_path=Path(lockfile_rel_path),
            coordinates=tuple(coordinates),
        )
示例#28
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])
示例#29
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",
    ]
示例#30
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