diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 0f028e33d..a3791c269 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -13,6 +13,7 @@ tasks: - "//..." # These tests are currently incompatible with RBE - "-//tests/integration:UnsafeSharedCacheTest" + - "-//tests/integration/override_targets" ubuntu1804: shell_commands: - bazel run @unpinned_regression_testing//:pin @@ -36,3 +37,4 @@ tasks: # https://github.com/bazelbuild/rules_kotlin/issues/179 # https://github.com/bazelbuild/rules_kotlin/blob/master/.bazelci/presubmit.yml - "-//tests/unit/kotlin/..." + - "-//tests/integration/override_targets" diff --git a/README.md b/README.md index 225c6d354..779955c62 100644 --- a/README.md +++ b/README.md @@ -530,6 +530,31 @@ $ bazel query @pinning//:all | grep guava_guava @pinning//:com_google_guava_guava_25_0_android ``` +### Overriding generated targets + +You can override the generated targets for artifacts with a target label of your +choice. For instance, if you want to provide your own definition of +`@maven//:com_google_guava_guava` at `//third_party/guava:guava`, specify the +mapping in the `override_targets` attribute: + +```python +maven_install( + name = "pinning", + artifacts = [ + "com.google.guava:guava:27.0-jre", + ], + repositories = [ + "https://repo1.maven.org/maven2", + ], + override_targets = { + "com.google.guava:guava": "@//third_party/guava:guava", + }, +) +``` + +Note that the target label contains `@//`, which tells Bazel to reference the +target relative to your main workspace, instead of the `@maven` workspace. + ### Proxies As with other Bazel repository rules, the standard `http_proxy`, `https_proxy` diff --git a/WORKSPACE b/WORKSPACE index b4f6bc51f..c41f0fa5b 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -151,6 +151,8 @@ maven_install( "org.openjfx:javafx-base:11.0.1", # https://github.com/bazelbuild/rules_jvm_external/issues/178 "io.kubernetes:client-java:4.0.0-beta1", + # https://github.com/bazelbuild/rules_jvm_external/issues/199 + "com.google.ar.sceneform.ux:sceneform-ux:1.10.0", ], repositories = [ "https://repo1.maven.org/maven2", @@ -159,6 +161,9 @@ maven_install( ], generate_compat_repositories = True, maven_install_json = "//:regression_testing_install.json", + override_targets = { + "com.google.ar.sceneform:rendering": "@//tests/integration/override_targets:sceneform_rendering", + } ) load("@regression_testing//:defs.bzl", "pinned_maven_install") diff --git a/coursier.bzl b/coursier.bzl index 9ed9a788e..91e9cb11a 100644 --- a/coursier.bzl +++ b/coursier.bzl @@ -130,7 +130,7 @@ def _genrule_copy_artifact_from_http_file(artifact): # tree. # # Made function public for testing. -def _generate_imports(repository_ctx, dep_tree, neverlink_artifacts = {}): +def _generate_imports(repository_ctx, dep_tree, neverlink_artifacts, override_targets): # The list of java_import/aar_import declaration strings to be joined at the end all_imports = [] @@ -145,6 +145,10 @@ def _generate_imports(repository_ctx, dep_tree, neverlink_artifacts = {}): # @maven//:junit_junit, we also generate @junit_junit//jar as an alias to it. jar_versionless_target_labels = [] + labels_to_override = {} + for coord in override_targets: + labels_to_override.update({_escape(coord): override_targets.get(coord)}) + # First collect a map of target_label to their srcjar relative paths, and symlink the srcjars if needed. # We will use this map later while generating target declaration strings with the "srcjar" attr. srcjar_paths = None @@ -171,7 +175,16 @@ def _generate_imports(repository_ctx, dep_tree, neverlink_artifacts = {}): elif repository_ctx.attr.fetch_sources and ":sources:" in artifact["coord"]: # We already processed the sources above, so skip them here. pass - elif target_label not in seen_imports and artifact_path != None: + elif target_label in labels_to_override: + # Override target labels with the user provided mapping, instead of generating + # a jvm_import/aar_import based on information in dep_tree. + seen_imports[target_label] = True + all_imports.append( + "alias(\n\tname = \"%s\",\n\tactual = \"%s\",\n)" % (target_label, labels_to_override.get(target_label))) + if repository_ctx.attr.maven_install_json: + # Provide the downloaded artifact as a file target. + all_imports.append(_genrule_copy_artifact_from_http_file(artifact)) + elif artifact_path != None: seen_imports[target_label] = True # 1. Generate the rule class. @@ -233,7 +246,11 @@ def _generate_imports(repository_ctx, dep_tree, neverlink_artifacts = {}): # Coursier returns cyclic dependencies sometimes. Handle it here. # See https://github.com/bazelbuild/rules_jvm_external/issues/172 if dep_target_label != target_label: - target_import_labels.append("\t\t\":%s\",\n" % dep_target_label) + if dep_target_label in labels_to_override: + dep_target_label = labels_to_override.get(dep_target_label) + else: + dep_target_label = ":" + dep_target_label + target_import_labels.append("\t\t\"%s\",\n" % dep_target_label) target_import_labels = _deduplicate_list(target_import_labels) target_import_string.append("".join(target_import_labels) + "\t],") @@ -573,6 +590,7 @@ def _pinned_coursier_fetch_impl(repository_ctx): for a in artifacts if a.get("neverlink", False) }, + override_targets = repository_ctx.attr.override_targets, ) repository_ctx.template( @@ -767,6 +785,7 @@ def _coursier_fetch_impl(repository_ctx): repository_ctx = repository_ctx, dep_tree = dep_tree, neverlink_artifacts = neverlink_artifacts, + override_targets = repository_ctx.attr.override_targets, ) repository_ctx.template( @@ -856,6 +875,7 @@ pinned_coursier_fetch = repository_rule( "fetch_sources": attr.bool(default = False), "generate_compat_repositories": attr.bool(default = False), # generate a compatible layer with repositories for each artifact "maven_install_json": attr.label(allow_single_file = True), + "override_targets": attr.string_dict(default = {}), }, implementation = _pinned_coursier_fetch_impl, ) @@ -883,6 +903,7 @@ coursier_fetch = repository_rule( values = ["default", "pinned"], ), "maven_install_json": attr.label(allow_single_file = True), + "override_targets": attr.string_dict(default = {}), }, environ = [ "JAVA_HOME", diff --git a/defs.bzl b/defs.bzl index 5c00f1622..a57a971af 100644 --- a/defs.bzl +++ b/defs.bzl @@ -27,7 +27,8 @@ def maven_install( excluded_artifacts = [], generate_compat_repositories = False, version_conflict_policy = "default", - maven_install_json = None): + maven_install_json = None, + override_targets = {}): """Resolves and fetches artifacts transitively from Maven repositories. This macro runs a repository rule that invokes the Coursier CLI to resolve @@ -52,6 +53,9 @@ def maven_install( Coursier's default policy. maven_install_json: A label to a `maven_install.json` file to use pinned artifacts for generating build targets. e.g `//:maven_install.json`. + override_targets: A mapping of `group:artifact` to Bazel target labels. All occurrences of the + target label for `group:artifact` will be an alias to the specified label, therefore overriding + the original generated `jvm_import` or `aar_import` target. """ repositories_json_strings = [] for repository in parse.parse_repository_spec_list(repositories): @@ -90,6 +94,7 @@ def maven_install( excluded_artifacts = excluded_artifacts_json_strings, generate_compat_repositories = generate_compat_repositories, version_conflict_policy = version_conflict_policy, + override_targets = override_targets, ) if maven_install_json != None: @@ -100,6 +105,7 @@ def maven_install( maven_install_json = maven_install_json, fetch_sources = fetch_sources, generate_compat_repositories = generate_compat_repositories, + override_targets = override_targets, ) diff --git a/docs/api.md b/docs/api.md index 987397e5e..35bc5f692 100644 --- a/docs/api.md +++ b/docs/api.md @@ -31,7 +31,7 @@ load("@rules_jvm_external//:defs.bzl", "maven_install", "artifact") ## maven_install
-maven_install(name, repositories, artifacts, fail_on_missing_checksum, fetch_sources, use_unsafe_shared_cache, excluded_artifacts, generate_compat_repositories, maven_install_json) +maven_install(name, repositories, artifacts, fail_on_missing_checksum, fetch_sources, use_unsafe_shared_cache, excluded_artifacts, generate_compat_repositories, version_conflict_policy, maven_install_json, override_targets)Resolves and fetches artifacts transitively from Maven repositories. @@ -123,6 +123,17 @@ and fetch Maven artifacts transitively. +
version_conflict_policy
"default"
+ + Policy for user-defined vs. transitive dependency version + conflicts. If "pinned", choose the user's version unconditionally. If "default", follow + Coursier's default policy. +
+maven_install_json
override_targets
{}
+ + A mapping of `group:artifact` to Bazel target labels. All occurrences of the + target label for `group:artifact` will be an alias to the specified label, therefore overriding + the original generated `jvm_import` or `aar_import` target. +
+