Skip to content

Commit

Permalink
Add support for using Maven BOMs with Coursier
Browse files Browse the repository at this point in the history
Coursier now support using Maven BOMs when resolving. This upgrades
Coursier to 2.1.23 and enables using BOMs leveraging the existing `boms`
attribute on `maven_install`.

Note that Coursier has a slight performance regression since adding
support for BOMs, see coursier/coursier#3190.

Fixes #1289
  • Loading branch information
protocol7 committed Jan 4, 2025
1 parent c1ca608 commit b22ec5e
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 893 deletions.
10 changes: 5 additions & 5 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ use_repo(

http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")

_COURSIER_CLI_VERSION = "v2.1.8"
_COURSIER_CLI_VERSION = "v2.1.23"

COURSIER_CLI_HTTP_FILE_NAME = ("coursier_cli_" + _COURSIER_CLI_VERSION).replace(".", "_").replace("-", "_")

Expand All @@ -113,7 +113,7 @@ COURSIER_CLI_GITHUB_ASSET_URL = "https://github.com/coursier/coursier/releases/d
# Run 'bazel run //:mirror_coursier' to upload a copy of the jar to the Bazel mirror.
COURSIER_CLI_BAZEL_MIRROR_URL = "https://mirror.bazel.build/coursier_cli/" + COURSIER_CLI_HTTP_FILE_NAME + ".jar"

COURSIER_CLI_SHA256 = "2b78bfdd3ef13fd1f42f158de0f029d7cbb1f4f652d51773445cf2b6f7918a87"
COURSIER_CLI_SHA256 = "520c0c3dea3e5d075542e874d33e4cfac5a9bf3f461a3d4a9e6fba4032f7f007"

http_file(
name = "coursier_cli",
Expand Down Expand Up @@ -536,8 +536,8 @@ dev_maven.install(
"com.github.spinalhdl:spinalhdl-core_2.11:1.3.6",
"com.github.spinalhdl:spinalhdl-lib_2.11:1.3.6",
# https://github.com/bazelbuild/rules_jvm_external/issues/201
"org.apache.kafka:kafka_2.11:2.1.1",
"io.confluent:kafka-avro-serializer:5.0.1",
#"org.apache.kafka:kafka_2.11:2.1.1",
#"io.confluent:kafka-avro-serializer:5.0.1",
# https://github.com/bazelbuild/rules_jvm_external/issues/309
"io.quarkus.http:quarkus-http-servlet:3.0.0.Beta1",
# https://github.com/bazelbuild/rules_jvm_external/issues/371
Expand Down Expand Up @@ -567,7 +567,7 @@ dev_maven.install(
repositories = [
"https://repo1.maven.org/maven2",
"https://maven.google.com",
"https://packages.confluent.io/maven/",
#"https://packages.confluent.io/maven/",
],
)
dev_maven.override(
Expand Down
13 changes: 1 addition & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,28 +362,17 @@ bar_pinned_maven_install()

## (Experimental) Support for Maven BOM files

Support for Maven BOMs can be enabled by switching the resolver used by `maven_install` to one that supports Maven BOMs.
This can be done by setting the `resolver` attribute to `maven`. The new resolver will likely result in different
resolutions than the existing resolver, so it is advised to re-run your dependencies pin.

The new resolver requires you to use a `maven_install_json` file, though if you have not yet pinned your dependencies,
this can simply be an empty file.

As an example:
Maven BOMs can be used by using the `boms` attribute, for example:

```starlark
maven.install(
# Resolution using BOMs is supported by using the `maven` resolver
resolver = "maven",
boms = [
"org.seleniumhq.selenium:selenium-bom:4.18.1",
],
artifacts = [
# This dependency is included in the `selenium-bom`, so we can omit the version number
"org.seleniumhq.selenium:selenium-java",
],
# The `maven` resolver requires a lock file, though this can be an empty file before pinning
lock_file = "//:manifest_install.json",
)
```

Expand Down
6 changes: 3 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ maven_install(
"com.github.spinalhdl:spinalhdl-core_2.11:1.3.6",
"com.github.spinalhdl:spinalhdl-lib_2.11:1.3.6",
# https://github.com/bazelbuild/rules_jvm_external/issues/201
"org.apache.kafka:kafka_2.11:2.1.1",
"io.confluent:kafka-avro-serializer:5.0.1",
#"org.apache.kafka:kafka_2.11:2.1.1",
#"io.confluent:kafka-avro-serializer:5.0.1",
# https://github.com/bazelbuild/rules_jvm_external/issues/309
"io.quarkus.http:quarkus-http-servlet:3.0.0.Beta1",
# https://github.com/bazelbuild/rules_jvm_external/issues/371
Expand Down Expand Up @@ -290,7 +290,7 @@ maven_install(
repositories = [
"https://repo1.maven.org/maven2",
"https://maven.google.com",
"https://packages.confluent.io/maven/",
#"https://packages.confluent.io/maven/",
],
)

Expand Down
1 change: 1 addition & 0 deletions private/extensions/maven.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ def maven_impl(mctx):
user_provided_name = name,
repositories = repo.get("repositories"),
artifacts = artifacts_json,
boms = boms_json,
fail_on_missing_checksum = repo.get("fail_on_missing_checksum"),
fetch_sources = repo.get("fetch_sources"),
fetch_javadoc = repo.get("fetch_javadoc"),
Expand Down
23 changes: 18 additions & 5 deletions private/rules/coursier.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ def get_coursier_cache_or_default(repository_ctx, use_unsafe_shared_cache):
def make_coursier_dep_tree(
repository_ctx,
artifacts,
boms,
excluded_artifacts,
repositories,
version_conflict_policy,
Expand Down Expand Up @@ -839,11 +840,15 @@ def make_coursier_dep_tree(
cmd.extend(artifact_coordinates)
if version_conflict_policy == "pinned":
for coord in artifact_coordinates:
# Undo any `,classifier=` and/or `,type=` suffix from `utils.artifact_coordinate`.
cmd.extend([
"--force-version",
",".join([c for c in coord.split(",") if not c.startswith("classifier=") and not c.startswith("type=")]),
])
# check if the artifact has version set
version = coord.split(",")[0].split(":")[2]

if version:
# Undo any `,classifier=` and/or `,type=` suffix from `utils.artifact_coordinate`.
cmd.extend([
"--force-version",
",".join([c for c in coord.split(",") if not c.startswith("classifier=") and not c.startswith("type=")]),
])
else:
for coord in forced_versions:
cmd.extend([
Expand All @@ -855,6 +860,9 @@ def make_coursier_dep_tree(
cmd.append("--no-default")
cmd.extend(["--json-output-file", "dep-tree.json"])

for bom in boms:
cmd.extend(["--bom", utils.artifact_coordinate(bom)])

if fail_on_missing_checksum:
cmd.extend(["--checksum", "SHA-1,MD5"])
else:
Expand Down Expand Up @@ -1026,6 +1034,9 @@ def _coursier_fetch_impl(repository_ctx):

_check_artifacts_are_unique(artifacts, repository_ctx.attr.duplicate_version_warning)

boms = [json.decode(bom) for bom in repository_ctx.attr.boms]
_check_artifacts_are_unique(boms, repository_ctx.attr.duplicate_version_warning)

excluded_artifacts = []
for artifact in repository_ctx.attr.excluded_artifacts:
excluded_artifacts.append(json.decode(artifact))
Expand All @@ -1039,6 +1050,7 @@ def _coursier_fetch_impl(repository_ctx):
dep_tree = make_coursier_dep_tree(
repository_ctx,
artifacts,
boms,
excluded_artifacts,
repositories,
repository_ctx.attr.version_conflict_policy,
Expand Down Expand Up @@ -1442,6 +1454,7 @@ coursier_fetch = repository_rule(
"user_provided_name": attr.string(),
"repositories": attr.string_list(), # list of repository objects, each as json
"artifacts": attr.string_list(), # list of artifact objects, each as json
"boms": attr.string_list(), # list of bom objects, each as json
"fail_on_missing_checksum": attr.bool(default = True),
"fetch_sources": attr.bool(default = False),
"fetch_javadoc": attr.bool(default = False),
Expand Down
6 changes: 2 additions & 4 deletions private/rules/maven_install.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def maven_install(
repositories: A list of Maven repository URLs, specified in lookup order.
Supports URLs with HTTP Basic Authentication, e.g. "https://username:[email protected]".
boms: A list of Maven artifact coordinates in the form of `group:artifact:version` which refer to Maven BOMs. The `coursier` `resolver` does not support using BOMs.
boms: A list of Maven artifact coordinates in the form of `group:artifact:version` which refer to Maven BOMs.
artifacts: A list of Maven artifact coordinates in the form of `group:artifact:version`.
resolver: Which resolver to use. One of `coursier`, or `maven`.
fail_on_missing_checksum: fail the fetch if checksum attributes are not present.
Expand Down Expand Up @@ -81,9 +81,6 @@ def maven_install(
ignore_empty_files: Treat jars that are empty as if they were not found.
additional_coursier_options: Additional options that will be passed to coursier.
"""
if boms and resolver == "coursier":
fail("The coursier resolver does not support resolving Maven BOMs. Please use another resolver.")

if resolver != "coursier" and not maven_install_json:
fail("Only the coursier resolver supports build time resolution. Please set `maven_install_json`. An empty file will work.")

Expand Down Expand Up @@ -126,6 +123,7 @@ def maven_install(
pinned_repo_name = None if maven_install_json == None else name,
repositories = repositories_json_strings,
artifacts = artifacts_json_strings,
boms = boms_json_strings,
fail_on_missing_checksum = fail_on_missing_checksum,
fetch_sources = fetch_sources,
fetch_javadoc = fetch_javadoc,
Expand Down
4 changes: 2 additions & 2 deletions private/versions.bzl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
_COURSIER_CLI_VERSION = "v2.1.8"
_COURSIER_CLI_VERSION = "v2.1.23"

COURSIER_CLI_HTTP_FILE_NAME = ("coursier_cli_" + _COURSIER_CLI_VERSION).replace(".", "_").replace("-", "_")
COURSIER_CLI_GITHUB_ASSET_URL = "https://github.com/coursier/coursier/releases/download/{COURSIER_CLI_VERSION}/coursier.jar".format(COURSIER_CLI_VERSION = _COURSIER_CLI_VERSION)

# Run 'bazel run //:mirror_coursier' to upload a copy of the jar to the Bazel mirror.
COURSIER_CLI_BAZEL_MIRROR_URL = "https://mirror.bazel.build/coursier_cli/" + COURSIER_CLI_HTTP_FILE_NAME + ".jar"
COURSIER_CLI_SHA256 = "2b78bfdd3ef13fd1f42f158de0f029d7cbb1f4f652d51773445cf2b6f7918a87"
COURSIER_CLI_SHA256 = "520c0c3dea3e5d075542e874d33e4cfac5a9bf3f461a3d4a9e6fba4032f7f007"
Loading

0 comments on commit b22ec5e

Please sign in to comment.