From 936ce88b9d634295a7ccb16989d68344935cf786 Mon Sep 17 00:00:00 2001 From: Brad Corso Date: Mon, 15 Jul 2024 12:01:54 -0700 Subject: [PATCH] Update Dagger's Bazel setup. RELNOTES=N/A PiperOrigin-RevId: 652556341 --- .bazelrc | 3 + .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- BUILD | 4 +- MODULE.bazel | 39 +++ WORKSPACE | 168 +++-------- build_defs.bzl | 4 +- gwt/BUILD | 4 +- java/dagger/BUILD | 2 +- java/dagger/android/BUILD | 6 +- java/dagger/android/processor/BUILD | 2 +- java/dagger/android/support/BUILD | 16 +- java/dagger/grpc/server/BUILD | 8 +- java/dagger/grpc/server/processor/BUILD | 6 +- java/dagger/hilt/BUILD | 2 +- java/dagger/hilt/android/BUILD | 14 +- java/dagger/hilt/android/processor/BUILD | 2 +- java/dagger/hilt/android/testing/BUILD | 18 +- java/dagger/hilt/processor/BUILD | 2 +- java/dagger/internal/codegen/BUILD | 2 +- java/dagger/lint/BUILD | 2 +- java/dagger/producers/BUILD | 2 +- java/dagger/spi/BUILD | 2 +- javatests/dagger/internal/codegen/BUILD | 4 +- third_party/java/auto/BUILD | 1 - tools/BUILD | 25 -- tools/jarjar/BUILD | 50 ++++ tools/jarjar/jarjar.bzl | 92 ++++++ tools/jarjar/jarjar_runner.sh | 64 ++++ tools/jarjar/test/BUILD | 43 +++ tools/jarjar/test/expected_libs.dep | 2 + tools/jarjar/test/jarjar_validator.sh | 8 + tools/jarjar/test/test-library1.jar | Bin 0 -> 753 bytes tools/jarjar/test/test-library2.jar | Bin 0 -> 753 bytes tools/javadoc/BUILD | 17 ++ tools/javadoc/javadoc.bzl | 156 ++++++++++ tools/maven/BUILD | 45 +++ tools/{ => maven}/maven.bzl | 14 +- tools/{ => maven}/maven_info.bzl | 0 tools/{ => maven}/pom-template.xml | 0 tools/maven/pom_file.bzl | 361 +++++++++++++++++++++++ 41 files changed, 973 insertions(+), 221 deletions(-) create mode 100644 MODULE.bazel create mode 100644 tools/jarjar/BUILD create mode 100644 tools/jarjar/jarjar.bzl create mode 100755 tools/jarjar/jarjar_runner.sh create mode 100644 tools/jarjar/test/BUILD create mode 100644 tools/jarjar/test/expected_libs.dep create mode 100755 tools/jarjar/test/jarjar_validator.sh create mode 100644 tools/jarjar/test/test-library1.jar create mode 100644 tools/jarjar/test/test-library2.jar create mode 100644 tools/javadoc/BUILD create mode 100644 tools/javadoc/javadoc.bzl create mode 100644 tools/maven/BUILD rename tools/{ => maven}/maven.bzl (97%) rename tools/{ => maven}/maven_info.bzl (100%) rename tools/{ => maven}/pom-template.xml (100%) create mode 100644 tools/maven/pom_file.bzl diff --git a/.bazelrc b/.bazelrc index ecd54a58a52..7e82da13348 100644 --- a/.bazelrc +++ b/.bazelrc @@ -6,3 +6,6 @@ build --host_javacopt=-g # TODO(ronshapiro): explore how much work it would be to reenable this build --javacopt="-Xep:BetaApi:OFF" build --host_javacopt="-Xep:BetaApi:OFF" + +# Enable MODULE.bazel +common --enable_bzlmod \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a18be6594d..ae9e1d32a9f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ env: USE_JAVA_VERSION_FOR_PLUGIN: '17' # Our Bazel builds currently rely on 6.4.0. The version is set via # baselisk by USE_BAZEL_VERSION: https://github.com/bazelbuild/bazelisk. - USE_BAZEL_VERSION: '6.4.0' + USE_BAZEL_VERSION: '7.2.1' # The default Maven 3.9.0 has a regression so we manually install 3.8.7. # https://issues.apache.org/jira/browse/MNG-7679 USE_MAVEN_VERSION: '3.8.7' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 31ecc66bb78..1d2b6956b0b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ env: USE_JAVA_VERSION_FOR_PLUGIN: '17' # Our Bazel builds currently rely on 6.4.0. The version is set via # baselisk by USE_BAZEL_VERSION: https://github.com/bazelbuild/bazelisk. - USE_BAZEL_VERSION: '6.4.0' + USE_BAZEL_VERSION: '7.2.1' DAGGER_RELEASE_VERSION: "${{ github.event.inputs.dagger_release_version }}" # The default Maven 3.9.0 has a regression so we manually install 3.8.7. # https://issues.apache.org/jira/browse/MNG-7679 diff --git a/BUILD b/BUILD index 2dbf6ff5397..25856d90411 100644 --- a/BUILD +++ b/BUILD @@ -12,10 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@google_bazel_common//tools/jarjar:jarjar.bzl", "jarjar_library") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "define_kt_toolchain") load("@rules_java//java:defs.bzl", "java_library") +load("//tools/jarjar:jarjar.bzl", "jarjar_library") +load("//tools/javadoc:javadoc.bzl", "javadoc_library") package(default_visibility = ["//visibility:public"]) diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 00000000000..d3bc453b6e8 --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,39 @@ +# Copyright (C) 2024 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +bazel_dep( + name = "bazel_skylib", + version = "1.7.1", +) + +bazel_dep( + name = "rules_java", + version = "7.7.0", +) + +bazel_dep( + name = "rules_kotlin", + version = "1.9.6", + repo_name = "io_bazel_rules_kotlin", +) + +bazel_dep( + name = "rules_jvm_external", + version = "6.2", +) + +bazel_dep( + name = "rules_robolectric", + version = "4.13", +) diff --git a/WORKSPACE b/WORKSPACE index 629806baac4..54fc3bb5067 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -13,8 +13,6 @@ # limitations under the License. -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - ############################# # Load nested repository ############################# @@ -27,129 +25,19 @@ local_repository( ) ############################# -# Load Bazel Skylib rules +# Load Android Sdk ############################# -BAZEL_SKYLIB_VERSION = "1.5.0" - -BAZEL_SKYLIB_SHA = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94" - -http_archive( - name = "bazel_skylib", - sha256 = BAZEL_SKYLIB_SHA, - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/%s/bazel-skylib-%s.tar.gz" % (BAZEL_SKYLIB_VERSION, BAZEL_SKYLIB_VERSION), - "https://github.com/bazelbuild/bazel-skylib/releases/download/%s/bazel-skylib-%s.tar.gz" % (BAZEL_SKYLIB_VERSION, BAZEL_SKYLIB_VERSION), - ], -) - -load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") - -bazel_skylib_workspace() - -############################# -# Load rules_java repository -############################# - -http_archive( - name = "rules_java", - sha256 = "c73336802d0b4882e40770666ad055212df4ea62cfa6edf9cb0f9d29828a0934", - url = "https://github.com/bazelbuild/rules_java/releases/download/5.3.5/rules_java-5.3.5.tar.gz", -) - -#################################################### -# Load Protobuf repository (needed by bazel-common) -#################################################### - -http_archive( - name = "rules_proto", - # output from `sha256sum` on the downloaded tar.gz file - sha256 = "66bfdf8782796239d3875d37e7de19b1d94301e8972b3cbd2446b332429b4df1", - strip_prefix = "rules_proto-4.0.0", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz", - "https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz", - ], -) - -load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains") - -rules_proto_dependencies() - -rules_proto_toolchains() - -############################# -# Load Bazel-Common repository -############################# - -http_archive( - name = "google_bazel_common", - sha256 = "82a49fb27c01ad184db948747733159022f9464fc2e62da996fa700594d9ea42", - strip_prefix = "bazel-common-2a6b6406e12208e02b2060df0631fb30919080f3", - urls = ["https://github.com/google/bazel-common/archive/2a6b6406e12208e02b2060df0631fb30919080f3.zip"], -) - -load("@google_bazel_common//:workspace_defs.bzl", "google_common_workspace_rules") - -google_common_workspace_rules() - -############################# -# Load Protobuf dependencies -############################# - -# rules_python and zlib are required by protobuf. -# TODO(ronshapiro): Figure out if zlib is in fact necessary, or if proto can depend on the -# @bazel_tools library directly. See discussion in -# https://github.com/protocolbuffers/protobuf/pull/5389#issuecomment-481785716 -# TODO(cpovirk): Should we eventually get rules_python from "Bazel Federation?" -# https://github.com/bazelbuild/rules_python#getting-started - -http_archive( - name = "rules_python", - sha256 = "e5470e92a18aa51830db99a4d9c492cc613761d5bdb7131c04bd92b9834380f6", - strip_prefix = "rules_python-4b84ad270387a7c439ebdccfd530e2339601ef27", - urls = ["https://github.com/bazelbuild/rules_python/archive/4b84ad270387a7c439ebdccfd530e2339601ef27.tar.gz"], -) - -http_archive( - name = "zlib", - build_file = "@com_google_protobuf//:third_party/zlib.BUILD", - sha256 = "629380c90a77b964d896ed37163f5c3a34f6e6d897311f1df2a7016355c45eff", - strip_prefix = "zlib-1.2.11", - urls = ["https://github.com/madler/zlib/archive/v1.2.11.tar.gz"], +android_sdk_repository( + name = "androidsdk", + api_level = 32, + build_tools_version = "32.0.0", ) -############################# -# Load Robolectric repository -############################# - -ROBOLECTRIC_VERSION = "4.4" - -http_archive( - name = "robolectric", - sha256 = "d4f2eb078a51f4e534ebf5e18b6cd4646d05eae9b362ac40b93831bdf46112c7", - strip_prefix = "robolectric-bazel-%s" % ROBOLECTRIC_VERSION, - urls = ["https://github.com/robolectric/robolectric-bazel/archive/%s.tar.gz" % ROBOLECTRIC_VERSION], -) - -load("@robolectric//bazel:robolectric.bzl", "robolectric_repositories") - -robolectric_repositories() - ############################# # Load Kotlin repository ############################# -RULES_KOTLIN_TAG = "v1.8" - -RULES_KOTLIN_SHA = "01293740a16e474669aba5b5a1fe3d368de5832442f164e4fbfc566815a8bc3a" - -http_archive( - name = "io_bazel_rules_kotlin", - sha256 = RULES_KOTLIN_SHA, - urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/%s/rules_kotlin_release.tgz" % RULES_KOTLIN_TAG], -) - load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories", "kotlinc_version") KOTLIN_VERSION = "1.9.23" @@ -172,23 +60,24 @@ kt_register_toolchains() # Load Maven dependencies ############################# -RULES_JVM_EXTERNAL_TAG = "4.5" - -RULES_JVM_EXTERNAL_SHA = "b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6" - -http_archive( - name = "rules_jvm_external", - sha256 = RULES_JVM_EXTERNAL_SHA, - strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG, - url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG, -) - load("@rules_jvm_external//:defs.bzl", "maven_install") ANDROID_LINT_VERSION = "30.1.0" +ANT_VERSION = "1.9.6" + +ASM_VERSION = "9.6" + AUTO_COMMON_VERSION = "1.2.1" +BYTE_BUDDY_VERSION = "1.9.10" + +CHECKER_FRAMEWORK_VERSION = "2.5.3" + +ECLIPSE_SISU_VERSION = "0.3.0" + +ERROR_PRONE_VERSION = "2.14.0" + # NOTE(bcorso): Even though we set the version here, our Guava version in # processor code will use whatever version is built into JavaBuilder, which is # tied to the version of Bazel we're using. @@ -198,14 +87,10 @@ GRPC_VERSION = "1.2.0" INCAP_VERSION = "0.2" -BYTE_BUDDY_VERSION = "1.9.10" - -CHECKER_FRAMEWORK_VERSION = "2.5.3" - -ERROR_PRONE_VERSION = "2.14.0" - KSP_VERSION = KOTLIN_VERSION + "-1.0.19" +MAVEN_VERSION = "3.3.3" + maven_install( artifacts = [ "androidx.annotation:annotation:1.1.0", @@ -264,6 +149,7 @@ maven_install( "io.grpc:grpc-protobuf:%s" % GRPC_VERSION, "jakarta.inject:jakarta.inject-api:2.0.1", "javax.annotation:javax.annotation-api:1.3.2", + "javax.enterprise:cdi-api:1.0", "javax.inject:javax.inject:1", "javax.inject:javax.inject-tck:1", "junit:junit:4.13", @@ -271,9 +157,19 @@ maven_install( "net.bytebuddy:byte-buddy-agent:%s" % BYTE_BUDDY_VERSION, "net.ltgt.gradle.incap:incap:%s" % INCAP_VERSION, "net.ltgt.gradle.incap:incap-processor:%s" % INCAP_VERSION, + "org.apache.ant:ant:%s" % ANT_VERSION, + "org.apache.ant:ant-launcher:%s" % ANT_VERSION, + "org.apache.maven:maven-artifact:%s" % MAVEN_VERSION, + "org.apache.maven:maven-model:%s" % MAVEN_VERSION, + "org.apache.maven:maven-plugin-api:%s" % MAVEN_VERSION, "org.checkerframework:checker-compat-qual:%s" % CHECKER_FRAMEWORK_VERSION, "org.checkerframework:dataflow:%s" % CHECKER_FRAMEWORK_VERSION, "org.checkerframework:javacutil:%s" % CHECKER_FRAMEWORK_VERSION, + "org.codehaus.plexus:plexus-utils:3.0.20", + "org.codehaus.plexus:plexus-classworlds:2.5.2", + "org.codehaus.plexus:plexus-component-annotations:1.5.5", + "org.eclipse.sisu:org.eclipse.sisu.plexus:%s" % ECLIPSE_SISU_VERSION, + "org.eclipse.sisu:org.eclipse.sisu.inject:%s" % ECLIPSE_SISU_VERSION, "org.hamcrest:hamcrest-core:1.3", "org.jetbrains.kotlin:kotlin-annotation-processing-embeddable:%s" % KOTLIN_VERSION, "org.jetbrains.kotlin:kotlin-compiler-embeddable:%s" % KOTLIN_VERSION, @@ -282,7 +178,11 @@ maven_install( "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.6.2", "org.jspecify:jspecify:0.3.0", "org.mockito:mockito-core:2.28.2", + "org.pantsbuild:jarjar:1.7.2", "org.objenesis:objenesis:1.0", + "org.ow2.asm:asm:%s" % ASM_VERSION, + "org.ow2.asm:asm-tree:%s" % ASM_VERSION, + "org.ow2.asm:asm-commons:%s" % ASM_VERSION, "org.robolectric:robolectric:4.4", "org.robolectric:shadows-framework:4.4", # For ActivityController ], diff --git a/build_defs.bzl b/build_defs.bzl index 70afaf0bfb1..3dd0647ca89 100644 --- a/build_defs.bzl +++ b/build_defs.bzl @@ -18,8 +18,6 @@ DOCLINT_HTML_AND_SYNTAX = ["-Xdoclint:html,syntax"] DOCLINT_REFERENCES = ["-Xdoclint:reference"] -JAVA_RELEASE_MIN = [ - "-source 7 -target 7", -] +JAVA_RELEASE_MIN = ["-source 8 -target 8"] POM_VERSION = "${project.version}" diff --git a/gwt/BUILD b/gwt/BUILD index 8238d50e26b..87b7c957aa8 100644 --- a/gwt/BUILD +++ b/gwt/BUILD @@ -17,7 +17,7 @@ load("@rules_java//java:defs.bzl", "java_library") load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "pom_file") +load("//tools/maven:maven.bzl", "dagger_pom_file") package(default_visibility = ["//:src"]) @@ -41,7 +41,7 @@ java_library( visibility = ["//visibility:private"], ) -pom_file( +dagger_pom_file( name = "pom", artifact_id = "dagger-gwt", artifact_name = "Dagger GWT", diff --git a/java/dagger/BUILD b/java/dagger/BUILD index 5572b503e55..28ec2ddd194 100644 --- a/java/dagger/BUILD +++ b/java/dagger/BUILD @@ -22,7 +22,7 @@ load( "JAVA_RELEASE_MIN", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) diff --git a/java/dagger/android/BUILD b/java/dagger/android/BUILD index 686e6aef5a3..e8e0824ba22 100644 --- a/java/dagger/android/BUILD +++ b/java/dagger/android/BUILD @@ -21,9 +21,9 @@ load( ) load("//tools:dejetify.bzl", "dejetified_library") load( - "//tools:maven.bzl", + "//tools/maven:maven.bzl", + "dagger_pom_file", "gen_maven_artifact", - "pom_file", ) package(default_visibility = ["//:src"]) @@ -94,7 +94,7 @@ android_library( ], ) -pom_file( +dagger_pom_file( name = "legacy-pom", artifact_id = "dagger-android-legacy", artifact_name = "Dagger Android Legacy", diff --git a/java/dagger/android/processor/BUILD b/java/dagger/android/processor/BUILD index f70c09102ab..16b662e7d00 100644 --- a/java/dagger/android/processor/BUILD +++ b/java/dagger/android/processor/BUILD @@ -22,7 +22,7 @@ load( "DOCLINT_REFERENCES", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) diff --git a/java/dagger/android/support/BUILD b/java/dagger/android/support/BUILD index 2f4c407b87a..78fed6617a3 100644 --- a/java/dagger/android/support/BUILD +++ b/java/dagger/android/support/BUILD @@ -21,9 +21,9 @@ load( ) load("//tools:dejetify.bzl", "dejetified_library") load( - "//tools:maven.bzl", + "//tools/maven:maven.bzl", + "dagger_pom_file", "gen_maven_artifact", - "pom_file", ) package(default_visibility = ["//:src"]) @@ -57,13 +57,13 @@ gen_maven_artifact( artifact_name = "Dagger Android Support", artifact_target = ":support", artifact_target_maven_deps = [ - "androidx.activity:activity", + "androidx.activity:activity:aar", "androidx.annotation:annotation", - "androidx.appcompat:appcompat", - "androidx.fragment:fragment", + "androidx.appcompat:appcompat:aar", + "androidx.fragment:fragment:aar", "androidx.lifecycle:lifecycle-common", - "androidx.lifecycle:lifecycle-viewmodel", - "androidx.lifecycle:lifecycle-viewmodel-savedstate", + "androidx.lifecycle:lifecycle-viewmodel:aar", + "androidx.lifecycle:lifecycle-viewmodel-savedstate:aar", "com.google.dagger:dagger", "com.google.dagger:dagger-android", ], @@ -95,7 +95,7 @@ android_library( ], ) -pom_file( +dagger_pom_file( name = "legacy-pom", artifact_id = "dagger-android-support-legacy", artifact_name = "Dagger Android Legacy Support", diff --git a/java/dagger/grpc/server/BUILD b/java/dagger/grpc/server/BUILD index 3c4e2f41b8f..83d96e8cd09 100644 --- a/java/dagger/grpc/server/BUILD +++ b/java/dagger/grpc/server/BUILD @@ -1,6 +1,5 @@ # A framework supporting Dagger-injected gRPC servers. -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") load("@rules_java//java:defs.bzl", "java_library") load( "//:build_defs.bzl", @@ -8,7 +7,8 @@ load( "DOCLINT_REFERENCES", "POM_VERSION", ) -load("//tools:maven.bzl", "pom_file") +load("//tools/javadoc:javadoc.bzl", "javadoc_library") +load("//tools/maven:maven.bzl", "dagger_pom_file") package(default_visibility = ["//:src"]) @@ -53,14 +53,14 @@ java_library( ], ) -pom_file( +dagger_pom_file( name = "annotations-pom", artifact_id = "dagger-grpc-server-annotations", artifact_name = "Dagger gRPC Server Annotations", targets = [":annotations"], ) -pom_file( +dagger_pom_file( name = "server-pom", artifact_id = "dagger-grpc-server", artifact_name = "Dagger gRPC Server", diff --git a/java/dagger/grpc/server/processor/BUILD b/java/dagger/grpc/server/processor/BUILD index 1c8d2263e51..79a2cfb75c1 100644 --- a/java/dagger/grpc/server/processor/BUILD +++ b/java/dagger/grpc/server/processor/BUILD @@ -1,11 +1,11 @@ -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") load("@rules_java//java:defs.bzl", "java_library", "java_plugin") load( "//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX", "POM_VERSION", ) -load("//tools:maven.bzl", "pom_file") +load("//tools/javadoc:javadoc.bzl", "javadoc_library") +load("//tools/maven:maven.bzl", "dagger_pom_file") package(default_visibility = ["//:src"]) @@ -28,7 +28,7 @@ java_library( ], ) -pom_file( +dagger_pom_file( name = "pom", artifact_id = "dagger-grpc-server-processor", artifact_name = "Dagger gRPC Server Processor", diff --git a/java/dagger/hilt/BUILD b/java/dagger/hilt/BUILD index 7d2b26e977b..cad92104d17 100644 --- a/java/dagger/hilt/BUILD +++ b/java/dagger/hilt/BUILD @@ -13,7 +13,7 @@ # limitations under the License. load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") # Description: # A library that wraps the Dagger API to make DI usage and testing easier. diff --git a/java/dagger/hilt/android/BUILD b/java/dagger/hilt/android/BUILD index b30f6625dd3..e10c5e02778 100644 --- a/java/dagger/hilt/android/BUILD +++ b/java/dagger/hilt/android/BUILD @@ -16,7 +16,7 @@ # A library based on Hilt that provides standard components and automated injection for Android. load("//:build_defs.bzl", "POM_VERSION") load("//tools:bazel_compat.bzl", "compat_kt_android_library") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -228,14 +228,14 @@ gen_maven_artifact( "//java/dagger/hilt/internal/componenttreedeps:componenttreedeps", ], artifact_target_maven_deps = [ - "androidx.activity:activity", + "androidx.activity:activity:aar", "androidx.annotation:annotation", - "androidx.annotation:annotation-experimental", - "androidx.fragment:fragment", + "androidx.annotation:annotation-experimental:aar", + "androidx.fragment:fragment:aar", "androidx.lifecycle:lifecycle-common", - "androidx.lifecycle:lifecycle-viewmodel", - "androidx.lifecycle:lifecycle-viewmodel-savedstate", - "androidx.savedstate:savedstate", + "androidx.lifecycle:lifecycle-viewmodel:aar", + "androidx.lifecycle:lifecycle-viewmodel-savedstate:aar", + "androidx.savedstate:savedstate:aar", "com.google.code.findbugs:jsr305", "com.google.dagger:dagger-lint-aar", "com.google.dagger:dagger", diff --git a/java/dagger/hilt/android/processor/BUILD b/java/dagger/hilt/android/processor/BUILD index bf5a6c3b539..f76f29062dc 100644 --- a/java/dagger/hilt/android/processor/BUILD +++ b/java/dagger/hilt/android/processor/BUILD @@ -16,7 +16,7 @@ # Hilt android processors. load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) diff --git a/java/dagger/hilt/android/testing/BUILD b/java/dagger/hilt/android/testing/BUILD index ee3d78ab16f..49ab154056b 100644 --- a/java/dagger/hilt/android/testing/BUILD +++ b/java/dagger/hilt/android/testing/BUILD @@ -15,7 +15,7 @@ # Testing libraries for Hilt Android. load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -227,16 +227,16 @@ gen_maven_artifact( "//java/dagger/hilt/android/testing:uninstall_modules", ], artifact_target_maven_deps = [ - "androidx.activity:activity", + "androidx.activity:activity:aar", "androidx.annotation:annotation", - "androidx.annotation:annotation-experimental", - "androidx.fragment:fragment", + "androidx.annotation:annotation-experimental:aar", + "androidx.fragment:fragment:aar", "androidx.lifecycle:lifecycle-common", - "androidx.lifecycle:lifecycle-viewmodel", - "androidx.lifecycle:lifecycle-viewmodel-savedstate", - "androidx.multidex:multidex", - "androidx.savedstate:savedstate", - "androidx.test:core", + "androidx.lifecycle:lifecycle-viewmodel:aar", + "androidx.lifecycle:lifecycle-viewmodel-savedstate:aar", + "androidx.multidex:multidex:aar", + "androidx.savedstate:savedstate:aar", + "androidx.test:core:aar", "com.google.code.findbugs:jsr305", "com.google.dagger:dagger", "com.google.dagger:hilt-android", diff --git a/java/dagger/hilt/processor/BUILD b/java/dagger/hilt/processor/BUILD index ecbc2949500..c46feff1d5e 100644 --- a/java/dagger/hilt/processor/BUILD +++ b/java/dagger/hilt/processor/BUILD @@ -16,7 +16,7 @@ # Hilt android processors. load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) diff --git a/java/dagger/internal/codegen/BUILD b/java/dagger/internal/codegen/BUILD index 80ca8d7dc5e..2de6ffc4c9f 100644 --- a/java/dagger/internal/codegen/BUILD +++ b/java/dagger/internal/codegen/BUILD @@ -20,7 +20,7 @@ load( "//:build_defs.bzl", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) diff --git a/java/dagger/lint/BUILD b/java/dagger/lint/BUILD index d071c033b4b..2d95571de86 100644 --- a/java/dagger/lint/BUILD +++ b/java/dagger/lint/BUILD @@ -17,7 +17,7 @@ load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) diff --git a/java/dagger/producers/BUILD b/java/dagger/producers/BUILD index 0dfd4d96f37..5bc7a5bb52d 100644 --- a/java/dagger/producers/BUILD +++ b/java/dagger/producers/BUILD @@ -23,7 +23,7 @@ load( "JAVA_RELEASE_MIN", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) diff --git a/java/dagger/spi/BUILD b/java/dagger/spi/BUILD index 8084e639669..c155dd261d7 100644 --- a/java/dagger/spi/BUILD +++ b/java/dagger/spi/BUILD @@ -22,7 +22,7 @@ load( "DOCLINT_REFERENCES", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) diff --git a/javatests/dagger/internal/codegen/BUILD b/javatests/dagger/internal/codegen/BUILD index b189fe5b33d..ce67ca0a913 100644 --- a/javatests/dagger/internal/codegen/BUILD +++ b/javatests/dagger/internal/codegen/BUILD @@ -72,7 +72,7 @@ java_library( "//third_party/java/guava/collect", "//third_party/java/javapoet", "//third_party/java/truth", - "@com_google_auto_value_auto_value//jar", + "@maven//:com_google_auto_value_auto_value", ], ) @@ -110,7 +110,7 @@ DEPS = [ "//third_party/java/guava/collect", "//third_party/java/guava/util/concurrent", "//third_party/java/auto:value", - "@com_google_auto_value_auto_value//jar", + "@maven//:com_google_auto_value_auto_value", "//third_party/java/auto:common", "//third_party/java/compile_testing", "//third_party/java/javapoet", diff --git a/third_party/java/auto/BUILD b/third_party/java/auto/BUILD index 93e7e5b4c60..48ad091f151 100644 --- a/third_party/java/auto/BUILD +++ b/third_party/java/auto/BUILD @@ -26,7 +26,6 @@ alias( java_plugin( name = "auto_value_processor", processor_class = "com.google.auto.value.processor.AutoValueProcessor", - visibility = ["//visibility:private"], deps = [ ":common", ":service", diff --git a/tools/BUILD b/tools/BUILD index 3be21e25471..035bdbaf265 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -16,34 +16,9 @@ # Tools for Dagger load("@bazel_skylib//:bzl_library.bzl", "bzl_library") -load(":maven_info.bzl", "maven_info_tests") package(default_visibility = ["//:src"]) -maven_info_tests() - -exports_files([ - "pom-template.xml", -]) - -bzl_library( - name = "maven_bzl", - srcs = ["maven.bzl"], - deps = [ - ":maven_info_bzl", - "@rules_java//java:rules", - ], -) - -bzl_library( - name = "maven_info_bzl", - srcs = ["maven_info.bzl"], - deps = [ - "@bazel_skylib//lib:unittest", - "@rules_java//java:rules", - ], -) - bzl_library( name = "dejetify_bzl", srcs = ["dejetify.bzl"], diff --git a/tools/jarjar/BUILD b/tools/jarjar/BUILD new file mode 100644 index 00000000000..6bcfba0708a --- /dev/null +++ b/tools/jarjar/BUILD @@ -0,0 +1,50 @@ +# Copyright (C) 2024 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Starlark rules for using jarjar + +load("@rules_java//java:defs.bzl", "java_binary") + +package(default_visibility = ["//:src"]) + +java_binary( + name = "jarjar", + main_class = "org.pantsbuild.jarjar.Main", + visibility = ["//visibility:public"], + runtime_deps = [ + "//third_party/java/asm", + "//third_party/java/asm:asm-commons", + "//third_party/java/asm:asm-tree", + "//third_party/java/jsr250_annotations", + "//third_party/java/jsr330_inject", + "@maven//:javax_enterprise_cdi_api", + "@maven//:org_apache_ant_ant", + "@maven//:org_apache_ant_ant_launcher", + "@maven//:org_apache_maven_maven_artifact", + "@maven//:org_apache_maven_maven_model", + "@maven//:org_apache_maven_maven_plugin_api", + "@maven//:org_codehaus_plexus_plexus_classworlds", + "@maven//:org_codehaus_plexus_plexus_component_annotations", + "@maven//:org_codehaus_plexus_plexus_utils", + "@maven//:org_eclipse_sisu_org_eclipse_sisu_inject", + "@maven//:org_eclipse_sisu_org_eclipse_sisu_plexus", + "@maven//:org_pantsbuild_jarjar", + ], +) + +sh_binary( + name = "jarjar_runner", + srcs = ["jarjar_runner.sh"], + visibility = ["//visibility:public"], +) diff --git a/tools/jarjar/jarjar.bzl b/tools/jarjar/jarjar.bzl new file mode 100644 index 00000000000..2fa6554f212 --- /dev/null +++ b/tools/jarjar/jarjar.bzl @@ -0,0 +1,92 @@ +# Copyright (C) 2024 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Skylark rules for jarjar. See https://github.com/pantsbuild/jarjar +""" + +load("@rules_java//java:defs.bzl", "java_common") + +def _jarjar_library(ctx): + ctx.actions.write( + output = ctx.outputs._rules_file, + content = "\n".join(ctx.attr.rules), + ) + + jar_files = depset(transitive = [jar.files for jar in ctx.attr.jars]).to_list() + + command = """ + export JAVA_HOME="{java_home}" + export MERGE_META_INF_FILES="{merge_meta_inf_files}" + export JARJAR="{jarjar}" + export RULES_FILE="{rules_file}" + export OUTFILE="{outfile}" + "{jarjar_runner}" {jars} + """.format( + java_home = str(ctx.attr._jdk[java_common.JavaRuntimeInfo].java_home), + merge_meta_inf_files = " ".join(ctx.attr.merge_meta_inf_files), + jarjar = ctx.executable._jarjar.path, + rules_file = ctx.outputs._rules_file.path, + outfile = ctx.outputs.jar.path, + jarjar_runner = ctx.executable._jarjar_runner.path, + jars = " ".join([jar.path for jar in jar_files]), + ) + + ctx.actions.run_shell( + command = command, + inputs = [ctx.outputs._rules_file] + jar_files + ctx.files._jdk, + outputs = [ctx.outputs.jar], + tools = [ctx.executable._jarjar, ctx.executable._jarjar_runner], + ) + +_jarjar_library_attrs = { + "rules": attr.string_list(), + "jars": attr.label_list( + allow_files = [".jar"], + ), + "merge_meta_inf_files": attr.string_list( + allow_empty = True, + default = [], + mandatory = False, + doc = """A list of regular expressions that match files relative to the + META-INF directory that will be merged into the output jar, in addition + to files in META-INF/services. To add all files in META-INF/foo, for + example, use "foo/.*".""", + ), +} + +_jarjar_library_attrs.update({ + "_jarjar": attr.label( + default = Label("//tools/jarjar"), + executable = True, + cfg = "exec", + ), + "_jarjar_runner": attr.label( + default = Label("//tools/jarjar:jarjar_runner"), + executable = True, + cfg = "exec", + ), + "_jdk": attr.label( + default = Label("@bazel_tools//tools/jdk:current_java_runtime"), + providers = [java_common.JavaRuntimeInfo], + ), +}) + +jarjar_library = rule( + attrs = _jarjar_library_attrs, + outputs = { + "jar": "%{name}.jar", + "_rules_file": "%{name}.jarjar_rules", + }, + implementation = _jarjar_library, +) diff --git a/tools/jarjar/jarjar_runner.sh b/tools/jarjar/jarjar_runner.sh new file mode 100755 index 00000000000..20bc27ca764 --- /dev/null +++ b/tools/jarjar/jarjar_runner.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# Copyright (C) 2024 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +JAVA_HOME="$(cd "${JAVA_HOME}" && pwd)" # this is used outside of the root + +TMPDIR="$(mktemp -d)" +for jar in "$@"; do + unzip -qq -B "${jar}" -d "${TMPDIR}" +done + +pushd "${TMPDIR}" &>/dev/null + +find=(find) +if [[ "$(uname -s)" == "Darwin" ]]; then + # Mac uses BSD find, which requires extra args for regex matching. + find+=(-E) + suffix='(~[0-9]*)?' +else + # Default to GNU find, which must escape parentheses. + suffix='\(~[0-9]*\)?' +fi + +# Concatenate similar files in META-INF that allow it. +for meta_inf_pattern in services/.* ${MERGE_META_INF_FILES}; do + regex="META-INF/${meta_inf_pattern}${suffix}" + for file in $("${find[@]}" META-INF -regex "${regex}"); do + original="$(sed s/"~[0-9]*$"// <<< "${file}")" + if [[ "${file}" != "${original}" ]]; then + cat "${file}" >> "${original}" + rm "${file}" + fi + done +done + +# build-data.properties is emitted by Bazel with target information that can +# cause conflicts. Delete it since it doesn't make sense to keep in the merged +# jar anyway. +rm build-data.properties* +rm META-INF/MANIFEST.MF* +rm -rf META-INF/maven/ +duplicate_files="$(find * -type f -regex '.*~[0-9]*$')" +if [[ -n "${duplicate_files}" ]]; then + echo "Error: duplicate files in merged jar: ${duplicate_files}" + exit 1 +fi +"${JAVA_HOME}/bin/jar" cf combined.jar * + +popd &>/dev/null + +"${JARJAR}" process "${RULES_FILE}" "${TMPDIR}/combined.jar" "${OUTFILE}" + +rm -rf "${TMPDIR}" diff --git a/tools/jarjar/test/BUILD b/tools/jarjar/test/BUILD new file mode 100644 index 00000000000..42659e68bb5 --- /dev/null +++ b/tools/jarjar/test/BUILD @@ -0,0 +1,43 @@ +# Copyright (C) 2024 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Starlark tests for jarjar + +load("//tools/jarjar:jarjar.bzl", "jarjar_library") + +# Test target used for validating rule. +jarjar_library( + name = "test_target", + testonly = 1, + jars = [ + ":test-library1.jar", + ":test-library2.jar", + ], + merge_meta_inf_files = ["utilities/libs.dep"], +) + +# Test that validates jarjar with merged META-INF files. +sh_test( + name = "validate_test_target", + srcs = [":jarjar_validator.sh"], + args = [ + "$(location :test_target.jar)", + "utilities/libs.dep", + "$(location :expected_libs.dep)", + ], + data = [ + ":expected_libs.dep", + ":test_target.jar", + ], +) diff --git a/tools/jarjar/test/expected_libs.dep b/tools/jarjar/test/expected_libs.dep new file mode 100644 index 00000000000..5e34c371d5f --- /dev/null +++ b/tools/jarjar/test/expected_libs.dep @@ -0,0 +1,2 @@ +Library2 +Library1 diff --git a/tools/jarjar/test/jarjar_validator.sh b/tools/jarjar/test/jarjar_validator.sh new file mode 100755 index 00000000000..ca64f9d887b --- /dev/null +++ b/tools/jarjar/test/jarjar_validator.sh @@ -0,0 +1,8 @@ +#!/bin/bash +if diff <(unzip -p "$1" "META-INF/$2") "$3"; then + echo Passed + exit 0 +else + echo Failed + exit 1 +fi diff --git a/tools/jarjar/test/test-library1.jar b/tools/jarjar/test/test-library1.jar new file mode 100644 index 0000000000000000000000000000000000000000..418894f3e59dfba7a12ee8323beec7a413aa0b8c GIT binary patch literal 753 zcmWIWW@Zs#VBp|jc-H6^zyJhHAOZ+D8CV#6T|*poJ^kGD|D9rBU}gwFQCzRmBx?m! zXbr?bBM^#x9sNArT!TaOeBD0#o;mH~t*dvD*IQTX+?n&6gAA@1KX_WC=jE&8>3gws z6$=-G>lYtUlRKY3UoH+3wfQ{ht4Za~ik(Pyr2`#ySnAWoc|be%0WlvC`(!2+B^Fg0 z>LuqS78hH8&A)EP#>Q667N^IS#->-smRH6m=f-9>`^=s*Le_3*+8bS0HGAnh=U;07yz{T!3gws z6$=-G>lYtUlRKY3UoH+3wfQ{ht4Za~ik(PyRRSHharc^-c|be%0WlvC`(!2+B^Fg0 z=_ThR78hH8&A)EP#>Q667N^IS#->-smRH6m=f-9>`^=s*Le_3T?UN@_u92qy!x;uf1Y5H79YW?*E|zRJ$P5**J64*;$JZ$>5&Q267BLZCHB03|}v zwW3ETLZ2>>3D=4gy~rkDizb8#Gl5LhNCWAWW5yLQ5@4;2KypcAGLVAXjxCs2A;E+e VL;>EcY#>uufKUo(#6gg03;=eQ#5w=~ literal 0 HcmV?d00001 diff --git a/tools/javadoc/BUILD b/tools/javadoc/BUILD new file mode 100644 index 00000000000..93553508bae --- /dev/null +++ b/tools/javadoc/BUILD @@ -0,0 +1,17 @@ +# Copyright (C) 2024 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Starlark rules for generating Javadoc + +package(default_visibility = ["//:src"]) diff --git a/tools/javadoc/javadoc.bzl b/tools/javadoc/javadoc.bzl new file mode 100644 index 00000000000..db7eccda980 --- /dev/null +++ b/tools/javadoc/javadoc.bzl @@ -0,0 +1,156 @@ +# Copyright (C) 2024 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""See javadoc_library.""" + +load("@rules_java//java:defs.bzl", "JavaInfo", "java_common") + +def _android_jar(android_api_level): + if android_api_level == -1: + return None + return Label("@androidsdk//:platforms/android-%s/android.jar" % android_api_level) + +def _javadoc_library(ctx): + transitive_deps = [] + for dep in ctx.attr.deps: + if JavaInfo in dep: + transitive_deps.append(dep[JavaInfo].transitive_compile_time_jars) + + if ctx.attr._android_jar: + transitive_deps.append(ctx.attr._android_jar.files) + + classpath = depset([], transitive = transitive_deps).to_list() + + java_home = str(ctx.attr._jdk[java_common.JavaRuntimeInfo].java_home) + + output_dir = ctx.actions.declare_directory("%s_javadoc" % ctx.attr.name) + + javadoc_arguments = ctx.actions.args() + javadoc_arguments.use_param_file("@%s", use_always = True) + javadoc_arguments.set_param_file_format("multiline") + + javadoc_command = java_home + "/bin/javadoc" + + javadoc_arguments.add("-use") + javadoc_arguments.add("-encoding", "UTF8") + javadoc_arguments.add_joined("-classpath", classpath, join_with = ":") + javadoc_arguments.add("-notimestamp") + javadoc_arguments.add("-d", output_dir.path) + javadoc_arguments.add("-Xdoclint:-missing") + javadoc_arguments.add("-quiet") + + # Documentation for the javadoc command + # https://docs.oracle.com/javase/9/javadoc/javadoc-command.htm + if ctx.attr.root_packages: + # TODO(b/167433657): Reevaluate the utility of root_packages + # 1. Find the first directory under the working directory named '*java'. + # 2. Assume all files to document can be found by appending a root_package name + # to that directory, or a subdirectory, replacing dots with slashes. + javadoc_command += ' -sourcepath $(find * -type d -name "*java" -print0 | tr "\\0" :) ' + javadoc_arguments.add_all(ctx.attr.root_packages) + javadoc_arguments.add_joined("-subpackages", ctx.attr.root_packages, join_with = ":") + else: + # Document exactly the code in the specified source files. + javadoc_arguments.add_all(ctx.files.srcs) + + if ctx.attr.doctitle: + javadoc_arguments.add("-doctitle", ctx.attr.doctitle, format = '"%s"') + + if ctx.attr.groups: + groups = [] + for k, v in ctx.attr.groups.items(): + groups.append("-group \"%s\" \"%s\"" % (k, ":".join(v))) + javadoc_arguments.add_all(groups) + + javadoc_arguments.add_joined("-exclude", ctx.attr.exclude_packages, join_with = ":") + + javadoc_arguments.add_all( + ctx.attr.external_javadoc_links, + map_each = _format_linkoffline_value, + ) + + if ctx.attr.bottom_text: + javadoc_arguments.add("-bottom", ctx.attr.bottom_text, format = '"%s"') + + # TODO(ronshapiro): Should we be using a different tool that doesn't include + # timestamp info? + jar_command = "%s/bin/jar cf %s -C %s ." % (java_home, ctx.outputs.jar.path, output_dir.path) + + srcs = depset(transitive = [src.files for src in ctx.attr.srcs]).to_list() + ctx.actions.run_shell( + inputs = srcs + classpath + ctx.files._jdk, + command = "%s $@ && %s" % (javadoc_command, jar_command), + arguments = [javadoc_arguments], + outputs = [output_dir, ctx.outputs.jar], + ) + +def _format_linkoffline_value(link): + return "-linkoffline {0} {0}".format(link) + +javadoc_library = rule( + attrs = { + "srcs": attr.label_list( + allow_empty = False, + allow_files = True, + doc = "Source files to generate Javadoc for.", + ), + "deps": attr.label_list( + doc = """ +Targets that contain references to other types referenced in Javadoc. These can +be the java_library/android_library target(s) for the same sources. +""", + ), + "doctitle": attr.string( + default = "", + doc = "Title for generated index.html. See javadoc -doctitle.", + ), + "groups": attr.string_list_dict( + doc = "Groups specified packages together in overview page. See javadoc -groups.", + ), + "root_packages": attr.string_list( + doc = """ +Java packages to include in generated Javadoc. Any subpackages not listed in +exclude_packages will be included as well. If none are provided, each file in +`srcs` is processed. +""", + ), + "exclude_packages": attr.string_list( + doc = "Java packages to exclude from generated Javadoc.", + ), + "android_api_level": attr.int( + default = -1, + doc = """ +If Android APIs are used, the API level to compile against to generate Javadoc. +""", + ), + "bottom_text": attr.string( + default = "", + doc = "Text passed to Javadoc's `-bottom` flag.", + ), + "external_javadoc_links": attr.string_list( + doc = "URLs passed to Javadoc's `-linkoffline` flag.", + ), + "_android_jar": attr.label( + default = _android_jar, + allow_single_file = True, + ), + "_jdk": attr.label( + default = Label("@bazel_tools//tools/jdk:current_java_runtime"), + providers = [java_common.JavaRuntimeInfo], + ), + }, + outputs = {"jar": "%{name}.jar"}, + doc = "Generates a Javadoc jar path/to/target/.jar.", + implementation = _javadoc_library, +) diff --git a/tools/maven/BUILD b/tools/maven/BUILD new file mode 100644 index 00000000000..c89314208dd --- /dev/null +++ b/tools/maven/BUILD @@ -0,0 +1,45 @@ +# Copyright (C) 2024 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Skylark rules for generating Maven pom files + +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load(":maven_info.bzl", "maven_info_tests") +load(":pom_file.bzl", "pom_file_tests") + +package(default_visibility = ["//:src"]) + +exports_files(["pom-template.xml"]) + +bzl_library( + name = "maven_bzl", + srcs = ["maven.bzl"], + deps = [ + ":maven_info_bzl", + "@rules_java//java:rules", + ], +) + +bzl_library( + name = "maven_info_bzl", + srcs = ["maven_info.bzl"], + deps = [ + "@bazel_skylib//lib:unittest", + "@rules_java//java:rules", + ], +) + +maven_info_tests() + +pom_file_tests() diff --git a/tools/maven.bzl b/tools/maven/maven.bzl similarity index 97% rename from tools/maven.bzl rename to tools/maven/maven.bzl index 89c7a4fb4b4..29036550e48 100644 --- a/tools/maven.bzl +++ b/tools/maven/maven.bzl @@ -14,26 +14,26 @@ """Macros to simplify generating maven files. """ -load("@google_bazel_common//tools/jarjar:jarjar.bzl", "jarjar_library") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") -load("@google_bazel_common//tools/maven:pom_file.bzl", default_pom_file = "pom_file") load("@rules_java//java:defs.bzl", "java_binary") +load("//tools/jarjar:jarjar.bzl", "jarjar_library") +load("//tools/javadoc:javadoc.bzl", "javadoc_library") load(":maven_info.bzl", "MavenInfo", "collect_maven_info") +load(":pom_file.bzl", "pom_file") SHADED_MAVEN_DEPS = [ "com.google.auto:auto-common", "org.jetbrains.kotlinx:kotlinx-metadata-jvm", ] -def pom_file(name, targets, artifact_name, artifact_id, packaging = None, **kwargs): - default_pom_file( +def dagger_pom_file(name, targets, artifact_name, artifact_id, packaging = None, **kwargs): + pom_file( name = name, targets = targets, preferred_group_ids = [ "com.google.dagger", "com.google", ], - template_file = "//tools:pom-template.xml", + template_file = "//tools/maven:pom-template.xml", substitutions = { "{artifact_name}": artifact_name, "{artifact_id}": artifact_id, @@ -174,7 +174,7 @@ def _gen_maven_artifact( ] artifact_id = artifact_coordinates.split(":")[1] - pom_file( + dagger_pom_file( name = pom_name, testonly = testonly, artifact_id = artifact_id, diff --git a/tools/maven_info.bzl b/tools/maven/maven_info.bzl similarity index 100% rename from tools/maven_info.bzl rename to tools/maven/maven_info.bzl diff --git a/tools/pom-template.xml b/tools/maven/pom-template.xml similarity index 100% rename from tools/pom-template.xml rename to tools/maven/pom-template.xml diff --git a/tools/maven/pom_file.bzl b/tools/maven/pom_file.bzl new file mode 100644 index 00000000000..52d32b13252 --- /dev/null +++ b/tools/maven/pom_file.bzl @@ -0,0 +1,361 @@ +# Copyright (C) 2024 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Skylark rules to make publishing Maven artifacts simpler. +""" + +load("@rules_java//java:defs.bzl", "java_library") +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") + +MavenInfo = provider( + fields = { + "maven_artifacts": """ + The Maven coordinates for the artifacts that are exported by this target: i.e. the target + itself and its transitively exported targets. + """, + "maven_dependencies": """ + The Maven coordinates of the direct dependencies, and the transitively exported targets, of + this target. + """, + }, +) + +_EMPTY_MAVEN_INFO = MavenInfo( + maven_artifacts = depset(), + maven_dependencies = depset(), +) + +_MAVEN_COORDINATES_PREFIX = "maven_coordinates=" + +def _maven_artifacts(targets): + return [target[MavenInfo].maven_artifacts for target in targets if MavenInfo in target] + +def _collect_maven_info_impl(_target, ctx): + tags = getattr(ctx.rule.attr, "tags", []) + deps = getattr(ctx.rule.attr, "deps", []) + exports = getattr(ctx.rule.attr, "exports", []) + runtime_deps = getattr(ctx.rule.attr, "runtime_deps", []) + + maven_artifacts = [] + for tag in tags: + if tag in ("maven:compile_only", "maven:shaded"): + return [_EMPTY_MAVEN_INFO] + if tag.startswith(_MAVEN_COORDINATES_PREFIX): + maven_artifacts.append(tag[len(_MAVEN_COORDINATES_PREFIX):]) + + return [MavenInfo( + maven_artifacts = depset(maven_artifacts, transitive = _maven_artifacts(exports)), + maven_dependencies = depset( + [], + transitive = _maven_artifacts(deps + exports + runtime_deps), + ), + )] + +_collect_maven_info = aspect( + attr_aspects = [ + "deps", + "exports", + "runtime_deps", + ], + doc = """ + Collects the Maven information for targets, their dependencies, and their transitive exports. + """, + implementation = _collect_maven_info_impl, +) + +def _prefix_index_of(item, prefixes): + """Returns the index of the first value in `prefixes` that is a prefix of `item`. + + If none of the prefixes match, return the size of `prefixes`. + + Args: + item: the item to match + prefixes: prefixes to match against + + Returns: + an integer representing the index of the match described above. + """ + for index, prefix in enumerate(prefixes): + if item.startswith(prefix): + return index + return len(prefixes) + +def _sort_artifacts(artifacts, prefixes): + """Sorts `artifacts`, preferring group ids that appear earlier in `prefixes`. + + Values in `prefixes` do not need to be complete group ids. For example, passing `prefixes = + ['io.bazel']` will match `io.bazel.rules:rules-artifact:1.0`. If multiple prefixes match an + artifact, the first one in `prefixes` will be used. + + _Implementation note_: Skylark does not support passing a comparator function to the `sorted()` + builtin, so this constructs a list of tuples with elements: + - `[0]` = an integer corresponding to the index in `prefixes` that matches the artifact (see + `_prefix_index_of`) + - `[1]` = parts of the complete artifact, split on `:`. This is used as a tiebreaker when + multilple artifacts have the same index referenced in `[0]`. The individual parts are used so + that individual artifacts in the same group are sorted correctly - if just the string is used, + the colon that separates the artifact name from the version will sort lower than a longer + name. For example: + - `com.example.project:base:1 + - `com.example.project:extension:1 + "base" sorts lower than "exension". + - `[2]` = the complete artifact. this is a convenience so that after sorting, the artifact can + be returned. + + The `sorted` builtin will first compare the index element and if it needs a tiebreaker, will + recursively compare the contents of the second element. + + Args: + artifacts: artifacts to be sorted + prefixes: the preferred group ids used to sort `artifacts` + + Returns: + A new, sorted list containing the contents of `artifacts`. + """ + indexed = [] + for artifact in artifacts: + parts = artifact.split(":") + indexed.append((_prefix_index_of(parts[0], prefixes), parts, artifact)) + + return [x[-1] for x in sorted(indexed)] + +DEP_BLOCK = """ + + {0} + {1} + {2} + +""".strip() + +CLASSIFIER_DEP_BLOCK = """ + + {0} + {1} + {2} + {3} + {4} + +""".strip() + +DEP_PKG_BLOCK = """ + + {0} + {1} + {2} + {3} + +""".strip() + +def _pom_file(ctx): + mvn_deps = depset( + [], + transitive = [target[MavenInfo].maven_dependencies for target in ctx.attr.targets], + ) + + formatted_deps = [] + for dep in _sort_artifacts(mvn_deps.to_list(), ctx.attr.preferred_group_ids): + parts = dep.split(":") + if ":".join(parts[0:2]) in ctx.attr.excluded_artifacts: + continue + if len(parts) == 3: + template = DEP_BLOCK + elif len(parts) == 4: + template = DEP_PKG_BLOCK + elif len(parts) == 5: + template = CLASSIFIER_DEP_BLOCK + else: + fail("Unknown dependency format: %s" % dep) + + formatted_deps.append(template.format(*parts)) + + substitutions = {} + substitutions.update(ctx.attr.substitutions) + substitutions.update({ + "{generated_bzl_deps}": "\n".join(formatted_deps), + "{pom_version}": ctx.var.get("pom_version", "LOCAL-SNAPSHOT"), + }) + + ctx.actions.expand_template( + template = ctx.file.template_file, + output = ctx.outputs.pom_file, + substitutions = substitutions, + ) + +pom_file = rule( + attrs = { + "template_file": attr.label( + allow_single_file = True, + ), + "substitutions": attr.string_dict( + allow_empty = True, + mandatory = False, + ), + "targets": attr.label_list( + mandatory = True, + aspects = [_collect_maven_info], + ), + "preferred_group_ids": attr.string_list(), + "excluded_artifacts": attr.string_list(), + }, + doc = """ + Creates a Maven POM file for `targets`. + + This rule scans the deps, runtime_deps, and exports of `targets` and their transitive exports, + checking each for tags of the form `maven_coordinates=`. These tags are used to build + the list of Maven dependencies for the generated POM. + + Users should call this rule with a `template_file` that contains a `{generated_bzl_deps}` + placeholder. The rule will replace this with the appropriate XML for all dependencies. + Additional placeholders to replace can be passed via the `substitutions` argument. + + The dependencies included will be sorted alphabetically by groupId, then by artifactId. The + `preferred_group_ids` can be used to specify groupIds (or groupId-prefixes) that should be + sorted ahead of other artifacts. Artifacts in the same group will be sorted alphabetically. + + Args: + name: the name of target. The generated POM file will use this name, with `.xml` appended + targets: a list of build target(s) that represent this POM file + template_file: a pom.xml file that will be used as a template for the generated POM + substitutions: an optional mapping of placeholders to replacement values that will be applied + to the `template_file` (e.g. `{'GROUP_ID': 'com.example.group'}`). `{pom_version}` is + implicitly included in this mapping and can be configured by passing `bazel build + --define=pom_version=`. + preferred_group_ids: an optional list of maven groupIds that will be used to sort the + generated deps. + excluded_artifacts: an optional list of maven artifacts in the format "groupId:artifactId" + that should be excluded from the generated pom file. + """, + outputs = {"pom_file": "%{name}.xml"}, + implementation = _pom_file, +) + +def _fake_java_library(name, deps = None, exports = None, runtime_deps = None): + src_file = ["%s.java" % name] + native.genrule( + name = "%s_source_file" % name, + outs = src_file, + cmd = "echo 'class %s {}' > $@" % name, + ) + java_library( + name = name, + srcs = src_file, + tags = ["maven_coordinates=%s:_:_" % name], + javacopts = ["-Xep:DefaultPackage:OFF"], + deps = deps or [], + exports = exports or [], + runtime_deps = runtime_deps or [], + ) + +def _maven_info_test_impl(ctx): + env = unittest.begin(ctx) + asserts.equals( + env, + expected = sorted(ctx.attr.maven_artifacts), + actual = sorted(ctx.attr.target[MavenInfo].maven_artifacts.to_list()), + msg = "MavenInfo.maven_artifacts", + ) + asserts.equals( + env, + expected = sorted(ctx.attr.maven_dependencies), + actual = sorted(ctx.attr.target[MavenInfo].maven_dependencies.to_list()), + msg = "MavenInfo.maven_dependencies", + ) + return unittest.end(env) + +_maven_info_test = unittest.make( + _maven_info_test_impl, + attrs = { + "target": attr.label(aspects = [_collect_maven_info]), + "maven_artifacts": attr.string_list(), + "maven_dependencies": attr.string_list(), + }, +) + +def pom_file_tests(): + """Tests for `pom_file` and `MavenInfo`. + """ + _fake_java_library(name = "FileA") + _maven_info_test( + name = "FileA_test", + target = ":FileA", + maven_artifacts = ["FileA:_:_"], + maven_dependencies = [], + ) + + _fake_java_library( + name = "DepOnFileA", + deps = [":FileA"], + ) + _maven_info_test( + name = "DepOnFileA_test", + target = ":DepOnFileA", + maven_artifacts = ["DepOnFileA:_:_"], + maven_dependencies = ["FileA:_:_"], + ) + + _fake_java_library( + name = "RuntimeDepOnFileA", + runtime_deps = [":FileA"], + ) + _maven_info_test( + name = "RuntimeDepOnFileA_test", + target = ":RuntimeDepOnFileA", + maven_artifacts = ["RuntimeDepOnFileA:_:_"], + maven_dependencies = ["FileA:_:_"], + ) + + _fake_java_library( + name = "ExportsFileA", + exports = [":FileA"], + ) + _maven_info_test( + name = "ExportsFileA_test", + target = ":ExportsFileA", + maven_artifacts = [ + "ExportsFileA:_:_", + "FileA:_:_", + ], + maven_dependencies = ["FileA:_:_"], + ) + + _fake_java_library( + name = "TransitiveExportsFileA", + exports = [":ExportsFileA"], + ) + _maven_info_test( + name = "TransitiveExportsFileA_test", + target = ":TransitiveExportsFileA", + maven_artifacts = [ + "TransitiveExportsFileA:_:_", + "ExportsFileA:_:_", + "FileA:_:_", + ], + maven_dependencies = [ + "ExportsFileA:_:_", + "FileA:_:_", + ], + ) + + _fake_java_library( + name = "TransitiveDepsFileA", + deps = [":ExportsFileA"], + ) + _maven_info_test( + name = "TransitiveDepsFileA_test", + target = ":TransitiveDepsFileA", + maven_artifacts = ["TransitiveDepsFileA:_:_"], + maven_dependencies = [ + "ExportsFileA:_:_", + "FileA:_:_", + ], + )