├── .npmrc ├── e2e ├── README.md ├── BUILD.bazel └── project │ ├── .gitignore │ ├── build.gradle.kts │ ├── settings.gradle.kts │ ├── src │ └── main │ │ └── java │ │ ├── sample │ │ └── HelloWorld.java │ │ └── HelloWorld.java │ └── BUILD.bazel ├── gradle ├── BUILD.bazel ├── wrapper │ ├── gradle-wrapper.jar │ ├── gradle-wrapper.properties │ └── BUILD.bazel └── defs.bzl ├── tools ├── BUILD.bazel ├── defs │ ├── BUILD.bazel │ ├── java │ │ ├── BUILD.bazel │ │ └── deps.bzl │ └── kt │ │ └── BUILD.bazel ├── bazel │ ├── bazel4.bazelrc │ ├── bazel5.bazelrc │ ├── base.bazelrc │ ├── windows.bazelrc │ ├── bzlmod.bazelrc │ ├── linux.bazelrc │ ├── macos.bazelrc │ ├── dev.bazelrc │ ├── ci.bazelrc │ ├── buildbuddy.bazelrc │ ├── hermetic.bazelrc │ ├── java.bazelrc │ ├── profiles.bazelrc │ ├── cache.bazelrc │ ├── labs.bazelrc │ ├── remote.bazelrc │ ├── bazel6.bazelrc │ ├── bazel7.bazelrc │ └── strict.bazelrc └── scripts │ ├── BUILD.bazel │ ├── latest_version_tag.sh │ └── workspace.sh ├── .bazelversion ├── internal ├── BUILD.bazel ├── config.bzl └── task.bzl ├── javatests └── BUILD.bazel ├── .bazelignore ├── .github ├── CODEOWNERS ├── .yamllint.yml ├── dependency-review-config.yml ├── CONTRIBUTING.md ├── workflows │ ├── BUILD.bazel │ ├── on.release.yml │ ├── ci.bazelrc │ ├── bazel.ci.yml │ ├── check.buildifier.yml │ ├── release_prep.sh │ ├── deploy.docs.yml │ ├── on.push.yml │ ├── check.lint-yaml.yml │ ├── on.pr.yml │ ├── check.scorecards.yml │ └── module.build.yml ├── dependabot.yml └── CODE_OF_CONDUCT.md ├── version.bazelrc ├── .gitignore ├── .aspect └── bazelrc │ ├── BUILD.bazel │ ├── bazel5.bazelrc │ ├── debug.bazelrc │ ├── bazel6.bazelrc │ ├── bazel7.bazelrc │ ├── convenience.bazelrc │ ├── javascript.bazelrc │ ├── performance.bazelrc │ ├── ci.bazelrc │ └── correctness.bazelrc ├── .bazelproject ├── package.json ├── BUILD.bazel ├── .bazelrc ├── java ├── build │ └── bazel │ │ └── gradle │ │ ├── util │ │ └── TeeOutputStream.java │ │ ├── TestUtils.java │ │ ├── GradleTool.kt │ │ ├── FileUtils.java │ │ ├── PathUtils.java │ │ ├── GradleW.java │ │ ├── GradleRunner.java │ │ └── Gradle.java ├── logback.xml └── BUILD.bazel ├── gradlew.bat ├── MODULE.bazel ├── README.md ├── gradlew ├── WORKSPACE.bazel └── maven_install.json /.npmrc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /e2e/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /e2e/BUILD.bazel: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gradle/BUILD.bazel: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/BUILD.bazel: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bazelversion: -------------------------------------------------------------------------------- 1 | 6.3.2 2 | -------------------------------------------------------------------------------- /internal/BUILD.bazel: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /javatests/BUILD.bazel: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/defs/BUILD.bazel: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/defs/java/BUILD.bazel: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bazelignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | *.* @sgammon 2 | -------------------------------------------------------------------------------- /e2e/project/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /.gradle -------------------------------------------------------------------------------- /tools/bazel/bazel4.bazelrc: -------------------------------------------------------------------------------- 1 | # Nothing at this time. -------------------------------------------------------------------------------- /tools/bazel/bazel5.bazelrc: -------------------------------------------------------------------------------- 1 | # Nothing at this time. -------------------------------------------------------------------------------- /tools/bazel/base.bazelrc: -------------------------------------------------------------------------------- 1 | coverage --combined_report=lcov 2 | -------------------------------------------------------------------------------- /tools/bazel/windows.bazelrc: -------------------------------------------------------------------------------- 1 | build:windows --enable_runfiles 2 | -------------------------------------------------------------------------------- /.github/.yamllint.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | line-length: 3 | max: 120 4 | -------------------------------------------------------------------------------- /version.bazelrc: -------------------------------------------------------------------------------- 1 | import %workspace%/tools/bazel/bazel6.bazelrc 2 | -------------------------------------------------------------------------------- /tools/bazel/bzlmod.bazelrc: -------------------------------------------------------------------------------- 1 | build:bzlmod --experimental_enable_bzlmod 2 | -------------------------------------------------------------------------------- /e2e/project/build.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | plugins { 3 | `java-library` 4 | } 5 | -------------------------------------------------------------------------------- /e2e/project/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | rootProject.name = "sample-project" 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bazel-* 2 | node_modules/ 3 | local.bazelrc 4 | .DS_Store 5 | .ijwb 6 | -------------------------------------------------------------------------------- /tools/bazel/linux.bazelrc: -------------------------------------------------------------------------------- 1 | build:linux --spawn_strategy=worker,sandboxed,local 2 | -------------------------------------------------------------------------------- /tools/bazel/macos.bazelrc: -------------------------------------------------------------------------------- 1 | build:macos --spawn_strategy=worker,sandboxed,local 2 | -------------------------------------------------------------------------------- /.github/dependency-review-config.yml: -------------------------------------------------------------------------------- 1 | license-check: true 2 | vulnerability-check: true 3 | fail-on-severity: "low" 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgammon/rules_gradle/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /tools/bazel/dev.bazelrc: -------------------------------------------------------------------------------- 1 | build:dev --config=buildless 2 | build:dev --config=buildbuddy 3 | build:dev --config=disk-cache 4 | -------------------------------------------------------------------------------- /tools/scripts/BUILD.bazel: -------------------------------------------------------------------------------- 1 | package(default_visibility = [ 2 | "@//:__pkg__", 3 | "@//tools:__pkg__", 4 | "@//tools:__subpackages__", 5 | ]) 6 | -------------------------------------------------------------------------------- /e2e/project/src/main/java/sample/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package sample; 2 | 3 | public class HelloWorld { 4 | public static void main(String[] args) { 5 | System.out.println("Hello, world!"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tools/bazel/ci.bazelrc: -------------------------------------------------------------------------------- 1 | build:ci --config=buildless 2 | build:ci --config=buildbuddy 3 | build:ci --build_metadata=ROLE=CI 4 | build:ci --build_metadata=VISIBILITY=PUBLIC 5 | build:ci-strict --lockfile_mode=error 6 | 7 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Gradle Rules for Bazel: Contribution Guide 2 | 3 | This codebase is a conventional Bazel 6 or Bazel 7 codebase. To use it, you build and test from [Bazel](https://bazel.build). 4 | 5 | Coming soon. 6 | -------------------------------------------------------------------------------- /e2e/project/src/main/java/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package samples.project.src.main.java; 2 | 3 | public class HelloWorld { 4 | public static void main(String[] args) { 5 | System.out.println("Hello, world!"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /gradle/defs.bzl: -------------------------------------------------------------------------------- 1 | "Provides Bazel rule definitions for working with Gradle projects." 2 | 3 | load( 4 | "//internal:task.bzl", 5 | _gradle_task = "gradle_task", 6 | ) 7 | 8 | # Exports. 9 | gradle_task = _gradle_task 10 | -------------------------------------------------------------------------------- /.github/workflows/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@buildifier_prebuilt//:rules.bzl", "buildifier") 2 | 3 | buildifier( 4 | name = "buildifier.check", 5 | exclude_patterns = ["./.git/*"], 6 | lint_mode = "warn", 7 | mode = "diff", 8 | ) 9 | -------------------------------------------------------------------------------- /tools/bazel/buildbuddy.bazelrc: -------------------------------------------------------------------------------- 1 | build:buildbuddy --bes_results_url=https://app.buildbuddy.io/invocation/ 2 | build:buildbuddy --bes_backend=grpcs://remote.buildbuddy.io 3 | build:buildbuddy --build_metadata=REPO_URL=https://github.com/sgammon/rules_gradle 4 | -------------------------------------------------------------------------------- /tools/scripts/latest_version_tag.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Prints the latest BuildBuddy version tag, like "v2.12.8" 5 | git tag -l 'v*' --sort=creatordate | 6 | perl -nle 'if (/^v\d+\.\d+\.\d+$/) { print $_ }' | 7 | tail -n1 8 | -------------------------------------------------------------------------------- /.aspect/bazelrc/BUILD.bazel: -------------------------------------------------------------------------------- 1 | "Aspect bazelrc presets; see https://docs.aspect.build/guides/bazelrc" 2 | 3 | load("@aspect_bazel_lib//lib:bazelrc_presets.bzl", "write_aspect_bazelrc_presets") 4 | 5 | write_aspect_bazelrc_presets(name = "update_aspect_bazelrc_presets") 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: daily 7 | 8 | - package-ecosystem: npm 9 | directory: / 10 | schedule: 11 | interval: daily 12 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://dl.less.build/toolchains/gradle/gradle-8.3-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /.aspect/bazelrc/bazel5.bazelrc: -------------------------------------------------------------------------------- 1 | # Performance improvement for WORKSPACE evaluation 2 | # of slow rulesets, for example rules_k8s has been 3 | # observed to take 10 seconds without this flag. 4 | # See https://github.com/bazelbuild/bazel/issues/13907 5 | common --incompatible_existing_rules_immutable_view 6 | -------------------------------------------------------------------------------- /.bazelproject: -------------------------------------------------------------------------------- 1 | directories: 2 | . 3 | 4 | workspace_type: java 5 | java_language_level: 11 6 | derive_targets_from_directories: false 7 | 8 | targets: 9 | //.aspect/... 10 | //java/... 11 | 12 | test_sources: 13 | javatests/* 14 | 15 | additional_languages: 16 | java 17 | kotlin 18 | 19 | -------------------------------------------------------------------------------- /.github/workflows/on.release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Release 3 | 4 | "on": 5 | push: 6 | tags: 7 | - "v*.*.*" 8 | 9 | jobs: 10 | release: 11 | name: "Release: BCR" 12 | uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v2 13 | with: 14 | release_files: rules_gradle-*.zip 15 | -------------------------------------------------------------------------------- /tools/bazel/hermetic.bazelrc: -------------------------------------------------------------------------------- 1 | build:hermetic --incompatible_enable_cc_toolchain_resolution 2 | build:hermetic --incompatible_use_python_toolchains 3 | build:hermetic --incompatible_enable_android_toolchain_resolution 4 | build:hermetic --incompatible_enable_apple_toolchain_resolution 5 | build:hermetic-strict --action_env BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 6 | -------------------------------------------------------------------------------- /gradle/wrapper/BUILD.bazel: -------------------------------------------------------------------------------- 1 | package( 2 | default_visibility = ["//visibility:public"], 3 | ) 4 | 5 | exports_files([ 6 | "gradle-wrapper.jar", 7 | "gradle-wrapper.properties", 8 | ]) 9 | 10 | filegroup( 11 | name = "wrapper", 12 | srcs = [ 13 | ":gradle-wrapper.jar", 14 | ":gradle-wrapper.properties", 15 | ], 16 | ) 17 | -------------------------------------------------------------------------------- /tools/bazel/java.bazelrc: -------------------------------------------------------------------------------- 1 | 2 | build --explicit_java_test_deps 3 | 4 | build --java_language_version=11 5 | build --java_runtime_version=remotejdk_11 6 | build --extra_toolchains=@graalvm//:sdk 7 | 8 | build --experimental_inmemory_jdeps_files 9 | build --experimental_strict_java_deps=strict 10 | 11 | test --verbose_failures 12 | test --test_output=errors 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rules_gradle", 3 | "version": "0.0.1", 4 | "private": true, 5 | "devDependencies": { 6 | "@commitlint/cli": "17.7.1", 7 | "@commitlint/config-conventional": "17.7.0", 8 | "husky": "8.0.3", 9 | "lint-staged": "14.0.1", 10 | "prettier": "^3.0.3", 11 | "prettier-plugin-java": "2.3.0" 12 | } 13 | } -------------------------------------------------------------------------------- /tools/bazel/profiles.bazelrc: -------------------------------------------------------------------------------- 1 | 2 | # Mode: Debug 3 | build:debug --sandbox_debug 4 | build:debug --verbose_failures 5 | build:debug --compilation_mode=dbg 6 | 7 | # Mode: Release 8 | build:release --stamp 9 | build:release --strip=always 10 | build:release --compilation_mode=opt 11 | build:release --workspace_status_command=$(pwd)/tools/scripts/workspace.sh 12 | 13 | # Mode: Fastbuild 14 | build:fastbuild --compilation_mode=fastbuild 15 | -------------------------------------------------------------------------------- /tools/defs/kt/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load( 2 | "@rules_kotlin//kotlin:core.bzl", 3 | "define_kt_toolchain", 4 | ) 5 | load( 6 | "//internal:config.bzl", 7 | "JAVA_LANGUAGE_LEVEL", 8 | "KOTLIN_API_VERSION", 9 | "KOTLIN_LANGUAGE_VERSION", 10 | ) 11 | 12 | 13 | define_kt_toolchain( 14 | name = "toolchain", 15 | api_version = KOTLIN_API_VERSION, 16 | jvm_target = JAVA_LANGUAGE_LEVEL, 17 | language_version = KOTLIN_LANGUAGE_VERSION, 18 | ) 19 | -------------------------------------------------------------------------------- /tools/bazel/cache.bazelrc: -------------------------------------------------------------------------------- 1 | 2 | build:disk-cache --disk_cache=~/.cache/bazel 3 | 4 | build:buildless --remote_cache=https://bazel.less.build/cache/generic 5 | 6 | build --modify_execution_info=PackageTar=+no-remote 7 | build --remote_local_fallback 8 | build --incompatible_remote_results_ignore_disk 9 | build --noexperimental_check_output_files 10 | build --nolegacy_important_outputs 11 | build --incompatible_default_to_explicit_init_py 12 | build --experimental_remote_merkle_tree_cache 13 | build --experimental_remote_cache_compression 14 | -------------------------------------------------------------------------------- /BUILD.bazel: -------------------------------------------------------------------------------- 1 | package( 2 | default_visibility = ["//visibility:public"], 3 | ) 4 | 5 | load("@npm//:defs.bzl", "npm_link_all_packages") 6 | load("@gazelle//:def.bzl", "gazelle") 7 | 8 | exports_files([ 9 | ".npmrc", 10 | ".bazelignore", 11 | "maven_install.json", 12 | "package.json", 13 | "pnpm-lock.yaml", 14 | ]) 15 | 16 | alias( 17 | name = "wrapper", 18 | actual = "//java", 19 | ) 20 | 21 | # gazelle:prefix github.com/sgammon/rules_gradle 22 | 23 | npm_link_all_packages(name = "node_modules") 24 | 25 | gazelle(name = "gazelle") 26 | -------------------------------------------------------------------------------- /tools/bazel/labs.bazelrc: -------------------------------------------------------------------------------- 1 | build:labs --experimental_platforms_api 2 | build:labs --experimental_local_lockfree_output 3 | build:labs --experimental_cc_shared_library 4 | build:labs --experimental_disable_external_package 5 | 6 | build:labs --experimental_use_windows_sandbox=auto 7 | build:labs --incompatible_strict_action_env 8 | build:labs --dynamic_local_strategy=worker,sandboxed,standalone 9 | build:labs --spawn_strategy=worker,sandboxed,local 10 | 11 | build:labs-sandbox --experimental_use_sandboxfs=auto 12 | 13 | build:labs-broken --experimental_strict_java_deps=error 14 | build:labs-broken --experimental_worker_strict_flagfiles 15 | -------------------------------------------------------------------------------- /e2e/project/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load( 2 | "//gradle:defs.bzl", 3 | "gradle_task", 4 | ) 5 | 6 | # gazelle:exclude src/* 7 | 8 | filegroup( 9 | name = "files", 10 | srcs = [ 11 | "build.gradle.kts", 12 | "settings.gradle.kts", 13 | "src/main/java/HelloWorld.java", 14 | ], 15 | ) 16 | 17 | gradle_task( 18 | name = "project", 19 | outputs = [ 20 | "libs/sample-project.jar", 21 | ], 22 | project = ":files", 23 | ) 24 | 25 | gradle_task( 26 | name = "project-native", 27 | outputs = [ 28 | "libs/sample-project.jar", 29 | ], 30 | project = ":files", 31 | runner = "//java:native", 32 | ) 33 | -------------------------------------------------------------------------------- /tools/bazel/remote.bazelrc: -------------------------------------------------------------------------------- 1 | 2 | build:remote --remote_download_minimal 3 | build:remote --remote_executor=grpcs://remote.buildbuddy.io 4 | build:remote --host_platform=@buildbuddy_toolchain//:platform 5 | build:remote --platforms=@buildbuddy_toolchain//:platform 6 | build:remote --extra_execution_platforms=@buildbuddy_toolchain//:platform 7 | build:remote --crosstool_top=@buildbuddy_toolchain//:toolchain 8 | build:remote --extra_toolchains=@buildbuddy_toolchain//:cc_toolchain 9 | build:remote --javabase=@buildbuddy_toolchain//:javabase_jdk8 10 | build:remote --host_javabase=@buildbuddy_toolchain//:javabase_jdk8 11 | build:remote --java_toolchain=@buildbuddy_toolchain//:toolchain_jdk8 12 | build:remote --host_java_toolchain=@buildbuddy_toolchain//:toolchain_jdk8 13 | build:remote --define=EXECUTOR=remote 14 | -------------------------------------------------------------------------------- /.aspect/bazelrc/debug.bazelrc: -------------------------------------------------------------------------------- 1 | ############################################################ 2 | # Use `bazel test --config=debug` to enable these settings # 3 | ############################################################ 4 | 5 | # Stream stdout/stderr output from each test in real-time. 6 | # Docs: https://bazel.build/docs/user-manual#test-output 7 | test:debug --test_output=streamed 8 | 9 | # Run one test at a time. 10 | # Docs: https://bazel.build/reference/command-line-reference#flag--test_strategy 11 | test:debug --test_strategy=exclusive 12 | 13 | # Prevent long running tests from timing out. 14 | # Docs: https://bazel.build/docs/user-manual#test-timeout 15 | test:debug --test_timeout=9999 16 | 17 | # Always run tests even if they have cached results. 18 | # Docs: https://bazel.build/docs/user-manual#cache-test-results 19 | test:debug --nocache_test_results 20 | -------------------------------------------------------------------------------- /.github/workflows/ci.bazelrc: -------------------------------------------------------------------------------- 1 | # This file contains Bazel settings to apply on CI only. 2 | # It is referenced with a --bazelrc option in the call to bazel in ci.yaml 3 | 4 | # Debug where options came from 5 | build --announce_rc 6 | 7 | # Apply CI configurations 8 | build --config=ci 9 | 10 | # This directory is configured in GitHub actions to be persisted between runs. 11 | # We do not enable the repository cache to cache downloaded external artifacts 12 | # as these are generally faster to download again than to fetch them from the 13 | # GitHub actions cache. 14 | build --disk_cache=~/.cache/bazel 15 | 16 | # Don't rely on test logs being easily accessible from the test runner, 17 | # though it makes the log noisier. 18 | test --test_output=errors 19 | 20 | # Allows tests to run bazelisk-in-bazel, since this is the cache folder used 21 | test --test_env=XDG_CACHE_HOME 22 | -------------------------------------------------------------------------------- /.github/workflows/bazel.ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bazel CI 3 | 4 | # Controls when the action will run. 5 | "on": 6 | push: 7 | branches: [main] 8 | pull_request: 9 | branches: [main] 10 | workflow_dispatch: {} 11 | 12 | concurrency: 13 | # Cancel previous actions from the same PR: https://stackoverflow.com/a/72408109 14 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | test: 19 | uses: bazel-contrib/.github/.github/workflows/bazel.yaml@29e53247c6366e30acbedfc767f58f79fc05836c 20 | with: 21 | folders: | 22 | [ 23 | "." 24 | ] 25 | exclude_windows: true 26 | exclude: | 27 | [ 28 | {"bazelversion": "5.4.0", "bzlmodEnabled": true}, 29 | {"bazelversion": "5.4.0", "bzlmodEnabled": false}, 30 | {"bazelversion": "5.4.0", "os": "macos-latest"}, 31 | ] 32 | -------------------------------------------------------------------------------- /.aspect/bazelrc/bazel6.bazelrc: -------------------------------------------------------------------------------- 1 | # Speed up all builds by not checking if external repository files have been modified. 2 | # Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java#L244 3 | build --noexperimental_check_external_repository_files 4 | fetch --noexperimental_check_external_repository_files 5 | query --noexperimental_check_external_repository_files 6 | 7 | # Directories used by sandboxed non-worker execution may be reused to avoid unnecessary setup costs. 8 | # Save time on Sandbox creation and deletion when many of the same kind of action run during the 9 | # build. 10 | # Docs: https://bazel.build/reference/command-line-reference#flag--reuse_sandbox_directories 11 | build --reuse_sandbox_directories 12 | 13 | # Avoid this flag being enabled by remote_download_minimal or remote_download_toplevel 14 | # See https://meroton.com/blog/bazel-6-errors-build-without-the-bytes/ 15 | build --noexperimental_action_cache_store_output_metadata 16 | -------------------------------------------------------------------------------- /.aspect/bazelrc/bazel7.bazelrc: -------------------------------------------------------------------------------- 1 | # Speed up all builds by not checking if external repository files have been modified. 2 | # Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java#L244 3 | build --noexperimental_check_external_repository_files 4 | fetch --noexperimental_check_external_repository_files 5 | query --noexperimental_check_external_repository_files 6 | 7 | # Directories used by sandboxed non-worker execution may be reused to avoid unnecessary setup costs. 8 | # Save time on Sandbox creation and deletion when many of the same kind of action run during the 9 | # build. 10 | # Docs: https://bazel.build/reference/command-line-reference#flag--reuse_sandbox_directories 11 | build --reuse_sandbox_directories 12 | 13 | # Avoid this flag being enabled by remote_download_minimal or remote_download_toplevel 14 | # See https://meroton.com/blog/bazel-6-errors-build-without-the-bytes/ 15 | build --noexperimental_action_cache_store_output_metadata 16 | -------------------------------------------------------------------------------- /internal/config.bzl: -------------------------------------------------------------------------------- 1 | "Configuration constants for the Gradle Rules for Bazel." 2 | 3 | GRADLE_VERSION = "8.2.1" 4 | 5 | GO_VERSION = "1.20.6" 6 | 7 | NODE_VERSION = "20.5.0" 8 | 9 | PYTHON_VERSION = "3.11" 10 | 11 | PROTOBUF_VERSION = "3.20.1" 12 | 13 | PROTOBUF_SHA = "8b28fdd45bab62d15db232ec404248901842e5340299a57765e48abe8a80d930" 14 | 15 | RULES_JVM_EXTERNAL_TAG = "5.3" 16 | 17 | RULES_JVM_EXTERNAL_SHA = "d31e369b854322ca5098ea12c69d7175ded971435e55c18dd9dd5f29cc5249ac" 18 | 19 | SLF4J_VERSION = "1.7.10" 20 | 21 | KOTLIN_VERSION = "1.8.20" 22 | 23 | KOTLIN_LANGUAGE_VERSION = "1.8" 24 | 25 | KOTLIN_API_VERSION = "1.8" 26 | 27 | RULES_KOTLIN_VERSION = "afff5acb1d8518f5ddc31c68c4420ca5927fc4a4" 28 | 29 | RULES_KOTLIN_SHA = "d8630c26e9002cfa954b428609fa10e675392138de2e7ce80210a0bcdfe84aa3" 30 | 31 | JAVA_LANGUAGE_LEVEL = "11" 32 | 33 | GRAALVM_VERSION = "17.0.8" 34 | 35 | GRAALVM_JAVA_VERSION = "17" 36 | 37 | GRAALVM_DISTRIBUTION = "ce" 38 | 39 | GUAVA_VERSION = "32.1.2-jre" 40 | 41 | PICOCLI_VERSION = "4.7.5" 42 | 43 | LOGBACK_VERSION = "1.4.11" 44 | -------------------------------------------------------------------------------- /tools/scripts/workspace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script will be run bazel when building process starts to 4 | # generate key-value information that represents the status of the 5 | # workspace. The output should be like 6 | # 7 | # KEY1 VALUE1 8 | # KEY2 VALUE2 9 | # 10 | # If the script exits with non-zero code, it's considered as a failure 11 | # and the output will be discarded. 12 | 13 | set -eo pipefail # exit immediately if any command fails. 14 | 15 | user=$(whoami); 16 | echo "USER $user"; 17 | 18 | commit_sha=$(git rev-parse HEAD) 19 | echo "COMMIT_SHA $commit_sha" 20 | 21 | git_branch=$(git rev-parse --abbrev-ref HEAD) 22 | echo "GIT_BRANCH $git_branch" 23 | 24 | git_tree_status=$(git diff-index --quiet HEAD -- && echo 'Clean' || echo 'Modified') 25 | echo "GIT_TREE_STATUS $git_tree_status" 26 | 27 | # Note: the "STABLE_" suffix causes these to be part of the "stable" workspace 28 | # status, which may trigger rebuilds of certain targets if these values change 29 | # and you're building with the "--stamp" flag. 30 | latest_version_tag=$(./tools/scripts/latest_version_tag.sh) 31 | echo "STABLE_VERSION_TAG $latest_version_tag" 32 | echo "STABLE_COMMIT_SHA $commit_sha" 33 | -------------------------------------------------------------------------------- /tools/bazel/bazel6.bazelrc: -------------------------------------------------------------------------------- 1 | build --experimental_remote_build_event_upload=minimal 2 | build --noexperimental_check_external_repository_files 3 | 4 | build:bzlmod --enable_bzlmod 5 | 6 | build:dev --lockfile_mode=update 7 | 8 | build:labs --experimental_worker_multiplex_sandboxing 9 | build:labs --experimental_bzl_visibility 10 | 11 | build:strict --incompatible_always_include_files_in_data 12 | build:strict --incompatible_check_sharding_support 13 | build:strict --incompatible_check_testonly_for_output_files 14 | build:strict --incompatible_disallow_symlink_file_to_dir 15 | build:strict --incompatible_fix_package_group_reporoot_syntax 16 | build:strict --incompatible_package_group_has_public_syntax 17 | build:strict --incompatible_remote_dangling_symlinks 18 | build:strict --incompatible_remote_downloader_send_all_headers 19 | build:strict --incompatible_remote_use_new_exit_code_for_lost_inputs 20 | build:strict --incompatible_remove_rule_name_parameter 21 | build:strict --incompatible_sandbox_hermetic_tmp 22 | build:strict --incompatible_unambiguous_label_stringification 23 | build:strict --incompatible_use_host_features 24 | 25 | build:strict-broken --incompatible_disable_starlark_host_transitions 26 | -------------------------------------------------------------------------------- /tools/defs/java/deps.bzl: -------------------------------------------------------------------------------- 1 | "Provides Java dependency macros." 2 | 3 | def _rewrite_maven_coordinate(string): 4 | return string.replace("-", "_").replace(":", "_").replace(".", "_") 5 | 6 | def maven(spec = None, artifact = None, group = None, repo = "@maven"): 7 | """Utility to rewrite a regular Maven dependency coordinate to a target name. 8 | 9 | Args: 10 | spec: Single-string specification, like `some.group:artifact`. Mutually exclusive 11 | with `artifact` and `group`. 12 | artifact: Name of the artifact; used with `group`. Mutually exclusive with `spec`. 13 | group: Group of the artifact; used with `artifact`. Mutually exclusive with `spec`. 14 | repo: Repo name to use; defaults to `@maven`. 15 | 16 | Returns: 17 | Formatted target string. 18 | """ 19 | 20 | coordinates = None 21 | 22 | if spec: 23 | coordinates = _rewrite_maven_coordinate(spec) 24 | 25 | elif artifact and group: 26 | coordinates = _rewrite_maven_coordinate("%s:%s" % (group, artifact)) 27 | 28 | if coordinates == None: 29 | fail("Failed to calculate coordinates for Maven dependency") 30 | 31 | return "%s//:%s" % (repo, coordinates) 32 | -------------------------------------------------------------------------------- /.github/workflows/check.buildifier.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Buildifier 3 | 4 | # Controls when the action will run. 5 | "on": 6 | # Triggers the workflow on push or pull request events but only for the main branch 7 | push: 8 | branches: [main] 9 | paths: 10 | - docs/**/*.* 11 | - e2e/**/*.* 12 | - gradle/**/*.* 13 | - internal/**/*.* 14 | - tools/**/*.* 15 | 16 | pull_request: 17 | branches: [main] 18 | paths: 19 | - docs/**/*.* 20 | - e2e/**/*.* 21 | - gradle/**/*.* 22 | - internal/**/*.* 23 | - tools/**/*.* 24 | 25 | # Allows you to run this workflow manually from the Actions tab 26 | workflow_dispatch: 27 | 28 | permissions: 29 | contents: read 30 | 31 | jobs: 32 | check: 33 | runs-on: ubuntu-latest 34 | continue-on-error: true 35 | steps: 36 | - name: Harden Runner 37 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 38 | with: 39 | egress-policy: audit 40 | - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 41 | - name: buildifier 42 | continue-on-error: true 43 | run: bazel run //.github/workflows:buildifier.check 44 | -------------------------------------------------------------------------------- /.github/workflows/release_prep.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit -o nounset -o pipefail 4 | 5 | # Set by GH actions, see 6 | # https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables 7 | TAG=${GITHUB_REF_NAME} 8 | # The prefix is chosen to match what GitHub generates for source archives 9 | PREFIX="rules_mylang-${TAG:1}" 10 | ARCHIVE="rules_mylang-$TAG.tar.gz" 11 | git archive --format=tar --prefix=${PREFIX}/ ${TAG} | gzip > $ARCHIVE 12 | SHA=$(shasum -a 256 $ARCHIVE | awk '{print $1}') 13 | 14 | cat << EOF 15 | ## Using Bzlmod with Bazel 6+ 16 | 17 | 1. Enable with \`common --enable_bzlmod\` in \`.bazelrc\`. 18 | 2. Add to your \`MODULE.bazel\` file: 19 | 20 | \`\`\`starlark 21 | bazel_dep(name = "rules_gradle", version = "${TAG:1}") 22 | \`\`\` 23 | 24 | ## Using WORKSPACE 25 | 26 | Paste this snippet into your `WORKSPACE.bazel` file: 27 | 28 | \`\`\`starlark 29 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 30 | http_archive( 31 | name = "rules_gradle", 32 | sha256 = "${SHA}", 33 | strip_prefix = "${PREFIX}", 34 | url = "https://github.com/sgammon/rules_gradle/releases/download/${TAG}/${ARCHIVE}", 35 | ) 36 | EOF 37 | 38 | awk 'f;/--SNIP--/{f=1}' e2e/project/bzlmod/WORKSPACE.bazel 39 | echo "\`\`\`" 40 | -------------------------------------------------------------------------------- /.bazelrc: -------------------------------------------------------------------------------- 1 | common:verbose --announce_rc 2 | 3 | build:macos --config=strict 4 | build:macos --config=hermetic 5 | build:macos --config=labs 6 | 7 | # Import Aspect bazelrc presets 8 | import %workspace%/.aspect/bazelrc/convenience.bazelrc 9 | import %workspace%/.aspect/bazelrc/correctness.bazelrc 10 | import %workspace%/.aspect/bazelrc/debug.bazelrc 11 | import %workspace%/.aspect/bazelrc/performance.bazelrc 12 | 13 | # Import project-level presets 14 | import %workspace%/tools/bazel/base.bazelrc 15 | import %workspace%/tools/bazel/buildbuddy.bazelrc 16 | import %workspace%/tools/bazel/cache.bazelrc 17 | import %workspace%/tools/bazel/ci.bazelrc 18 | import %workspace%/tools/bazel/bzlmod.bazelrc 19 | import %workspace%/tools/bazel/profiles.bazelrc 20 | import %workspace%/tools/bazel/dev.bazelrc 21 | import %workspace%/tools/bazel/labs.bazelrc 22 | import %workspace%/tools/bazel/strict.bazelrc 23 | import %workspace%/tools/bazel/hermetic.bazelrc 24 | import %workspace%/tools/bazel/java.bazelrc 25 | import %workspace%/tools/bazel/windows.bazelrc 26 | import %workspace%/tools/bazel/linux.bazelrc 27 | import %workspace%/tools/bazel/macos.bazelrc 28 | import %workspace%/tools/bazel/remote.bazelrc 29 | 30 | common --color=auto 31 | 32 | build --verbose_failures 33 | 34 | # pick something trivial as a "noop" 35 | common:noop --logging=3 36 | 37 | try-import %workspace%/local.bazelrc 38 | try-import %workspace%/version.bazelrc 39 | -------------------------------------------------------------------------------- /java/build/bazel/gradle/util/TeeOutputStream.java: -------------------------------------------------------------------------------- 1 | package build.bazel.gradle.util; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | 5 | import java.io.IOException; 6 | import java.io.OutputStream; 7 | 8 | public class TeeOutputStream extends OutputStream { 9 | private final ImmutableList delegates; 10 | 11 | public TeeOutputStream(ImmutableList delegates) { 12 | this.delegates = delegates; 13 | } 14 | 15 | public TeeOutputStream(OutputStream... delegates) { 16 | this(ImmutableList.copyOf(delegates)); 17 | } 18 | 19 | @Override 20 | public void write(int b) throws IOException { 21 | for (OutputStream delegate : delegates) { 22 | delegate.write(b); 23 | } 24 | } 25 | @Override 26 | public void write(byte[] b) throws IOException { 27 | for (OutputStream delegate : delegates) { 28 | delegate.write(b); 29 | } 30 | } 31 | @Override 32 | public void write(byte[] b, int off, int len) throws IOException { 33 | for (OutputStream delegate : delegates) { 34 | delegate.write(b, off, len); 35 | } 36 | } 37 | @Override 38 | public void flush() throws IOException { 39 | for (OutputStream delegate : delegates) { 40 | delegate.flush(); 41 | } 42 | } 43 | @Override 44 | public void close() throws IOException { 45 | for (OutputStream delegate : delegates) { 46 | delegate.close(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /.aspect/bazelrc/convenience.bazelrc: -------------------------------------------------------------------------------- 1 | # Attempt to build & test every target whose prerequisites were successfully built. 2 | # Docs: https://bazel.build/docs/user-manual#keep-going 3 | build --keep_going 4 | 5 | # Output test errors to stderr so users don't have to `cat` or open test failure log files when test 6 | # fail. This makes the log noiser in exchange for reducing the time-to-feedback on test failures for 7 | # users. 8 | # Docs: https://bazel.build/docs/user-manual#test-output 9 | test --test_output=errors 10 | 11 | # Show the output files created by builds that requested more than one target. This helps users 12 | # locate the build outputs in more cases 13 | # Docs: https://bazel.build/docs/user-manual#show-result 14 | build --show_result=20 15 | 16 | # Bazel picks up host-OS-specific config lines from bazelrc files. For example, if the host OS is 17 | # Linux and you run bazel build, Bazel picks up lines starting with build:linux. Supported OS 18 | # identifiers are `linux`, `macos`, `windows`, `freebsd`, and `openbsd`. Enabling this flag is 19 | # equivalent to using `--config=linux` on Linux, `--config=windows` on Windows, etc. 20 | # Docs: https://bazel.build/reference/command-line-reference#flag--enable_platform_specific_config 21 | common --enable_platform_specific_config 22 | 23 | # Output a heap dump if an OOM is thrown during a Bazel invocation 24 | # (including OOMs due to `--experimental_oom_more_eagerly_threshold`). 25 | # The dump will be written to `/.heapdump.hprof`. 26 | # You may need to configure CI to capture this artifact and upload for later use. 27 | # Docs: https://bazel.build/reference/command-line-reference#flag--heap_dump_on_oom 28 | common --heap_dump_on_oom 29 | -------------------------------------------------------------------------------- /.aspect/bazelrc/javascript.bazelrc: -------------------------------------------------------------------------------- 1 | # Aspect recommended Bazel flags when using Aspect's JavaScript rules: https://github.com/aspect-build/rules_js 2 | # Docs for Node.js flags: https://nodejs.org/en/docs/guides/debugging-getting-started/#command-line-options 3 | 4 | # Support for debugging Node.js tests. Use bazel run with `--config=debug` to turn on the NodeJS 5 | # inspector agent. The node process will break before user code starts and wait for the debugger to 6 | # connect. Pass the --inspect-brk option to all tests which enables the node inspector agent. See 7 | # https://nodejs.org/de/docs/guides/debugging-getting-started/#command-line-options for more 8 | # details. 9 | # Docs: https://nodejs.org/en/docs/guides/debugging-getting-started/#command-line-options 10 | run:debug -- --node_options=--inspect-brk 11 | 12 | # Enable runfiles on all platforms. Runfiles are on by default on Linux and MacOS but off on 13 | # Windows. 14 | # 15 | # In general, rules_js and derivate rule sets assume that runfiles are enabled and do not support no 16 | # runfiles case because it does not scale to teach all Node.js tools to use the runfiles manifest. 17 | # 18 | # If you are developing on Windows, you must either run bazel with administrator privileges or 19 | # enable developer mode. If you do not you may hit this error on Windows: 20 | # 21 | # Bazel needs to create symlinks to build the runfiles tree. 22 | # Creating symlinks on Windows requires one of the following: 23 | # 1. Bazel is run with administrator privileges. 24 | # 2. The system version is Windows 10 Creators Update (1703) or later 25 | # and developer mode is enabled. 26 | # 27 | # Docs: https://bazel.build/reference/command-line-reference#flag--enable_runfiles 28 | build --enable_runfiles 29 | -------------------------------------------------------------------------------- /tools/bazel/bazel7.bazelrc: -------------------------------------------------------------------------------- 1 | import %workspace%/.aspect/bazelrc/bazel7.bazelrc 2 | 3 | build --remote_build_event_upload=minimal 4 | build --noexperimental_check_external_repository_files 5 | build --extra_toolchains=@graalvm//:bootstrap_runtime_toolchain 6 | 7 | build:bzlmod --enable_bzlmod 8 | 9 | build:dev --lockfile_mode=update 10 | 11 | build:labs --experimental_worker_sandbox_hardening 12 | build:labs --experimental_worker_for_repo_fetching=platform 13 | build:labs --experimental_worker_multiplex_sandboxing 14 | build:labs --experimental_bzl_visibility 15 | 16 | build:strict --incompatible_depset_for_java_output_source_jars 17 | build:strict --incompatible_disallow_sdk_frameworks_attributes 18 | build:strict --incompatible_objc_alwayslink_by_default 19 | build:strict --incompatible_python_disable_py2 20 | build:strict --incompatible_remote_disallow_symlink_in_tree_artifact 21 | build:strict --incompatible_always_include_files_in_data 22 | build:strict --incompatible_check_sharding_support 23 | build:strict --incompatible_check_testonly_for_output_files 24 | build:strict --incompatible_disable_starlark_host_transitions 25 | build:strict --incompatible_disallow_symlink_file_to_dir 26 | build:strict --incompatible_fix_package_group_reporoot_syntax 27 | build:strict --incompatible_package_group_has_public_syntax 28 | build:strict --incompatible_remote_dangling_symlinks 29 | build:strict --incompatible_remote_downloader_send_all_headers 30 | build:strict --incompatible_remote_use_new_exit_code_for_lost_inputs 31 | build:strict --incompatible_remove_rule_name_parameter 32 | build:strict --incompatible_sandbox_hermetic_tmp 33 | build:strict --incompatible_unambiguous_label_stringification 34 | build:strict --incompatible_use_host_features 35 | 36 | build:strict-broken --incompatible_auto_exec_groups 37 | -------------------------------------------------------------------------------- /java/build/bazel/gradle/TestUtils.java: -------------------------------------------------------------------------------- 1 | 2 | package build.bazel.gradle; 3 | 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | import java.nio.file.Paths; 7 | import java.io.IOException; 8 | 9 | 10 | public class TestUtils { 11 | /** 12 | * Creates a temporary directory that is deleted when the JVM exits. 13 | * 14 | * @deprecated Temporary directories and files should be deleted after each test, not kept 15 | * around for the lifetime of the JVM. This can be achieved by using 16 | * a `org.junit.rules.TemporaryFolder` rule, or by calling the 17 | * {@link PathUtils#deleteRecursivelyIfExists(Path)} method in {@code tearDown}. 18 | */ 19 | @Deprecated 20 | public static Path createTempDirDeletedOnExit() throws IOException { 21 | Path tempDir = Files.createTempDirectory(""); 22 | PathUtils.addRemovePathHook(tempDir); 23 | return tempDir; 24 | } 25 | 26 | /** 27 | * Returns a directory which tests can output data to. If running through Bazel's test runner, 28 | * this returns the directory as specified by the TEST_UNDECLARED_OUTPUTS_DIR environment 29 | * variable. Data written to this directory will be zipped and made available under the 30 | * WORKSPACE_ROOT/bazel-testlogs/ after the test completes. For non-Bazel runs, this currently 31 | * returns a tmp directory that is deleted on exit. 32 | */ 33 | public static Path getTestOutputDir() throws IOException { 34 | // If running via bazel, returns the sandboxed test output dir. 35 | String testOutputDir = System.getenv("TEST_UNDECLARED_OUTPUTS_DIR"); 36 | if (testOutputDir != null) { 37 | return Paths.get(testOutputDir); 38 | } 39 | 40 | return createTempDirDeletedOnExit(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | %cyan(%d{HH:mm:ss.SSS}) %highlight(%6level) %boldWhite(%logger) - %white(%msg) %n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | false 16 | 17 | %cyan(%d{HH:mm:ss.SSS}) %highlight(%6level) %boldWhite(%logger) - %white(%msg) %n 18 | 19 | 20 | 21 | 22 | 23 | codesource 24 | user 25 | 26 | 27 | 28 | 20 29 | 30 | 256 31 | false 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /java/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load( 2 | "@rules_kotlin//kotlin:jvm.bzl", 3 | java_binary = "kt_jvm_binary", 4 | java_library = "kt_jvm_library", 5 | ) 6 | load( 7 | "@rules_java//java:defs.bzl", 8 | "java_plugin", 9 | pure_java_library = "java_library", 10 | ) 11 | load( 12 | "@rules_graalvm//graalvm:defs.bzl", 13 | "native_image", 14 | ) 15 | load( 16 | "//tools/defs/java:deps.bzl", 17 | "maven", 18 | ) 19 | 20 | DEPS = [ 21 | maven("ch.qos.logback:logback-core"), 22 | maven("ch.qos.logback:logback-classic"), 23 | maven("com.google.guava:guava"), 24 | maven("info.picocli:picocli"), 25 | maven("org.gradle:gradle-tooling-api"), 26 | maven("org.slf4j:slf4j-api"), 27 | maven("org.slf4j:jul-to-slf4j"), 28 | maven("org.jetbrains.kotlin:kotlin-stdlib"), 29 | ] 30 | 31 | filegroup( 32 | name = "srcs", 33 | srcs = glob([ 34 | "build/bazel/**/*.java", 35 | "build/bazel/**/*.kt", 36 | ]), 37 | ) 38 | 39 | java_plugin( 40 | name = "picocli-processor", 41 | generates_api = True, 42 | processor_class = "picocli.codegen.aot.graalvm.processor.NativeImageConfigGeneratorProcessor", 43 | deps = [maven("info.picocli:picocli-codegen")], 44 | ) 45 | 46 | pure_java_library( 47 | name = "picocli", 48 | exported_plugins = [":picocli-processor"], 49 | runtime_deps = [maven("info.picocli:picocli")], 50 | ) 51 | 52 | java_library( 53 | name = "lib", 54 | srcs = [":srcs"], 55 | deps = DEPS + [ 56 | ":picocli", 57 | ], 58 | ) 59 | 60 | java_binary( 61 | name = "runner", 62 | main_class = "build.bazel.gradle.GradleRunner", 63 | visibility = ["//visibility:public"], 64 | runtime_deps = [":lib"], 65 | ) 66 | 67 | java_binary( 68 | name = "wrapper", 69 | main_class = "build.bazel.gradle.GradleW", 70 | resources = [":logback.xml"], 71 | visibility = ["//visibility:public"], 72 | runtime_deps = [":lib"] + DEPS, 73 | ) 74 | 75 | native_image( 76 | name = "native", 77 | main_class = "build.bazel.gradle.GradleRunner", 78 | visibility = ["//visibility:public"], 79 | deps = [":lib"], 80 | ) 81 | 82 | alias( 83 | name = "java", 84 | actual = "runner", 85 | visibility = ["//visibility:public"], 86 | ) 87 | -------------------------------------------------------------------------------- /.github/workflows/deploy.docs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Docs 3 | 4 | "on": 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: {} 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | deployments: write 18 | 19 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 20 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 21 | concurrency: 22 | group: "pages" 23 | cancel-in-progress: false 24 | 25 | jobs: 26 | build: 27 | name: "Build: Docs" 28 | continue-on-error: true 29 | runs-on: ubuntu-latest 30 | steps: 31 | - name: Harden Runner 32 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 33 | with: 34 | egress-policy: audit 35 | - name: "Setup: Checkout" 36 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 37 | - name: "Setup: Pages" 38 | uses: actions/configure-pages@f156874f8191504dae5b037505266ed5dda6c382 # v3.0.6 39 | - name: "Build: Jekyll" 40 | uses: actions/jekyll-build-pages@058068233b22675635bdf8dfa178d6ae77f12694 # v1.0.8 41 | with: 42 | source: ./docs 43 | destination: ./_site 44 | - name: "Artifact: Upload" 45 | continue-on-error: true 46 | uses: actions/upload-pages-artifact@a753861a5debcf57bf8b404356158c8e1e33150c # v2.0.0 47 | 48 | deploy: 49 | name: "Deploy: Docs" 50 | environment: 51 | name: github-pages 52 | url: ${{ steps.deployment.outputs.page_url }} 53 | runs-on: ubuntu-latest 54 | needs: build 55 | continue-on-error: true 56 | steps: 57 | - name: Harden Runner 58 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 59 | with: 60 | egress-policy: audit 61 | - name: "Deploy: GitHub Pages" 62 | id: deployment 63 | continue-on-error: true 64 | uses: actions/deploy-pages@9dbe3824824f8a1377b8e298bafde1a50ede43e5 # v2.0.4 65 | -------------------------------------------------------------------------------- /.github/workflows/on.push.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "CI" 3 | 4 | "on": 5 | ## Events: Pushes on Main 6 | push: 7 | branches: 8 | - main 9 | paths: 10 | - docs/**/*.* 11 | - e2e/**/*.* 12 | - gradle/**/*.* 13 | - internal/**/*.* 14 | - java/**/*.* 15 | - tools/**/*.* 16 | - "*.bzl" 17 | - "*.bazel" 18 | 19 | jobs: 20 | dependency-graph: 21 | name: "Dependency Graph" 22 | continue-on-error: true 23 | runs-on: ubuntu-latest 24 | steps: 25 | - name: Harden Runner 26 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 27 | with: 28 | egress-policy: audit 29 | - name: "Setup: Checkout" 30 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 31 | - name: "Report: Dependency Graph" 32 | continue-on-error: true 33 | uses: advanced-security/maven-dependency-submission-action@c5ad0fd6b977364190852883b46728f25a9617c3 # v3.0.2 34 | 35 | build: 36 | name: "Build (${{ matrix.label }})" 37 | uses: ./.github/workflows/module.build.yml 38 | strategy: 39 | fail-fast: false 40 | matrix: 41 | runner: [ubuntu-latest] 42 | main: [false] 43 | label: ["Ubuntu"] 44 | labs: [false] 45 | flags: ["--config=linux"] 46 | testlabel: ["Ubuntu"] 47 | coverage: [false] 48 | include: 49 | # Bazel 6 50 | - runner: ubuntu-latest 51 | label: Ubuntu 52 | labs: false 53 | main: false 54 | coverage: false 55 | flags: --config=linux 56 | testlabel: Ubuntu 57 | - runner: macos-latest 58 | label: macOS 59 | labs: false 60 | main: false 61 | coverage: false 62 | flags: --config=macos 63 | testlabel: macOS 64 | # - runner: windows-2022 65 | # label: Windows 66 | # labs: false 67 | # main: false 68 | # coverage: false 69 | # flags: --config=windows 70 | # testlabel: Windows 71 | 72 | secrets: inherit 73 | with: 74 | runner: ${{ matrix.runner }} 75 | label: ${{ matrix.label }} 76 | labs: ${{ matrix.labs }} 77 | main: ${{ matrix.main }} 78 | flags: ${{ matrix.flags }} 79 | coverage: ${{ matrix.coverage }} 80 | -------------------------------------------------------------------------------- /java/build/bazel/gradle/GradleTool.kt: -------------------------------------------------------------------------------- 1 | 2 | package build.bazel.gradle 3 | 4 | import org.slf4j.Logger 5 | import org.slf4j.LoggerFactory 6 | import java.io.File 7 | import java.nio.file.Files 8 | import java.nio.file.Path 9 | import kotlin.io.path.Path 10 | import kotlin.io.path.exists 11 | 12 | 13 | object GradleTool { 14 | // Logger. 15 | private val logging: Logger = LoggerFactory.getLogger(GradleTool::class.java.name) 16 | 17 | @JvmStatic private fun outputTarget(project: Path, relative: String, target: String): Pair { 18 | // base: `bazel-out/darwin_arm64-fastbuild/bin/e2e/project` 19 | // project: `e2e/project` 20 | // relative: `build/libs/sample-project.jar` 21 | // target: `bazel-out/darwin_arm64-fastbuild/bin/e2e/project/build/libs/sample-project.jar` 22 | return ( 23 | // source: 24 | // `e2e/project/build/libs/sample-project.jar` 25 | project.resolve(relative) 26 | ) to ( 27 | // target: 28 | Path.of(target).toFile() 29 | ) 30 | } 31 | 32 | @JvmStatic fun mountOutputs(root: Path, logFilePath: Path, outputs: List) { 33 | val cwd = Path(System.getProperty("user.dir")) 34 | val logFile = root.resolve(logFilePath) 35 | val outBase = logFile.parent 36 | 37 | if (!outBase.exists()) { 38 | Files.createDirectories(outBase) 39 | } 40 | if (!outBase.exists()) error( 41 | "Cannot locate output base for Gradle artifacts" 42 | ) 43 | 44 | outputs.map { 45 | val artifact = it.source 46 | val relativeTarget = it.target 47 | val (source, target) = outputTarget(root, artifact, relativeTarget) 48 | logging.info("Checking output ${cwd}/$artifact (target: $target)") 49 | 50 | cwd.resolve(source).toFile().let { file -> 51 | if (!file.exists()) { 52 | error("Output does not exist: ${file.path}") 53 | } 54 | val outDir = target.parentFile 55 | if (!outDir.exists()) { 56 | Files.createDirectories(outDir.toPath()) 57 | } 58 | 59 | // copy the output 60 | file.copyTo( 61 | target = target, 62 | overwrite = false, 63 | ) 64 | logging.info("Output copied to Bazel base.") 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /.aspect/bazelrc/performance.bazelrc: -------------------------------------------------------------------------------- 1 | # Speed up all builds by not checking if output files have been modified. Lets you make changes to 2 | # the output tree without triggering a build for local debugging. For example, you can modify 3 | # [rules_js](https://github.com/aspect-build/rules_js) 3rd party npm packages in the output tree 4 | # when local debugging. 5 | # Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/pkgcache/PackageOptions.java#L185 6 | build --noexperimental_check_output_files 7 | fetch --noexperimental_check_output_files 8 | query --noexperimental_check_output_files 9 | 10 | # Don't apply `--noremote_upload_local_results` and `--noremote_accept_cached` to the disk cache. 11 | # If you have both `--noremote_upload_local_results` and `--disk_cache`, then this fixes a bug where 12 | # Bazel doesn't write to the local disk cache as it treats as a remote cache. 13 | # Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_remote_results_ignore_disk 14 | build --incompatible_remote_results_ignore_disk 15 | 16 | # Directories used by sandboxed non-worker execution may be reused to avoid unnecessary setup costs. 17 | # Save time on Sandbox creation and deletion when many of the same kind of action run during the 18 | # build. 19 | # No longer experimental in Bazel 6: https://github.com/bazelbuild/bazel/commit/c1a95501a5611878e5cc43a3cc531f2b9e47835b 20 | # Docs: https://bazel.build/reference/command-line-reference#flag--reuse_sandbox_directories 21 | build --experimental_reuse_sandbox_directories 22 | 23 | # Do not build runfiles symlink forests for external repositories under 24 | # `.runfiles/wsname/external/repo` (in addition to `.runfiles/repo`). This reduces runfiles & 25 | # sandbox creation times & prevents accidentally depending on this feature which may flip to off by 26 | # default in the future. Note, some rules may fail under this flag, please file issues with the rule 27 | # author. 28 | # Docs: https://bazel.build/reference/command-line-reference#flag--legacy_external_runfiles 29 | build --nolegacy_external_runfiles 30 | 31 | # Some actions are always IO-intensive but require little compute. It's wasteful to put the output 32 | # in the remote cache, it just saturates the network and fills the cache storage causing earlier 33 | # evictions. It's also not worth sending them for remote execution. 34 | # For actions like PackageTar it's usually faster to just re-run the work locally every time. 35 | # You'll have to look at an execution log to figure out what other action mnemonics you care about. 36 | # In some cases you may need to patch rulesets to add a mnemonic to actions that don't have one. 37 | # https://bazel.build/reference/command-line-reference#flag--modify_execution_info 38 | build --modify_execution_info=PackageTar=+no-remote 39 | -------------------------------------------------------------------------------- /.github/workflows/check.lint-yaml.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Lint: YAML" 3 | 4 | concurrency: 5 | group: lint-yaml-${{ github.head_ref || github.run_id }} 6 | cancel-in-progress: true 7 | 8 | "on": 9 | ## Check YAML on merge queue insertion 10 | merge_group: {} 11 | 12 | ## Check on release 13 | release: 14 | types: [created] 15 | 16 | ## Check on push to `main` if modified 17 | push: 18 | branches: 19 | - main 20 | paths: 21 | - ".github/workflows/*.yaml" 22 | - ".github/workflows/*.yml" 23 | - ".bazelci/presubmit.yml" 24 | - ".bcr/*.yml" 25 | 26 | ## Check each PR change against `main` 27 | pull_request: 28 | paths: 29 | - ".github/workflows/*.yaml" 30 | - ".github/workflows/*.yml" 31 | - ".bazelci/presubmit.yml" 32 | - ".bcr/*.yml" 33 | 34 | permissions: 35 | contents: read 36 | 37 | jobs: 38 | ## Task: Lint workflows via Actionlint 39 | lint-workflows: 40 | name: "Lint: Workflows" 41 | uses: elide-dev/build-infra/.github/workflows/check.actions-lint.ci.yml@c54d8227f4bd37839a67ab9cb71fb59a0d197aee 42 | permissions: 43 | checks: write 44 | pull-requests: read 45 | id-token: write 46 | contents: read 47 | 48 | ## Task: Lint Bazel Central Registry config files 49 | lint-bcr-yaml: 50 | name: "Lint: BCR" 51 | runs-on: ubuntu-latest 52 | permissions: 53 | contents: "read" 54 | id-token: "write" 55 | checks: "write" 56 | pull-requests: "read" 57 | steps: 58 | - name: Harden Runner 59 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 60 | with: 61 | egress-policy: audit 62 | - name: "Setup: Checkout" 63 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 64 | - name: "Lint: YAML" 65 | uses: karancode/yamllint-github-action@0a904064817924fc6fb449a32f67f25bfacc48ae # master 66 | with: 67 | yamllint_file_or_dir: ".bcr" 68 | yamllint_config_filepath: "./.github/.yamllint.yml" 69 | env: 70 | GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} 71 | 72 | ## Task: Lint Bazel CI config files 73 | lint-bazelci-yaml: 74 | name: "Lint: Bazel CI" 75 | runs-on: ubuntu-latest 76 | permissions: 77 | contents: "read" 78 | id-token: "write" 79 | checks: "write" 80 | pull-requests: "read" 81 | steps: 82 | - name: Harden Runner 83 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 84 | with: 85 | egress-policy: audit 86 | - name: "Setup: Checkout" 87 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 88 | - name: "Lint: YAML" 89 | uses: karancode/yamllint-github-action@0a904064817924fc6fb449a32f67f25bfacc48ae # master 90 | with: 91 | yamllint_file_or_dir: ".bazelci" 92 | yamllint_config_filepath: "./.github/.yamllint.yml" 93 | env: 94 | GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} 95 | -------------------------------------------------------------------------------- /java/build/bazel/gradle/FileUtils.java: -------------------------------------------------------------------------------- 1 | 2 | package build.bazel.gradle; 3 | 4 | import com.google.common.base.Joiner; 5 | import com.google.common.base.Optional; 6 | import com.google.common.base.Preconditions; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | 11 | 12 | public final class FileUtils { 13 | private static final Joiner PATH_JOINER = Joiner.on(File.separatorChar); 14 | private static final Joiner COMMA_SEPARATED_JOINER = Joiner.on(", "); 15 | private static final Joiner UNIX_NEW_LINE_JOINER = Joiner.on('\n'); 16 | 17 | public FileUtils() { } 18 | 19 | /** 20 | * Deletes a file or a directory if it exists. If the directory is not empty, its contents will 21 | * be deleted recursively. 22 | * 23 | * @param file the file or directory to delete. The file/directory may not exist; if the 24 | * directory exists, it may be non-empty. 25 | */ 26 | public static void deleteRecursivelyIfExists(File file) throws IOException { 27 | PathUtils.deleteRecursivelyIfExists(file.toPath()); 28 | } 29 | 30 | /** 31 | * Recursively deletes a path. 32 | * 33 | * @param path the path delete, may exist or not 34 | * @throws IOException failed to delete the file / directory 35 | */ 36 | public static void deletePath(final File path) throws IOException { 37 | deleteRecursivelyIfExists(path); 38 | } 39 | 40 | /** 41 | * Recursively deletes a directory content (including the sub directories) but not itself. 42 | * 43 | * @param directory the directory, that must exist and be a valid directory 44 | * @throws IOException failed to delete the file / directory 45 | */ 46 | public static void deleteDirectoryContents(final File directory) throws IOException { 47 | Preconditions.checkArgument(directory.isDirectory(), "!directory.isDirectory"); 48 | 49 | File[] files = directory.listFiles(); 50 | Preconditions.checkNotNull(files); 51 | for (File file : files) { 52 | deletePath(file); 53 | } 54 | } 55 | 56 | /** 57 | * Makes sure {@code path} is an empty directory. If {@code path} is a directory, its contents 58 | * are removed recursively, leaving an empty directory. If {@code path} is not a directory, 59 | * it is removed and a directory created with the given path. If {@code path} does not 60 | * exist, a directory is created with the given path. 61 | * 62 | * @param path the path, that may exist or not and may be a file or directory 63 | * @throws IOException failed to delete directory contents, failed to delete {@code path} or 64 | * failed to create a directory at {@code path} 65 | */ 66 | public static void cleanOutputDir(File path) throws IOException { 67 | if (!path.isDirectory()) { 68 | if (path.exists()) { 69 | deletePath(path); 70 | } 71 | 72 | if (!path.mkdirs()) { 73 | throw new IOException(String.format("Could not create empty folder %s", path)); 74 | } 75 | 76 | return; 77 | } 78 | 79 | deleteDirectoryContents(path); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /.github/workflows/on.pr.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "PR" 3 | 4 | "on": 5 | ## Run on PR filings 6 | pull_request: 7 | paths: 8 | - docs/**/*.* 9 | - e2e/**/*.* 10 | - gradle/**/*.* 11 | - internal/**/*.* 12 | - java/**/*.* 13 | - tools/**/*.* 14 | 15 | ## Run on PR queue check requests 16 | merge_group: {} 17 | 18 | concurrency: 19 | # Cancel previous actions from the same PR: https://stackoverflow.com/a/72408109 20 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 21 | cancel-in-progress: true 22 | 23 | jobs: 24 | dependency-graph: 25 | name: "Dependency Graph" 26 | continue-on-error: true 27 | runs-on: ubuntu-latest 28 | permissions: 29 | id-token: write 30 | contents: write 31 | steps: 32 | - name: Harden Runner 33 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 34 | with: 35 | egress-policy: audit 36 | - name: "Setup: Checkout" 37 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 38 | - name: "Report: Dependency Graph" 39 | continue-on-error: true 40 | uses: advanced-security/maven-dependency-submission-action@c5ad0fd6b977364190852883b46728f25a9617c3 # v3.0.2 41 | 42 | dependency-review: 43 | name: "Dependency Review" 44 | runs-on: ubuntu-latest 45 | steps: 46 | - name: Harden Runner 47 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 48 | with: 49 | egress-policy: audit 50 | - name: "Checkout Repository" 51 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 52 | - name: "Dependency Review" 53 | uses: actions/dependency-review-action@f6fff72a3217f580d5afd49a46826795305b63c7 # v3.0.8 54 | with: 55 | config-file: "./.github/dependency-review-config.yml" 56 | 57 | test: 58 | name: "Tests: ${{ matrix.label }}" 59 | uses: ./.github/workflows/module.build.yml 60 | strategy: 61 | fail-fast: false 62 | matrix: 63 | runner: [ubuntu-latest] 64 | main: [false] 65 | label: ["Ubuntu"] 66 | labs: [false] 67 | flags: ["--config=linux"] 68 | testlabel: ["Ubuntu"] 69 | coverage: [false] 70 | include: 71 | # Bazel 6 72 | - runner: ubuntu-latest 73 | label: Ubuntu 74 | labs: false 75 | main: false 76 | coverage: false 77 | flags: --config=linux 78 | - runner: macos-latest 79 | label: macOS 80 | labs: false 81 | main: false 82 | coverage: false 83 | flags: --config=macos 84 | # - runner: windows-2022 85 | # label: Windows 86 | # labs: false 87 | # main: false 88 | # coverage: false 89 | # flags: --config=windows 90 | 91 | secrets: inherit 92 | with: 93 | runner: ${{ matrix.runner }} 94 | label: ${{ matrix.label }} 95 | labs: ${{ matrix.labs }} 96 | main: ${{ matrix.main }} 97 | flags: ${{ matrix.flags }} 98 | coverage: ${{ matrix.coverage }} 99 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /tools/bazel/strict.bazelrc: -------------------------------------------------------------------------------- 1 | build:strict --incompatible_allow_tags_propagation 2 | build:strict --incompatible_always_check_depset_elements 3 | build:strict --incompatible_avoid_conflict_dlls 4 | build:strict --incompatible_config_setting_private_default_visibility 5 | build:strict --incompatible_default_to_explicit_init_py 6 | build:strict --incompatible_depset_for_libraries_to_link_getter 7 | build:strict --incompatible_disable_expand_if_all_available_in_flag_set 8 | build:strict --incompatible_disable_native_android_rules 9 | build:strict --incompatible_disable_runtimes_filegroups 10 | build:strict --incompatible_disallow_legacy_javainfo 11 | build:strict --incompatible_disallow_legacy_py_provider 12 | build:strict --incompatible_do_not_split_linking_cmdline 13 | build:strict --incompatible_dont_emit_static_libgcc 14 | build:strict --incompatible_dont_enable_host_nonhost_crosstool_features 15 | build:strict --incompatible_dont_use_javasourceinfoprovider 16 | build:strict --incompatible_enforce_config_setting_visibility 17 | build:strict --incompatible_exclusive_test_sandboxed 18 | build:strict --incompatible_existing_rules_immutable_view 19 | build:strict --incompatible_force_strict_header_check_from_starlark 20 | build:strict --incompatible_java_common_parameters 21 | build:strict --incompatible_legacy_local_fallback 22 | build:strict --incompatible_linkopts_in_user_link_flags 23 | build:strict --incompatible_make_thinlto_command_lines_standalone 24 | build:strict --incompatible_merge_genfiles_directory 25 | build:strict --incompatible_new_actions_api 26 | build:strict --incompatible_no_attr_license 27 | build:strict --incompatible_py2_outputs_are_suffixed 28 | build:strict --incompatible_py3_is_default 29 | build:strict --incompatible_remote_output_paths_relative_to_input_root 30 | build:strict --incompatible_remote_results_ignore_disk 31 | build:strict --incompatible_remote_symlinks 32 | build:strict --incompatible_remove_cpu_and_compiler_attributes_from_cc_toolchain 33 | build:strict --incompatible_remove_legacy_whole_archive 34 | build:strict --incompatible_require_ctx_in_configure_features 35 | build:strict --incompatible_require_linker_input_cc_api 36 | build:strict --incompatible_run_shell_command_string 37 | build:strict --incompatible_strict_action_env 38 | build:strict --incompatible_struct_has_no_methods 39 | build:strict --incompatible_top_level_aspects_require_providers 40 | build:strict --incompatible_use_cc_configure_from_rules_cc 41 | build:strict --incompatible_use_platforms_repo_for_constraints 42 | build:strict --incompatible_use_python_toolchains 43 | build:strict --incompatible_validate_top_level_header_inclusions 44 | build:strict --incompatible_visibility_private_attributes_at_definition 45 | 46 | build:strict-noide --incompatible_disable_target_provider_fields 47 | 48 | build:strict-broken --incompatible_strict_action_env 49 | build:strict-broken --incompatible_disallow_empty_glob 50 | build:strict-broken --incompatible_check_visibility_for_toolchains 51 | build:strict-broken --incompatible_disallow_struct_provider_syntax 52 | build:strict-broken --incompatible_no_implicit_file_export 53 | build:strict-broken --incompatible_no_rule_outputs_param 54 | build:strict-broken --incompatible_python_disallow_native_rules 55 | build:strict-broken --incompatible_stop_exporting_language_modules 56 | -------------------------------------------------------------------------------- /.github/workflows/check.scorecards.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This workflow uses actions that are not certified by GitHub. They are provided 3 | # by a third-party and are governed by separate terms of service, privacy 4 | # policy, and support documentation. 5 | 6 | name: Scorecard 7 | "on": 8 | # For Branch-Protection check. Only the default branch is supported. See 9 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection 10 | branch_protection_rule: 11 | # To guarantee Maintained check is occasionally updated. See 12 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained 13 | schedule: 14 | - cron: "20 7 * * 2" 15 | push: 16 | branches: ["main"] 17 | 18 | # Declare default permissions as read only. 19 | permissions: read-all 20 | 21 | jobs: 22 | analysis: 23 | name: Scorecard analysis 24 | runs-on: ubuntu-latest 25 | permissions: 26 | # Needed to upload the results to code-scanning dashboard. 27 | security-events: write 28 | # Needed to publish results and get a badge (see publish_results below). 29 | id-token: write 30 | contents: read 31 | actions: read 32 | 33 | steps: 34 | - name: Harden Runner 35 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 36 | with: 37 | egress-policy: audit 38 | 39 | - name: "Checkout code" 40 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 41 | with: 42 | persist-credentials: false 43 | 44 | - name: "Run analysis" 45 | uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # v2.2.0 46 | with: 47 | results_file: results.sarif 48 | results_format: sarif 49 | # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: 50 | # - you want to enable the Branch-Protection check on a *public* repository, or 51 | # - you are installing Scorecards on a *private* repository 52 | # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. 53 | # repo_token: ${{ secrets.SCORECARD_TOKEN }} 54 | 55 | # Public repositories: 56 | # - Publish results to OpenSSF REST API for easy access by consumers 57 | # - Allows the repository to include the Scorecard badge. 58 | # - See https://github.com/ossf/scorecard-action#publishing-results. 59 | # For private repositories: 60 | # - `publish_results` will always be set to `false`, regardless 61 | # of the value entered here. 62 | publish_results: true 63 | 64 | # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF 65 | # format to the repository Actions tab. 66 | - name: "Upload artifact" 67 | uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 68 | with: 69 | name: SARIF file 70 | path: results.sarif 71 | retention-days: 5 72 | 73 | # Upload the results to GitHub's code scanning dashboard. 74 | - name: "Upload to code-scanning" 75 | uses: github/codeql-action/upload-sarif@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 76 | with: 77 | sarif_file: results.sarif 78 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies within all project spaces, and it also applies when 49 | an individual is representing the project or its community in public spaces. 50 | Examples of representing a project or community include using an official 51 | project e-mail address, posting via an official social media account, or acting 52 | as an appointed representative at an online or offline event. Representation of 53 | a project may be further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at benasher44@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /.aspect/bazelrc/ci.bazelrc: -------------------------------------------------------------------------------- 1 | # We recommend enforcing a policy that keeps your CI from being slowed down 2 | # by individual test targets that should be optimized 3 | # or split up into multiple test targets with sharding or manually. 4 | # Set this flag to exclude targets that have their timeout set to eternal (>15m) from running on CI. 5 | # Docs: https://bazel.build/docs/user-manual#test-timeout-filters 6 | test --test_timeout_filters=-eternal 7 | 8 | # Set this flag to enable re-tries of failed tests on CI. 9 | # When any test target fails, try one or more times. This applies regardless of whether the "flaky" 10 | # tag appears on the target definition. 11 | # This is a tradeoff: legitimately failing tests will take longer to report, 12 | # but we can paper over flaky tests that pass most of the time. 13 | # The alternative is to mark every flaky test with the `flaky = True` attribute, but this requires 14 | # the buildcop to make frequent code edits. 15 | # Not recommended for local builds so that the flakiness is observed during development and thus 16 | # is more likely to get fixed. 17 | # Note that when passing after the first attempt, Bazel will give a special "FLAKY" status. 18 | # Docs: https://bazel.build/docs/user-manual#flaky-test-attempts 19 | test --flaky_test_attempts=2 20 | 21 | # Announce all announces command options read from the bazelrc file(s) when starting up at the 22 | # beginning of each Bazel invocation. This is very useful on CI to be able to inspect what Bazel rc 23 | # settings are being applied on each run. 24 | # Docs: https://bazel.build/docs/user-manual#announce-rc 25 | build --announce_rc 26 | 27 | # Add a timestamp to each message generated by Bazel specifying the time at which the message was 28 | # displayed. 29 | # Docs: https://bazel.build/docs/user-manual#show-timestamps 30 | build --show_timestamps 31 | 32 | # Only show progress every 60 seconds on CI. 33 | # We want to find a compromise between printing often enough to show that the build isn't stuck, 34 | # but not so often that we produce a long log file that requires a lot of scrolling. 35 | # https://bazel.build/reference/command-line-reference#flag--show_progress_rate_limit 36 | build --show_progress_rate_limit=60 37 | 38 | # Use cursor controls in screen output. 39 | # Docs: https://bazel.build/docs/user-manual#curses 40 | build --curses=yes 41 | 42 | # Use colors to highlight output on the screen. Set to `no` if your CI does not display colors. 43 | # Docs: https://bazel.build/docs/user-manual#color 44 | build --color=yes 45 | 46 | # The terminal width in columns. Configure this to override the default value based on what your CI system renders. 47 | # Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/runtime/UiOptions.java#L151 48 | build --terminal_columns=143 49 | 50 | ###################################### 51 | # Generic remote cache configuration # 52 | ###################################### 53 | 54 | # Only download remote outputs of top level targets to the local machine. 55 | # Docs: https://bazel.build/reference/command-line-reference#flag--remote_download_toplevel 56 | build --remote_download_toplevel 57 | 58 | # The maximum amount of time to wait for remote execution and cache calls. 59 | # https://bazel.build/reference/command-line-reference#flag--remote_timeout 60 | build --remote_timeout=3600 61 | 62 | # Upload locally executed action results to the remote cache. 63 | # Docs: https://bazel.build/reference/command-line-reference#flag--remote_upload_local_results 64 | build --remote_upload_local_results 65 | 66 | # Fall back to standalone local execution strategy if remote execution fails. If the grpc remote 67 | # cache connection fails, it will fail the build, add this so it falls back to the local cache. 68 | # Docs: https://bazel.build/reference/command-line-reference#flag--remote_local_fallback 69 | build --remote_local_fallback 70 | 71 | # Fixes builds hanging on CI that get the TCP connection closed without sending RST packets. 72 | # Docs: https://bazel.build/reference/command-line-reference#flag--grpc_keepalive_time 73 | build --grpc_keepalive_time=30s 74 | -------------------------------------------------------------------------------- /.aspect/bazelrc/correctness.bazelrc: -------------------------------------------------------------------------------- 1 | # Do not upload locally executed action results to the remote cache. 2 | # This should be the default for local builds so local builds cannot poison the remote cache. 3 | # It should be flipped to `--remote_upload_local_results` on CI 4 | # by using `--bazelrc=.aspect/bazelrc/ci.bazelrc`. 5 | # Docs: https://bazel.build/reference/command-line-reference#flag--remote_upload_local_results 6 | build --noremote_upload_local_results 7 | 8 | # Don't allow network access for build actions in the sandbox. 9 | # Ensures that you don't accidentally make non-hermetic actions/tests which depend on remote 10 | # services. 11 | # Developers should tag targets with `tags=["requires-network"]` to opt-out of the enforcement. 12 | # Docs: https://bazel.build/reference/command-line-reference#flag--sandbox_default_allow_network 13 | build --sandbox_default_allow_network=false 14 | 15 | # Warn if a test's timeout is significantly longer than the test's actual execution time. 16 | # Bazel's default for test_timeout is medium (5 min), but most tests should instead be short (1 min). 17 | # While a test's timeout should be set such that it is not flaky, a test that has a highly 18 | # over-generous timeout can hide real problems that crop up unexpectedly. 19 | # For instance, a test that normally executes in a minute or two should not have a timeout of 20 | # ETERNAL or LONG as these are much, much too generous. 21 | # Docs: https://bazel.build/docs/user-manual#test-verbose-timeout-warnings 22 | test --test_verbose_timeout_warnings 23 | 24 | # Allow the Bazel server to check directory sources for changes. Ensures that the Bazel server 25 | # notices when a directory changes, if you have a directory listed in the srcs of some target. 26 | # Recommended when using 27 | # [copy_directory](https://github.com/aspect-build/bazel-lib/blob/main/docs/copy_directory.md) and 28 | # [rules_js](https://github.com/aspect-build/rules_js) since npm package are source directories 29 | # inputs to copy_directory actions. 30 | # Docs: https://bazel.build/reference/command-line-reference#flag--host_jvm_args 31 | startup --host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1 32 | 33 | # Allow exclusive tests to run in the sandbox. Fixes a bug where Bazel doesn't enable sandboxing for 34 | # tests with `tags=["exclusive"]`. 35 | # Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_exclusive_test_sandboxed 36 | test --incompatible_exclusive_test_sandboxed 37 | 38 | # Use a static value for `PATH` and does not inherit `LD_LIBRARY_PATH`. Doesn't let environment 39 | # variables like `PATH` sneak into the build, which can cause massive cache misses when they change. 40 | # Use `--action_env=ENV_VARIABLE` if you want to inherit specific environment variables from the 41 | # client, but note that doing so can prevent cross-user caching if a shared cache is used. 42 | # Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_strict_action_env 43 | build --incompatible_strict_action_env 44 | 45 | # Propagate tags from a target declaration to the actions' execution requirements. 46 | # Ensures that tags applied in your BUILD file, like `tags=["no-remote"]` 47 | # get propagated to actions created by the rule. 48 | # Without this option, you rely on rules authors to manually check the tags you passed 49 | # and apply relevant ones to the actions they create. 50 | # See https://github.com/bazelbuild/bazel/issues/8830 for details. 51 | # Docs: https://bazel.build/reference/command-line-reference#flag--experimental_allow_tags_propagation 52 | build --experimental_allow_tags_propagation 53 | fetch --experimental_allow_tags_propagation 54 | query --experimental_allow_tags_propagation 55 | 56 | # Do not automatically create `__init__.py` files in the runfiles of Python targets. Fixes the wrong 57 | # default that comes from Google's internal monorepo by using `__init__.py` to delimit a Python 58 | # package. Precisely, when a `py_binary` or `py_test` target has `legacy_create_init` set to `auto (the 59 | # default), it is treated as false if and only if this flag is set. See 60 | # https://github.com/bazelbuild/bazel/issues/10076. 61 | # Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_default_to_explicit_init_py 62 | build --incompatible_default_to_explicit_init_py 63 | -------------------------------------------------------------------------------- /MODULE.bazel: -------------------------------------------------------------------------------- 1 | "Gradle Rules for Bazel" 2 | 3 | module( 4 | name = "rules_gradle", 5 | version = "0.0.1", 6 | ) 7 | 8 | GRADLE_VERSION = "8.2.1" 9 | 10 | GO_VERSION = "1.20.6" 11 | 12 | ## 13 | ## Dependencies: API 14 | ## 15 | 16 | bazel_dep( 17 | name = "platforms", 18 | version = "0.0.7", 19 | ) 20 | bazel_dep( 21 | name = "bazel_features", 22 | version = "1.0.0", 23 | ) 24 | bazel_dep( 25 | name = "rules_java", 26 | version = "6.4.0", 27 | ) 28 | bazel_dep( 29 | name = "bazel_skylib", 30 | version = "1.4.2", 31 | ) 32 | bazel_dep( 33 | name = "apple_support", 34 | version = "1.8.1", 35 | repo_name = "build_bazel_apple_support", 36 | ) 37 | 38 | ## 39 | ## Dependencies: Development 40 | ## 41 | 42 | # bazel_dep( 43 | # name = "rules_license", 44 | # version = "0.0.7", 45 | # dev_dependency = True, 46 | # ) 47 | # bazel_dep( 48 | # name = "rules_cc", 49 | # version = "0.0.8", 50 | # dev_dependency = True, 51 | # ) 52 | # bazel_dep( 53 | # name = "rules_python", 54 | # version = "0.25.0", 55 | # dev_dependency = True, 56 | # ) 57 | # bazel_dep( 58 | # name = "rules_testing", 59 | # version = "0.4.0", 60 | # dev_dependency = True, 61 | # ) 62 | # bazel_dep( 63 | # name = "aspect_bazel_lib", 64 | # version = "1.34.1", 65 | # dev_dependency = True, 66 | # ) 67 | # bazel_dep( 68 | # name = "aspect_rules_js", 69 | # version = "1.32.1", 70 | # dev_dependency = True, 71 | # ) 72 | # bazel_dep( 73 | # name = "rules_nodejs", 74 | # version = "6.0.1", 75 | # dev_dependency = True, 76 | # ) 77 | # bazel_dep( 78 | # name = "rules_go", 79 | # version = "0.41.0", 80 | # dev_dependency = True, 81 | # repo_name = "io_bazel_rules_go", 82 | # ) 83 | # bazel_dep( 84 | # name = "gazelle", 85 | # version = "0.32.0", 86 | # dev_dependency = True, 87 | # repo_name = "bazel_gazelle", 88 | # ) 89 | # bazel_dep( 90 | # name = "rules_jvm_external", 91 | # version = "5.3", 92 | # dev_dependency = True, 93 | # ) 94 | # bazel_dep( 95 | # name = "stardoc", 96 | # version = "0.6.2", 97 | # dev_dependency = True, 98 | # repo_name = "io_bazel_stardoc", 99 | # ) 100 | # bazel_dep( 101 | # name = "bazel_skylib_gazelle_plugin", 102 | # version = "1.4.2", 103 | # dev_dependency = True, 104 | # ) 105 | # bazel_dep( 106 | # name = "contrib_rules_jvm", 107 | # version = "0.18.0", 108 | # dev_dependency = True, 109 | # ) 110 | # bazel_dep( 111 | # name = "buildifier_prebuilt", 112 | # version = "6.3.3", 113 | # dev_dependency = True, 114 | # ) 115 | 116 | 117 | # ################################################################################ 118 | # # rules_cc 119 | # ################################################################################ 120 | 121 | # cc_configure = use_extension( 122 | # "@rules_cc//cc:extensions.bzl", 123 | # "cc_configure", 124 | # dev_dependency = True, 125 | # ) 126 | 127 | # use_repo(cc_configure, "local_config_cc_toolchains") 128 | 129 | # register_toolchains( 130 | # "@local_config_cc_toolchains//:all", 131 | # dev_dependency = True, 132 | # ) 133 | 134 | # ################################################################################ 135 | # # rules_jvm_external 136 | # ################################################################################ 137 | 138 | # maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") 139 | 140 | # maven.artifact( 141 | # artifact = "gradle-tooling-api", 142 | # group = "org.gradle", 143 | # version = GRADLE_VERSION, 144 | # ) 145 | 146 | # maven.install( 147 | # name = "maven", 148 | # repositories = [ 149 | # "https://maven.pkg.st", 150 | # "https://gradle.pkg.st", 151 | # "https://repo.gradle.org/gradle/libs-releases", 152 | # ], 153 | # generate_compat_repositories = False, 154 | # ) 155 | 156 | # use_repo( 157 | # maven, 158 | # "maven", 159 | # "maven_unpinned", 160 | # ) 161 | 162 | # ################################################################################ 163 | # # rules_js 164 | # ################################################################################ 165 | 166 | # npm = use_extension("@aspect_rules_js//npm:extensions.bzl", "npm", dev_dependency = True) 167 | 168 | # npm.npm_translate_lock( 169 | # name = "npm", 170 | # pnpm_lock = "//:pnpm-lock.yaml", 171 | # npmrc = "//:.npmrc", 172 | # ) 173 | 174 | # use_repo(npm, "npm") 175 | 176 | # ################################################################################ 177 | # # rules_go 178 | # ################################################################################ 179 | 180 | # go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk") 181 | 182 | # # Download an SDK for the host OS & architecture. 183 | # go_sdk.download( 184 | # version = GO_VERSION, 185 | # ) 186 | -------------------------------------------------------------------------------- /internal/task.bzl: -------------------------------------------------------------------------------- 1 | """Defines Bazel rules for interacting with Gradle.""" 2 | 3 | GRADLE_WRAPPER = "@rules_gradle//gradle/wrapper" 4 | GRADLE_TOOL_RUNNER = "@rules_gradle//java:runner" 5 | JAVA_TOOLCHAIN_TYPE = "@bazel_tools//tools/jdk:runtime_toolchain_type" 6 | 7 | _WrapperArgument = struct( 8 | PROJECT = "gradle_project", 9 | DISTRIBUTION = "gradle_distribution", 10 | BUILDFILE = "gradle_build_file", 11 | JAVA_HOME = "java_home", 12 | LOGFILE = "logfile", 13 | OUTPUT = "output", 14 | ) 15 | 16 | def _arg(args, argument, value = None): 17 | val = argument 18 | if value != None: 19 | val = "--%s=%s" % (argument, value) 20 | args.add(val) 21 | 22 | def _gradle_task_impl(ctx): 23 | """Run a Gradle task and capture a build output.""" 24 | 25 | # resolve the runner, declare a file to capture run output 26 | runner = ctx.attr.runner 27 | inputs, _, _ = ctx.resolve_command( 28 | tools = [runner], 29 | ) 30 | tool_bin = inputs[0] 31 | tool_path = tool_bin.path 32 | 33 | direct_inputs = [] 34 | transitive_inputs = [] 35 | 36 | # resolve java toolchains 37 | java = ctx.toolchains[JAVA_TOOLCHAIN_TYPE].java_runtime 38 | transitive_inputs.append(java.files) 39 | 40 | # resolve project and wrapper inputs 41 | project = ctx.attr.project.files.to_list() 42 | direct_inputs += project 43 | 44 | if ctx.attr.data: 45 | direct_inputs += ctx.attr.data 46 | 47 | if ctx.attr.distribution: 48 | direct_inputs += ctx.files.distribution 49 | 50 | wrapper = ctx.attr._wrapper.files.to_list() 51 | direct_inputs += wrapper 52 | 53 | tasklist = ctx.attr.tasks 54 | project_root = project[0].dirname 55 | 56 | env = {} 57 | outputs = [] 58 | args = ctx.actions.args() 59 | 60 | # prepare required arguments first 61 | _arg(args, _WrapperArgument.PROJECT, project_root) 62 | _arg(args, _WrapperArgument.BUILDFILE, ctx.file.build_file.path) 63 | _arg(args, _WrapperArgument.LOGFILE, ctx.outputs.output_log.path) 64 | _arg(args, _WrapperArgument.DISTRIBUTION, ctx.attr.distribution.files.to_list()[0].path) 65 | _arg(args, _WrapperArgument.JAVA_HOME, java.java_home) 66 | 67 | # gradle outputs to the `build` directory within the project root 68 | outputs.append(ctx.actions.declare_directory( 69 | "build", 70 | )) 71 | 72 | if ctx.attr.outputs != None and len(ctx.attr.outputs) > 0: 73 | for out in ctx.attr.outputs: 74 | if not out.startswith("build/"): 75 | out = "build/%s" % out 76 | outfile = ctx.actions.declare_file(out) 77 | outputs.append(outfile) 78 | _arg(args, _WrapperArgument.OUTPUT, "%s=%s" % (out, outfile.path)) 79 | 80 | # add each requisite task to the positional arguments list at the end 81 | for i in tasklist: 82 | args.add(i) 83 | 84 | # write our arguments file, which we will pass to the wrapper 85 | marker = ctx.actions.declare_file( 86 | "bazel-gradle-build.args", 87 | ) 88 | ctx.actions.write( 89 | marker, 90 | args, 91 | is_executable = False, 92 | ) 93 | 94 | # prepare list of inputs for gradle build execution 95 | inputs = depset( 96 | direct_inputs, 97 | transitive = transitive_inputs, 98 | ) 99 | 100 | # run gradle through the wrapper 101 | ctx.actions.run( 102 | inputs = inputs, 103 | outputs = outputs + [ctx.outputs.output_log], 104 | executable = ctx.executable.runner, 105 | progress_message = "Gradle %s: %s" % (ctx.label, ", ".join(tasklist)), 106 | mnemonic = "GradleTask", 107 | arguments = [args], 108 | env = env, 109 | use_default_shell_env = True, 110 | toolchain = JAVA_TOOLCHAIN_TYPE, 111 | tools = [ 112 | ctx.executable.runner, 113 | ], 114 | ) 115 | 116 | return [DefaultInfo( 117 | files = depset(outputs), 118 | runfiles = ctx.runfiles( 119 | collect_data = True, 120 | collect_default = True, 121 | files = [], 122 | ), 123 | )] 124 | 125 | _gradle_task_rule = rule( 126 | implementation = _gradle_task_impl, 127 | attrs = { 128 | "runner": attr.label( 129 | cfg = "exec", 130 | default = Label(GRADLE_TOOL_RUNNER), 131 | allow_files = True, 132 | executable = True, 133 | ), 134 | "output_log": attr.output(), 135 | "_wrapper": attr.label( 136 | default = GRADLE_WRAPPER, 137 | allow_files = True, 138 | ), 139 | "build_file": attr.label( 140 | allow_single_file = True, 141 | ), 142 | "project": attr.label( 143 | allow_files = True, 144 | ), 145 | "outputs": attr.string_list( 146 | mandatory = True, 147 | ), 148 | "tasks": attr.string_list( 149 | mandatory = False, 150 | default = ["build"], 151 | ), 152 | "debug": attr.bool( 153 | default = False, 154 | ), 155 | "distribution": attr.label( 156 | allow_files = True, 157 | default = Label("@gradle//file"), 158 | ), 159 | "data": attr.label_list(allow_files = True), 160 | }, 161 | fragments = [ 162 | "java", 163 | ], 164 | toolchains = [ 165 | JAVA_TOOLCHAIN_TYPE, 166 | ], 167 | ) 168 | 169 | def _gradle_task(name, build_file = "build.gradle.kts", tags = [], output_log = None, **kwargs): 170 | """ Macro to wrap a Gradle task target. """ 171 | 172 | _gradle_task_rule( 173 | name = name, 174 | build_file = build_file, 175 | output_log = output_log or (name + ".log"), 176 | tags = tags + [ 177 | "requires-network", 178 | ], 179 | **kwargs 180 | ) 181 | 182 | gradle_task = _gradle_task 183 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Gradle Rules for Bazel 3 | 4 | [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v1.4-ff69b4.svg)](CODE_OF_CONDUCT.md) 5 | ![Bazel 7](https://img.shields.io/badge/Bazel%207-black?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0My41NyA0My4zNyI%2BCiAgPGRlZnM%2BCiAgICA8c3R5bGU%2BCiAgICAgIC5jbHMtMSB7CiAgICAgICAgZmlsbDogIzAwNDMwMDsKICAgICAgfQoKICAgICAgLmNscy0yIHsKICAgICAgICBmaWxsOiAjMDA3MDFhOwogICAgICB9CgogICAgICAuY2xzLTMgewogICAgICAgIGZpbGw6ICM0M2EwNDc7CiAgICAgIH0KCiAgICAgIC5jbHMtNCB7CiAgICAgICAgZmlsbDogIzc2ZDI3NTsKICAgICAgfQogICAgPC9zdHlsZT4KICA8L2RlZnM%2BCiAgPGcgaWQ9IkxheWVyXzEtMiIgZGF0YS1uYW1lPSJMYXllciAxIj4KICAgIDxwYXRoIGNsYXNzPSJjbHMtMiIgZD0ibTIxLjc4LDMyLjY4djEwLjY5bC0xMC44OS0xMC44OXYtMTAuNjlsMTAuODksMTAuODlaIi8%2BCiAgICA8cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Im0yMS43OCwzMi42OGwxMC45LTEwLjg5djEwLjY5bC0xMC45LDEwLjg5di0xMC42OVoiLz4KICAgIDxwYXRoIGNsYXNzPSJjbHMtMyIgZD0ibTEwLjg5LDIxLjc5djEwLjY5TDAsMjEuNTh2LTEwLjY5bDEwLjg5LDEwLjlaIi8%2BCiAgICA8cGF0aCBjbGFzcz0iY2xzLTMiIGQ9Im00My41NywxMC44OXYxMC42OWwtMTAuODksMTAuOXYtMTAuNjlsMTAuODktMTAuOVoiLz4KICAgIDxwYXRoIGNsYXNzPSJjbHMtMyIgZD0ibTIxLjc4LDMyLjY4bC0xMC44OS0xMC44OSwxMC44OS0xMC45LDEwLjksMTAuOS0xMC45LDEwLjg5WiIvPgogICAgPHBhdGggY2xhc3M9ImNscy00IiBkPSJtMTAuODksMjEuNzlMMCwxMC44OSwxMC44OSwwbDEwLjg5LDEwLjg5LTEwLjg5LDEwLjlaIi8%2BCiAgICA8cGF0aCBjbGFzcz0iY2xzLTQiIGQ9Im0zMi42OCwyMS43OWwtMTAuOS0xMC45TDMyLjY4LDBsMTAuODksMTAuODktMTAuODksMTAuOVoiLz4KICA8L2c%2BCjwvc3ZnPg%3D%3D&logoColor=gray) 6 | ![Bzlmod](https://img.shields.io/badge/Bzlmod-black?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0My41NyA0My4zNyI%2BCiAgPGRlZnM%2BCiAgICA8c3R5bGU%2BCiAgICAgIC5jbHMtMSB7CiAgICAgICAgZmlsbDogIzAwNDMwMDsKICAgICAgfQoKICAgICAgLmNscy0yIHsKICAgICAgICBmaWxsOiAjMDA3MDFhOwogICAgICB9CgogICAgICAuY2xzLTMgewogICAgICAgIGZpbGw6ICM0M2EwNDc7CiAgICAgIH0KCiAgICAgIC5jbHMtNCB7CiAgICAgICAgZmlsbDogIzc2ZDI3NTsKICAgICAgfQogICAgPC9zdHlsZT4KICA8L2RlZnM%2BCiAgPGcgaWQ9IkxheWVyXzEtMiIgZGF0YS1uYW1lPSJMYXllciAxIj4KICAgIDxwYXRoIGNsYXNzPSJjbHMtMiIgZD0ibTIxLjc4LDMyLjY4djEwLjY5bC0xMC44OS0xMC44OXYtMTAuNjlsMTAuODksMTAuODlaIi8%2BCiAgICA8cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Im0yMS43OCwzMi42OGwxMC45LTEwLjg5djEwLjY5bC0xMC45LDEwLjg5di0xMC42OVoiLz4KICAgIDxwYXRoIGNsYXNzPSJjbHMtMyIgZD0ibTEwLjg5LDIxLjc5djEwLjY5TDAsMjEuNTh2LTEwLjY5bDEwLjg5LDEwLjlaIi8%2BCiAgICA8cGF0aCBjbGFzcz0iY2xzLTMiIGQ9Im00My41NywxMC44OXYxMC42OWwtMTAuODksMTAuOXYtMTAuNjlsMTAuODktMTAuOVoiLz4KICAgIDxwYXRoIGNsYXNzPSJjbHMtMyIgZD0ibTIxLjc4LDMyLjY4bC0xMC44OS0xMC44OSwxMC44OS0xMC45LDEwLjksMTAuOS0xMC45LDEwLjg5WiIvPgogICAgPHBhdGggY2xhc3M9ImNscy00IiBkPSJtMTAuODksMjEuNzlMMCwxMC44OSwxMC44OSwwbDEwLjg5LDEwLjg5LTEwLjg5LDEwLjlaIi8%2BCiAgICA8cGF0aCBjbGFzcz0iY2xzLTQiIGQ9Im0zMi42OCwyMS43OWwtMTAuOS0xMC45TDMyLjY4LDBsMTAuODksMTAuODktMTAuODksMTAuOVoiLz4KICA8L2c%2BCjwvc3ZnPg%3D%3D&logoColor=gray) 7 | 8 | --- 9 | 10 | > Latest release: _(None yet)_ 11 | 12 | > **Important** 13 | > Currently in **active development**. Feedback welcome but will probably break your build. 14 | 15 | Use [Gradle](https://gradle.org) from [Bazel](https://bazel.build), with support for: 16 | 17 | - Obtaining outputs built by Gradle from a Bazel build 18 | - Building with Gradle within Bazel's sandbox 19 | - Sandboxed Gradle home and build directories 20 | - Provide sealed Maven dependency repositories 21 | - Bazel-provided distribution of Gradle 22 | 23 | ## Installation 24 | 25 | **Via `WORKSPACE.bazel`:** 26 | 27 | ```starlark 28 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file") 29 | ``` 30 | 31 | ```starlark 32 | http_archive( 33 | name = "rules_gradle", 34 | sha256 = "...", 35 | strip_prefix = "rules_gradle-", 36 | urls = [ 37 | "https://github.com/sgammon/rules_gradle/archive//rules_gradle-.zip", 38 | ], 39 | ) 40 | ``` 41 | 42 | ```starlark 43 | http_file( 44 | name = "gradle", 45 | sha256 = "591855b517fc635b9e04de1d05d5e76ada3f89f5fc76f87978d1b245b4f69225", 46 | url = "https://dl.less.build/toolchains/gradle/gradle-8.3-bin.zip", 47 | ) 48 | ``` 49 | 50 | > You can use any Gradle toolchain download URL, including those provided by Gradle, in the form: 51 | > `https://services.gradle.org/distributions/gradle--.zip` 52 | 53 | ## Usage 54 | 55 | **In a `BUILD.bazel` file:** 56 | 57 | ```starlark 58 | load("@rules_gradle//gradle:defs.bzl", "gradle_task") 59 | 60 | filegroup( 61 | name = "files", 62 | srcs = [ 63 | "build.gradle.kts", 64 | "settings.gradle.kts", 65 | "src/main/java/HelloWorld.java", 66 | ], 67 | ) 68 | 69 | gradle_task( 70 | name = "project", 71 | outputs = [ 72 | "libs/sample-project.jar", 73 | ], 74 | project = ":files", 75 | ) 76 | ``` 77 | 78 | **Then, you can do:** 79 | 80 | ``` 81 | bazel build //path/to/your:project 82 | ``` 83 | 84 | **And obtain the outputs within the Bazel task graph:** 85 | 86 | ``` 87 | BUILD SUCCESSFUL in 639ms 88 | 2 actionable tasks: 2 executed 89 | Target //e2e/project:project up-to-date: 90 | bazel-bin/e2e/project/build 91 | bazel-bin/e2e/project/build/libs/sample-project.jar 92 | 93 | INFO: Elapsed time: 58.984s, Critical Path: 36.79s 94 | INFO: 395 processes: 44 internal, 331 darwin-sandbox, 20 worker. 95 | INFO: Build completed successfully, 395 total actions 96 | ``` 97 | 98 | ## Roadmap 99 | 100 | Stuff which is coming soon, time and APIs permitting, in rough order of priority: 101 | 102 | - Support for Windows 103 | - Support for Bzlmod 104 | - Extension to `rules_jvm_external` for easily installing Gradle plugins 105 | - Integration between Bazel's Java Toolchain and [Gradle Toolchains](https://docs.gradle.org/current/userguide/toolchains.html) 106 | - Stubbed Coursier-resolved repos 107 | - Dispatch of Gradle within the Bazel wrapper entrypoint 108 | - Analysis-time task graph integration (not sure this is even possible) 109 | - Gradle invocation with no daemon 110 | - Gradle plugin for tighter integration with Bazel 111 | - Support for Gradle invocations from Bazel persistent workers 112 | - Hand Gradle specific paths for toolchains (for instance, Java toolchain integration) 113 | - Native binary for wrapper (maybe) 114 | -------------------------------------------------------------------------------- /java/build/bazel/gradle/PathUtils.java: -------------------------------------------------------------------------------- 1 | 2 | package build.bazel.gradle; 3 | 4 | 5 | import java.io.IOException; 6 | import java.nio.file.AccessDeniedException; 7 | import java.nio.file.DirectoryNotEmptyException; 8 | import java.nio.file.Files; 9 | import java.nio.file.Path; 10 | import java.util.Iterator; 11 | import java.util.logging.Level; 12 | import java.util.logging.Logger; 13 | import java.util.stream.Stream; 14 | 15 | public final class PathUtils { 16 | /** 17 | * The number of times we should try deleting an empty directory, due to a limitation of the 18 | * Windows filesystem. See {@link #deleteRecursivelyIfExists(Path)}. 19 | */ 20 | private static final int EMPTY_DIRECTORY_DELETION_ATTEMPTS = 10; 21 | 22 | private PathUtils() {} 23 | 24 | /** 25 | * Deletes a file or a directory if it exists. If the directory is not empty, its contents will 26 | * be deleted recursively. Symbolic links to files or directories will be removed, but the files 27 | * or directories they link will not be altered. See b/71843178 29 | * 30 | * @param path the file or directory to delete. The file/directory may not exist; if the 31 | * directory exists, it may be non-empty. 32 | */ 33 | public static void deleteRecursivelyIfExists(Path path) throws IOException { 34 | if (Files.isDirectory(path) && !Files.isSymbolicLink(path)) { 35 | try (Stream pathsInDir = Files.list(path)) { 36 | Iterator iterator = pathsInDir.iterator(); 37 | while (iterator.hasNext()) { 38 | deleteRecursivelyIfExists(iterator.next()); 39 | } 40 | } 41 | } 42 | 43 | /* 44 | * HACK ALERT (http://issuetracker.google.com/77478235): 45 | * 46 | * We have confirmed through a number of experiments (see the bug above) that there is a 47 | * timing issue on the Windows filesystem, such that if we delete a directory immediately 48 | * after deleting its contents, the deletion might occasionally fail. If we wait for a 49 | * little after deleting its contents, then it has a higher chance to succeed. 50 | * 51 | * Note that in our experiments, we did not see any other thread/process accessing the same 52 | * directory at the time of deletion, so this is not a concurrency issue. 53 | * 54 | * We have also tried using Guava (com.google.common.io.MoreFiles.deleteRecursively) for 55 | * file deletion, but (surprisingly) Guava also faces this same problem. 56 | * 57 | * To work around the issue, we use a combination of waiting and retrying. Waiting alone is 58 | * not enough because it's unclear how long we should wait to be effective but not wasteful. 59 | * Retrying alone is not enough because we tried it before and still ran into this issue--- 60 | * see bug 131623810. 61 | */ 62 | try { 63 | try { 64 | Files.deleteIfExists(path); 65 | } catch (AccessDeniedException exception) { 66 | /* 67 | * NOTE (http://issuetracker.google.com/173689862): 68 | * 69 | * On Windows filesystem, a file marked read-only can not be deleted 70 | * by the Files.deleteIfExists(...) call above. On Linux and Darwin, 71 | * the same file can be deleted. 72 | * 73 | * Set the file to writable to make it work the same on Windows as 74 | * the others. 75 | * 76 | * See referenced bug for user scenario that triggered the issue. 77 | */ 78 | path.toFile().setWritable(true); 79 | Files.deleteIfExists(path); 80 | } 81 | } catch (DirectoryNotEmptyException exception) { 82 | // Keep deleting the directory until it succeeds or hits a reasonable limit. 83 | int failedAttempts = 1; // Count failed attempts, including the initial failure above 84 | while (failedAttempts < EMPTY_DIRECTORY_DELETION_ATTEMPTS) { 85 | try { 86 | // making the thread sleep for a minimum amount of time appears to improve the 87 | // odds of success. I suspect that JDK is forcing re-reading or flushing when 88 | // the thread is swapped in/out. 89 | Thread.sleep(1); 90 | } catch (InterruptedException e) { 91 | Thread.currentThread().interrupt(); 92 | throw new IOException(e); 93 | } 94 | try { 95 | Files.deleteIfExists(path); 96 | } catch (DirectoryNotEmptyException e) { 97 | failedAttempts++; 98 | continue; 99 | } 100 | break; 101 | } 102 | if (failedAttempts >= EMPTY_DIRECTORY_DELETION_ATTEMPTS) { 103 | throw new IOException( 104 | String.format( 105 | "Unable to delete directory '%s' after %d attempts", 106 | path, failedAttempts), 107 | exception); 108 | } 109 | } 110 | } 111 | 112 | /** 113 | * Adds a hook to the shutdown event of the JVM which will delete all files and directories at 114 | * the given path (inclusive) when the JVM exits. 115 | * 116 | * @param path the path to delete 117 | */ 118 | public static void addRemovePathHook(Path path) { 119 | Runtime.getRuntime().addShutdownHook( 120 | new Thread( 121 | () -> { 122 | try { 123 | PathUtils.deleteRecursivelyIfExists(path); 124 | } catch (IOException e) { 125 | Logger.getLogger(PathUtils.class.getName()) 126 | .log(Level.WARNING, "Unable to delete " + path, e); 127 | } 128 | })); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /java/build/bazel/gradle/GradleW.java: -------------------------------------------------------------------------------- 1 | 2 | package build.bazel.gradle; 3 | 4 | import build.bazel.gradle.util.TeeOutputStream; 5 | import com.google.common.base.Preconditions; 6 | import com.google.common.collect.ImmutableList; 7 | import java.io.BufferedOutputStream; 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.io.OutputStream; 11 | import java.nio.file.FileVisitResult; 12 | import java.nio.file.Files; 13 | import java.nio.file.Path; 14 | import java.nio.file.PathMatcher; 15 | import java.nio.file.Paths; 16 | import java.nio.file.SimpleFileVisitor; 17 | import java.nio.file.attribute.BasicFileAttributes; 18 | import java.util.ArrayList; 19 | import java.util.Arrays; 20 | import java.util.Iterator; 21 | import java.util.LinkedList; 22 | import java.util.List; 23 | 24 | 25 | class GradleW { 26 | public static void main(String[] args) throws IOException { 27 | System.exit(new GradleW().run(Arrays.asList(args))); 28 | } 29 | private int run(List args) throws IOException { 30 | if (args.isEmpty()) { 31 | System.out.println("usage: java -jar gradlew.jar (options)"); 32 | return 1; 33 | } 34 | Path logFile = null; 35 | File gradleFile = null; 36 | File distribution = null; 37 | LinkedList repos = new LinkedList<>(); 38 | LinkedList tasks = new LinkedList<>(); 39 | LinkedList outputFiles = new LinkedList<>(); 40 | List gradleArgs = new ArrayList<>(); 41 | Iterator it = args.iterator(); 42 | while (it.hasNext()) { 43 | String arg = it.next(); 44 | if (arg.equals("--output") && it.hasNext()) { 45 | String from = it.next(); 46 | if (!it.hasNext()) { 47 | throw new IllegalArgumentException("--output requires two arguments."); 48 | } 49 | String to = it.next(); 50 | outputFiles.add(new OutputFileEntry(from, to)); 51 | } else if (arg.equals("--gradle_file") && it.hasNext()) { 52 | gradleFile = new File(it.next()); 53 | } else if (arg.equals("--distribution") && it.hasNext()) { 54 | distribution = new File(it.next()); 55 | } else if (arg.equals("--repo") && it.hasNext()) { 56 | repos.add(new File(it.next())); 57 | } else if (arg.equals("--task") && it.hasNext()) { 58 | tasks.add(it.next()); 59 | } else if (arg.equals("--log_file") && it.hasNext()) { 60 | logFile = Paths.get(it.next()); 61 | } else if (arg.equals("--max_workers") && it.hasNext()) { 62 | gradleArgs.add("--max-workers"); 63 | gradleArgs.add(it.next()); 64 | } else { 65 | throw new IllegalArgumentException("Unknown argument '" + arg + "'."); 66 | } 67 | } 68 | 69 | File outDir = 70 | gradleFile.getParentFile().toPath().resolve("build").toFile(); 71 | // Files.createDirectories(outDir.toPath()); 72 | 73 | try (Gradle gradle = new Gradle(gradleFile.getParentFile(), outDir, distribution); 74 | OutputStream log = new BufferedOutputStream(Files.newOutputStream(logFile))) { 75 | for (File repo : repos) { 76 | gradle.addRepo(repo); 77 | } 78 | gradleArgs.forEach(gradle::addArgument); 79 | OutputStream out = new TeeOutputStream(System.out, log); 80 | OutputStream err = new TeeOutputStream(System.err, log); 81 | gradle.run(tasks, out, err); 82 | for (OutputFileEntry outputFile : outputFiles) { 83 | outputFile.collect(gradle.getBuildDir().toPath(), gradle.getLocalMavenRepo()); 84 | } 85 | } 86 | return 0; 87 | } 88 | private static class OutputFileEntry { 89 | private enum Type { 90 | OUTPUT_FILE("build/"), 91 | LOCAL_MAVEN_FILE("m2/"); 92 | final String prefix; 93 | Type(String prefix) { 94 | this.prefix = prefix; 95 | } 96 | } 97 | final String from; 98 | final Type type; 99 | final Path to; 100 | OutputFileEntry(String from, String to) { 101 | this.to = Paths.get(to); 102 | for (Type value : Type.values()) { 103 | if (from.contains(value.prefix)) { 104 | this.type = value; 105 | this.from = from; 106 | return; 107 | } 108 | } 109 | throw new RuntimeException("Unknown output entry type for " + from); 110 | } 111 | 112 | void collect(Path outputDir, Path m2Repository) throws IOException { 113 | Path searchDir = getSearchDir(outputDir, m2Repository); 114 | PathMatcher pathMatcher = searchDir.getFileSystem().getPathMatcher("glob:" + from); 115 | PathFinder pathFinder = new PathFinder(searchDir, pathMatcher); 116 | Files.walkFileTree(searchDir, pathFinder); 117 | Preconditions.checkNotNull( 118 | pathFinder.result, "Output file %s not found in %s", from, searchDir); 119 | Files.copy(pathFinder.result, to); 120 | } 121 | 122 | private class PathFinder extends SimpleFileVisitor { 123 | private final Path searchDir; 124 | private final PathMatcher search; 125 | Path result = null; 126 | private PathFinder(Path searchDir, PathMatcher search) { 127 | this.searchDir = searchDir; 128 | this.search = search; 129 | } 130 | @Override 131 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 132 | throws IOException { 133 | if (search.matches(searchDir.relativize(file))) { 134 | if (result != null) { 135 | throw new IOException( 136 | "Multiple matches for " 137 | + from 138 | + " in dir " 139 | + searchDir 140 | + "\n 1. " 141 | + result 142 | + "\n 2. " 143 | + file); 144 | } 145 | result = file; 146 | } 147 | return FileVisitResult.CONTINUE; 148 | } 149 | } 150 | private Path getSearchDir(Path outputDir, Path m2Repository) { 151 | switch (type) { 152 | case OUTPUT_FILE: 153 | return outputDir; 154 | case LOCAL_MAVEN_FILE: 155 | return m2Repository; 156 | } 157 | throw new IllegalStateException("Unknown output entry type " + type); 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /.github/workflows/module.build.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Build" 3 | 4 | "on": 5 | workflow_dispatch: 6 | inputs: 7 | ## Runner to use 8 | runner: 9 | description: "Runner" 10 | type: string 11 | default: "ubuntu-latest" 12 | 13 | ## Whether to build with bzlmod 14 | bzlmod: 15 | description: "Enable Bzlmod" 16 | type: boolean 17 | default: false 18 | 19 | ## Whether to run tests 20 | tests: 21 | description: "Run Tests" 22 | type: boolean 23 | default: true 24 | 25 | ## Whether we should run integration tests (main target) 26 | main: 27 | description: "Main target" 28 | type: boolean 29 | default: false 30 | 31 | ## Whether we should report coverage 32 | coverage: 33 | description: "Coverage" 34 | type: boolean 35 | default: false 36 | 37 | ## Bazel version to use 38 | bazel_version: 39 | description: "Bazel version" 40 | type: string 41 | default: "6.3.2" 42 | 43 | ## Configuration profile to use 44 | bazel_config: 45 | description: "Bazel profile" 46 | type: string 47 | default: "bazel6" 48 | 49 | ## Additional flags to pass to Bazel 50 | flags: 51 | description: "Flags" 52 | type: string 53 | default: "" 54 | 55 | workflow_call: 56 | inputs: 57 | runner: 58 | description: "Runner" 59 | type: string 60 | default: "ubuntu-latest" 61 | label: 62 | description: "Label" 63 | type: string 64 | default: "Ubuntu" 65 | bzlmod: 66 | description: "Enable Bzlmod" 67 | type: boolean 68 | default: false 69 | tests: 70 | description: "Run Tests" 71 | type: boolean 72 | default: true 73 | labs: 74 | description: "Skip Failures" 75 | type: boolean 76 | default: false 77 | bazel_version: 78 | description: "Bazel version" 79 | type: string 80 | default: "6.3.2" 81 | bazel_config: 82 | description: "Bazel profile" 83 | type: string 84 | default: "bazel6" 85 | main: 86 | description: "Main target" 87 | type: boolean 88 | default: false 89 | flags: 90 | description: "Flags" 91 | type: string 92 | default: "" 93 | coverage: 94 | description: "Coverage" 95 | type: boolean 96 | default: false 97 | 98 | secrets: 99 | ## Secrets: BuildBuddy API key 100 | BUILDBUDDY_APIKEY: 101 | required: false 102 | 103 | ## Secrets: Buildless API key 104 | BUILDLESS_APIKEY: 105 | required: false 106 | 107 | ## Secrets: Codecov Reporting Token 108 | CODECOV_TOKEN: 109 | required: false 110 | 111 | env: 112 | BUILDLESS_APIKEY: ${{ secrets.BUILDLESS_APIKEY }} 113 | BUILDBUDDY_APIKEY: ${{ secrets.BUILDBUDDY_APIKEY }} 114 | 115 | jobs: 116 | build: 117 | name: "Build" 118 | runs-on: ${{ inputs.runner || 'ubuntu-latest' }} 119 | continue-on-error: ${{ inputs.labs }} 120 | steps: 121 | - name: Harden Runner 122 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 123 | with: 124 | egress-policy: audit 125 | - name: "Setup: Checkout" 126 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 127 | - name: "Setup: msbuild" 128 | uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1 129 | if: ${{ contains(inputs.runner, 'windows') }} 130 | - name: "Setup: Bazel" 131 | uses: bazelbuild/setup-bazelisk@95c9bf48d0c570bb3e28e57108f3450cd67c1a44 # v2.0.0 132 | - name: "Setup: Cache" 133 | uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 134 | with: 135 | path: "~/.cache/bazel" 136 | key: bazel-v3 137 | - name: "Configure: Bazel Services" 138 | shell: bash 139 | if: contains(env.BUILDLESS_APIKEY || '', 'user_') 140 | run: | 141 | echo "build --remote_header=x-buildbuddy-api-key=${{ secrets.BUILDBUDDY_APIKEY }}" >> local.bazelrc 142 | echo "build --remote_header=x-api-key=${{ secrets.BUILDLESS_APIKEY }}" >> local.bazelrc 143 | - name: "Configure: Bzlmod" 144 | if: inputs.bzlmod 145 | run: | 146 | echo "build --config=bzlmod" >> local.bazelrc 147 | - name: "Build: Project" 148 | continue-on-error: ${{ inputs.labs }} 149 | shell: bash 150 | run: bazel build --config=ci ${{ inputs.flags }} "//e2e/project" 151 | - name: "Testsuite" 152 | continue-on-error: ${{ inputs.labs }} 153 | if: inputs.coverage 154 | shell: bash 155 | run: bazel coverage --config=ci ${{ inputs.flags }} "//tools/..." "//javatests/..." "//.aspect/..." 156 | - name: "Report: Coverage" 157 | uses: codecov/codecov-action@v3 158 | if: inputs.coverage 159 | continue-on-error: true 160 | with: 161 | token: ${{ secrets.CODECOV_TOKEN }} 162 | files: bazel-out/_coverage/_coverage_report.dat 163 | flags: tools 164 | verbose: true 165 | fail_ci_if_error: true # optional (default = false) 166 | 167 | integration-tests: 168 | name: ${{ matrix.label }} 169 | runs-on: ${{ inputs.runner || 'ubuntu-latest' }} 170 | continue-on-error: ${{ inputs.labs || matrix.labs }} 171 | if: inputs.main 172 | strategy: 173 | fail-fast: false 174 | matrix: 175 | label: ["E2E Basic"] 176 | target: ["//e2e/project"] 177 | action: ["build"] 178 | directory: ["."] 179 | labs: [false] 180 | skip: [false] 181 | include: 182 | # Test: E2E Sample 183 | - label: E2E Basic 184 | target: //e2e/project 185 | action: build 186 | directory: "." 187 | labs: false 188 | skip: false 189 | 190 | steps: 191 | - name: Harden Runner 192 | uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 193 | with: 194 | egress-policy: audit 195 | - name: "Setup: Checkout" 196 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 197 | - name: "Setup: msbuild" 198 | uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1 199 | if: ${{ contains(inputs.runner, 'windows') }} 200 | - name: "Setup: Bazel" 201 | uses: bazelbuild/setup-bazelisk@95c9bf48d0c570bb3e28e57108f3450cd67c1a44 # v2.0.0 202 | - name: "Configure: Bazel Version" 203 | shell: bash 204 | if: matrix.skip != true && inputs.bazel_version != '' && inputs.bazel_config != '' 205 | run: | 206 | echo "${{ inputs.bazel_version }}" > .bazelversion 207 | echo "import %workspace%/tools/bazel/${{ inputs.bazel_config }}.bazelrc" > version.bazelrc 208 | - name: "Configure: Bazel Services" 209 | shell: bash 210 | if: contains(env.BUILDLESS_APIKEY || '', 'user_') 211 | run: | 212 | echo "build --remote_header=x-buildbuddy-api-key=${{ secrets.BUILDBUDDY_APIKEY }}" >> local.bazelrc 213 | echo "build --remote_header=x-api-key=${{ secrets.BUILDLESS_APIKEY }}" >> local.bazelrc 214 | - name: "Test: ${{ matrix.label }}" 215 | if: matrix.skip == false 216 | continue-on-error: ${{ inputs.labs }} 217 | working-directory: ${{ matrix.directory }} 218 | shell: bash 219 | run: bazel ${{ matrix.action || 'build' }} "${{ matrix.target || '//...' }}" 220 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit 88 | 89 | # Use the maximum available, or set MAX_FD != -1 to use that value. 90 | MAX_FD=maximum 91 | 92 | warn () { 93 | echo "$*" 94 | } >&2 95 | 96 | die () { 97 | echo 98 | echo "$*" 99 | echo 100 | exit 1 101 | } >&2 102 | 103 | # OS specific support (must be 'true' or 'false'). 104 | cygwin=false 105 | msys=false 106 | darwin=false 107 | nonstop=false 108 | case "$( uname )" in #( 109 | CYGWIN* ) cygwin=true ;; #( 110 | Darwin* ) darwin=true ;; #( 111 | MSYS* | MINGW* ) msys=true ;; #( 112 | NONSTOP* ) nonstop=true ;; 113 | esac 114 | 115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 116 | 117 | 118 | # Determine the Java command to use to start the JVM. 119 | if [ -n "$JAVA_HOME" ] ; then 120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 121 | # IBM's JDK on AIX uses strange locations for the executables 122 | JAVACMD=$JAVA_HOME/jre/sh/java 123 | else 124 | JAVACMD=$JAVA_HOME/bin/java 125 | fi 126 | if [ ! -x "$JAVACMD" ] ; then 127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 128 | 129 | Please set the JAVA_HOME variable in your environment to match the 130 | location of your Java installation." 131 | fi 132 | else 133 | JAVACMD=java 134 | if ! command -v java >/dev/null 2>&1 135 | then 136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | fi 142 | 143 | # Increase the maximum file descriptors if we can. 144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 145 | case $MAX_FD in #( 146 | max*) 147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 148 | # shellcheck disable=SC3045 149 | MAX_FD=$( ulimit -H -n ) || 150 | warn "Could not query maximum file descriptor limit" 151 | esac 152 | case $MAX_FD in #( 153 | '' | soft) :;; #( 154 | *) 155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 156 | # shellcheck disable=SC3045 157 | ulimit -n "$MAX_FD" || 158 | warn "Could not set maximum file descriptor limit to $MAX_FD" 159 | esac 160 | fi 161 | 162 | # Collect all arguments for the java command, stacking in reverse order: 163 | # * args from the command line 164 | # * the main class name 165 | # * -classpath 166 | # * -D...appname settings 167 | # * --module-path (only if needed) 168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 169 | 170 | # For Cygwin or MSYS, switch paths to Windows format before running java 171 | if "$cygwin" || "$msys" ; then 172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 174 | 175 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 176 | 177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 178 | for arg do 179 | if 180 | case $arg in #( 181 | -*) false ;; # don't mess with options #( 182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 183 | [ -e "$t" ] ;; #( 184 | *) false ;; 185 | esac 186 | then 187 | arg=$( cygpath --path --ignore --mixed "$arg" ) 188 | fi 189 | # Roll the args list around exactly as many times as the number of 190 | # args, so each arg winds up back in the position where it started, but 191 | # possibly modified. 192 | # 193 | # NB: a `for` loop captures its iteration list before it begins, so 194 | # changing the positional parameters here affects neither the number of 195 | # iterations, nor the values presented in `arg`. 196 | shift # remove old arg 197 | set -- "$@" "$arg" # push replacement arg 198 | done 199 | fi 200 | 201 | 202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 204 | 205 | # Collect all arguments for the java command; 206 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 207 | # shell script including quotes and variable substitutions, so put them in 208 | # double quotes to make sure that they get re-expanded; and 209 | # * put everything else in single quotes, so that it's not re-expanded. 210 | 211 | set -- \ 212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 213 | -classpath "$CLASSPATH" \ 214 | org.gradle.wrapper.GradleWrapperMain \ 215 | "$@" 216 | 217 | # Stop when "xargs" is not available. 218 | if ! command -v xargs >/dev/null 2>&1 219 | then 220 | die "xargs is not available" 221 | fi 222 | 223 | # Use "xargs" to parse quoted args. 224 | # 225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 226 | # 227 | # In Bash we could simply go: 228 | # 229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 230 | # set -- "${ARGS[@]}" "$@" 231 | # 232 | # but POSIX shell has neither arrays nor command substitution, so instead we 233 | # post-process each arg (as a line of input to sed) to backslash-escape any 234 | # character that might be a shell metacharacter, then use eval to reverse 235 | # that process (while maintaining the separation between arguments), and wrap 236 | # the whole thing up as a single "set" statement. 237 | # 238 | # This will of course break if any of these variables contains a newline or 239 | # an unmatched quote. 240 | # 241 | 242 | eval "set -- $( 243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 244 | xargs -n1 | 245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 246 | tr '\n' ' ' 247 | )" '"$@"' 248 | 249 | exec "$JAVACMD" "$@" 250 | -------------------------------------------------------------------------------- /java/build/bazel/gradle/GradleRunner.java: -------------------------------------------------------------------------------- 1 | 2 | package build.bazel.gradle; 3 | 4 | import build.bazel.gradle.util.TeeOutputStream; 5 | import com.google.common.base.Joiner; 6 | import org.gradle.tooling.GradleConnector; 7 | import org.gradle.tooling.ProgressListener; 8 | import org.gradle.tooling.ProjectConnection; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.slf4j.bridge.SLF4JBridgeHandler; 12 | import picocli.CommandLine; 13 | 14 | import java.io.*; 15 | import java.nio.file.Files; 16 | import java.nio.file.Path; 17 | import java.nio.file.Paths; 18 | import java.util.HashMap; 19 | import java.util.concurrent.Callable; 20 | import java.util.concurrent.atomic.AtomicReference; 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | 25 | 26 | @CommandLine.Command( 27 | name = "gradlew", 28 | version = "bazel-gradle-wrapper 1.0", 29 | mixinStandardHelpOptions = true, 30 | showAtFileInUsageHelp = true, 31 | description = "Wraps an invocation of Gradle from Bazel" 32 | ) 33 | public class GradleRunner implements Callable { 34 | static { System.setProperty("logback.configurationFile", "/java/logback.xml"); } 35 | 36 | public static class MappedOutput { 37 | private final String source; 38 | private final String target; 39 | 40 | private MappedOutput(String source, String target) { 41 | this.source = source; 42 | this.target = target; 43 | } 44 | 45 | static MappedOutput of(String source, String target) { 46 | return new MappedOutput(source, target); 47 | } 48 | 49 | public String getSource() { 50 | return source; 51 | } 52 | 53 | public String getTarget() { 54 | return target; 55 | } 56 | } 57 | 58 | static class OutputFileMapConverter implements CommandLine.ITypeConverter { 59 | @Override 60 | public MappedOutput convert(String subject) { 61 | if (!subject.contains("=")) { 62 | throw new IllegalArgumentException("Cannot map --output without target (separated with `=`)"); 63 | } 64 | String[] portions = subject.split("="); 65 | if (portions.length != 2) { 66 | throw new IllegalArgumentException("Too many `=` in `--output`"); 67 | } 68 | return MappedOutput.of( 69 | portions[0], 70 | portions[1] 71 | ); 72 | } 73 | } 74 | 75 | private static Logger logging = LoggerFactory.getLogger(GradleRunner.class); 76 | 77 | private static AtomicReference> allArgs = new AtomicReference<>(); 78 | 79 | @CommandLine.Option( 80 | names = { "--java_home" }, 81 | required = false, 82 | description = "Java Home to use for the Gradle build; if not provided, defaults to current JVM." 83 | ) 84 | private String javaHome = System.getProperty("java.home"); 85 | 86 | @CommandLine.Option( 87 | names = { "--gradle_distribution" }, 88 | required = true, 89 | description = "Path to a Gradle distribution tarball to use for this build." 90 | ) 91 | private File gradleDistribution; 92 | 93 | @CommandLine.Option( 94 | names = { "--gradle_project" }, 95 | required = true, 96 | description = "Path to the root of the Gradle project." 97 | ) 98 | private Path gradleProject; 99 | 100 | @CommandLine.Option( 101 | names = { "--gradle_build_file" }, 102 | required = true, 103 | description = "Relative path to the specific build file to run; defaults to `build.gradle.kts`." 104 | ) 105 | private String gradleBuildFile = "build.gradle.kts"; 106 | 107 | @CommandLine.Option( 108 | names = { "--logfile" }, 109 | required = true, 110 | description = "Path to the log file to write build output to." 111 | ) 112 | private Path logfilePath; 113 | 114 | @CommandLine.Option( 115 | names = { "--output" }, 116 | arity = "1..N", 117 | required = true, 118 | converter = OutputFileMapConverter.class, 119 | description = "One or more mapped outputs in the form `source=dest`; each source is copied to `dest`." 120 | ) 121 | private List mappedOutputsList; 122 | 123 | @CommandLine.Parameters( 124 | paramLabel = "TASK", 125 | description = "one or more Gradle tasks to run" 126 | ) 127 | List tasks = new ArrayList<>(); 128 | 129 | private static void boot() { 130 | SLF4JBridgeHandler.removeHandlersForRootLogger(); 131 | SLF4JBridgeHandler.install(); 132 | } 133 | 134 | private static File getGradleUserHome(File outDir) { 135 | return new File(outDir, "_home"); 136 | } 137 | 138 | public static Path getLocalMavenRepo(File outDir) { 139 | return outDir.toPath().resolve("_tmp_local_maven"); 140 | } 141 | 142 | private static File getRepoDir(File outDir) { 143 | return new File(outDir, "_repo"); 144 | } 145 | 146 | private static File getInitScript(File outDir) { 147 | return new File(outDir, "init.script"); 148 | } 149 | 150 | public static void addRepo(File outDir, File repo) throws IOException { 151 | Gradle.unzip(repo, getRepoDir(outDir)); 152 | } 153 | 154 | private static void putIfNotNull(HashMap env, String key, String val) { 155 | if (val != null) { 156 | env.put(key, val); 157 | } 158 | } 159 | 160 | private static void createInitScript(File initScript, File repoDir) throws IOException { 161 | String content = 162 | "allprojects {\n" 163 | + " buildscript {\n" 164 | + " repositories {\n" 165 | + " maven { url '" 166 | + repoDir.toURI() 167 | + "'}\n" 168 | + " }\n" 169 | + " }\n" 170 | + " repositories {\n" 171 | + " maven {\n" 172 | + " url '" 173 | + repoDir.toURI() 174 | + "'\n" 175 | + " metadataSources {\n" 176 | + " mavenPom()\n" 177 | + " artifact()\n" 178 | + " }\n" 179 | + " }\n" 180 | + " }\n" 181 | + "}\n" 182 | + "rootProject {\n" 183 | + " task cleanLocalCaches(type: Delete) {\n" 184 | + " delete fileTree(gradle.gradleUserHomeDir.toString() + '/caches/transforms-2') { " 185 | + " exclude '*.lock'\n" 186 | + " }\n" 187 | + " }\n" 188 | + "}\n"; 189 | try (FileWriter writer = new FileWriter(initScript)) { 190 | writer.write(content); 191 | } 192 | } 193 | 194 | public static void main(String[] args) throws IOException { 195 | String[] effective = args; 196 | if (args.length < 1) { 197 | effective = new String[]{"--help"}; 198 | } 199 | 200 | // static init 201 | boot(); 202 | GradleRunner.allArgs.set(Arrays.asList(effective)); 203 | int exitCode = new CommandLine(new GradleRunner()).execute(effective); 204 | System.exit(exitCode); 205 | } 206 | 207 | @Override 208 | public Integer call() throws Exception { 209 | final Path root = gradleProject; 210 | final Path logfile = logfilePath; 211 | final File distribution = gradleDistribution; 212 | List outputs = mappedOutputsList; 213 | List taskList = tasks; 214 | File javaHomeDir = Paths.get(javaHome).toRealPath().toAbsolutePath().toFile(); 215 | 216 | ArrayList taskArgs = new ArrayList<>(taskList.size()); 217 | taskArgs.addAll(taskList); 218 | 219 | if (taskArgs.isEmpty()) { 220 | // run `build` task by default 221 | taskArgs.add("build"); 222 | } 223 | logging.debug("Gradle tool root: " + root); 224 | File base = logfile.toFile().getParentFile(); 225 | File homeDir = getGradleUserHome(base).getAbsoluteFile(); 226 | Path tmpLocalMaven = getLocalMavenRepo(base); 227 | 228 | File repoDir = getRepoDir(base).getAbsoluteFile(); 229 | File initScript = getInitScript(base).getAbsoluteFile(); 230 | createInitScript(initScript, repoDir); 231 | 232 | HashMap env = new HashMap<>(); 233 | List arguments = new ArrayList<>(); 234 | 235 | putIfNotNull(env, "SystemRoot", System.getenv("SystemRoot")); 236 | putIfNotNull(env, "TEMP", System.getenv("TEMP")); 237 | putIfNotNull(env, "TMP", System.getenv("TMP")); 238 | 239 | arguments.add("--offline"); 240 | arguments.add("--init-script"); 241 | arguments.add(initScript.getAbsolutePath()); 242 | arguments.add("-Dmaven.repo.local=" + tmpLocalMaven.toAbsolutePath()); 243 | // Workaround for issue https://github.com/gradle/gradle/issues/5188 244 | System.setProperty("gradle.user.home", ""); 245 | 246 | try { 247 | if (!Files.exists(root) || !Files.isReadable(root)) { 248 | logging.error("Could not find gradle tool root or can't read"); 249 | return 1; 250 | } 251 | 252 | logging.debug( 253 | "All wrapper arguments: " + Joiner.on(" ").join(GradleRunner.allArgs.get()) 254 | ); 255 | 256 | logging.debug( 257 | "Launching Gradle embedded build (tasks: \"" + String.join("\", \"", taskArgs) + "\")" 258 | ); 259 | 260 | try (ProjectConnection connection = GradleConnector.newConnector() 261 | .forProjectDirectory(root.toFile()) 262 | .useDistribution(distribution.toURI()) 263 | .useGradleUserHomeDir(homeDir) 264 | .connect(); OutputStream log = new BufferedOutputStream(Files.newOutputStream(logfile))) { 265 | 266 | OutputStream out = new TeeOutputStream(System.out, log); 267 | OutputStream err = new TeeOutputStream(System.err, log); 268 | 269 | connection.newBuild() 270 | .forTasks(taskArgs.toArray(new String[0])) 271 | .setEnvironmentVariables(env) 272 | .setColorOutput(true) 273 | .setJavaHome(javaHomeDir) 274 | .withArguments(arguments) 275 | .setStandardInput(System.in) 276 | .setStandardOutput(out) 277 | .setStandardError(err) 278 | .addProgressListener((ProgressListener) progressEvent -> 279 | logging.debug("Gradle status: " + progressEvent.getDescription()) 280 | ) 281 | .run(); 282 | 283 | GradleTool.mountOutputs( 284 | root, 285 | logfile, 286 | outputs 287 | ); 288 | } 289 | return 0; 290 | } catch (RuntimeException e) { 291 | logging.error("Could not find Gradle tool root (error)", e); 292 | // print cwd 293 | logging.error("Current working directory: " + System.getProperty("user.dir")); 294 | Files.list(root).forEach(path1 -> logging.error("Path: " + path1)); 295 | return 1; 296 | } 297 | } 298 | } 299 | -------------------------------------------------------------------------------- /java/build/bazel/gradle/Gradle.java: -------------------------------------------------------------------------------- 1 | package build.bazel.gradle; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import java.io.BufferedInputStream; 5 | import java.io.Closeable; 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.FileOutputStream; 9 | import java.io.FileWriter; 10 | import java.io.IOException; 11 | import java.io.OutputStream; 12 | import java.nio.file.*; 13 | import java.nio.file.attribute.BasicFileAttributes; 14 | import java.util.ArrayList; 15 | import java.util.Collections; 16 | import java.util.HashMap; 17 | import java.util.LinkedList; 18 | import java.util.List; 19 | import java.util.zip.ZipEntry; 20 | import java.util.zip.ZipInputStream; 21 | import org.gradle.tooling.BuildLauncher; 22 | import org.gradle.tooling.GradleConnector; 23 | import org.gradle.tooling.ProgressListener; 24 | import org.gradle.tooling.ProjectConnection; 25 | import org.gradle.tooling.internal.consumer.DefaultGradleConnector; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | 30 | /** 31 | * A wrapper to easily call gradle from Java. To use it: 32 | * 33 | *
 34 |  *     // Create the wrapper with the distribution to use the project and where to write stuff.
 35 |  *     Gradle gradle = new Gradle(project_dir, scratch_dir, gradle_distribution);
 36 |  *     // Add local maven repo zips that will be available to the build.
 37 |  *     gradle.addRepo(path_to_zip);
 38 |  *     // Run a task
 39 |  *     gradle.run("assembleDebug");
 40 |  *     // Clean the scratch dir and close the daemon
 41 |  *     gradle.close();
 42 |  * 
43 | */ 44 | public class Gradle implements Closeable { 45 | private static Logger logging = LoggerFactory.getLogger(GradleRunner.class); 46 | private final File outDir; 47 | private final File distribution; 48 | private final File project; 49 | private final List arguments; 50 | 51 | public Gradle(File project, File outDir, File distribution) 52 | throws IOException { 53 | this.project = project; 54 | this.outDir = outDir; 55 | this.distribution = distribution; 56 | this.arguments = new LinkedList<>(); 57 | File initScript = getInitScript().getAbsoluteFile(); 58 | File repoDir = getRepoDir().getAbsoluteFile(); 59 | FileUtils.cleanOutputDir(outDir); 60 | Files.createDirectories(getBuildDir().toPath()); 61 | createInitScript(initScript, repoDir); 62 | } 63 | 64 | public void addRepo(File repo) throws IOException { 65 | unzip(repo, getRepoDir()); 66 | } 67 | 68 | public void addArgument(String argument) { 69 | arguments.add(argument); 70 | } 71 | 72 | public void withProfiler() { 73 | arguments.add("--profile"); 74 | } 75 | 76 | private File getInitScript() { 77 | return new File(outDir, "init.script"); 78 | } 79 | 80 | public void run(String task) { 81 | run(Collections.singletonList(task), System.out, System.err); 82 | } 83 | 84 | public void run(List tasks) { 85 | run(tasks, System.out, System.err); 86 | } 87 | 88 | public void run(List tasks, OutputStream out, OutputStream err) { 89 | File buildDir = getBuildDir().getAbsoluteFile(); 90 | File homeDir = getGradleUserHome().getAbsoluteFile(); 91 | // gradle tries to write into .m2 so we pass it a tmp one. 92 | Path tmpLocalMaven = getLocalMavenRepo(); 93 | HashMap env = new HashMap<>(); 94 | env.put("BUILD_DIR", buildDir.getAbsolutePath()); 95 | // On windows it is needed to set a few more environment variables 96 | // Variable should be set only if not null to avoid exceptions in Gradle such as 97 | // "java.lang.IllegalArgumentException: Cannot encode a null string." 98 | putIfNotNull(env, "SystemRoot", System.getenv("SystemRoot")); 99 | putIfNotNull(env, "TEMP", System.getenv("TEMP")); 100 | putIfNotNull(env, "TMP", System.getenv("TMP")); 101 | List arguments = new ArrayList<>(); 102 | arguments.add("--offline"); 103 | arguments.add("--info"); 104 | arguments.add("--init-script"); 105 | arguments.add(getInitScript().getAbsolutePath()); 106 | arguments.add("-Dmaven.repo.local=" + tmpLocalMaven.toAbsolutePath().toString()); 107 | // Workaround for issue https://github.com/gradle/gradle/issues/5188 108 | System.setProperty("gradle.user.home", ""); 109 | arguments.addAll(this.arguments); 110 | 111 | ProjectConnection projectConnection = getProjectConnection(homeDir, project, distribution); 112 | try { 113 | BuildLauncher launcher = 114 | projectConnection 115 | .newBuild() 116 | .setEnvironmentVariables(env) 117 | .withArguments(arguments) 118 | .setColorOutput(true) 119 | .setStandardInput(System.in) 120 | .setStandardOutput(out) 121 | .setStandardError(err) 122 | .addProgressListener((ProgressListener) progressEvent -> 123 | logging.info("Gradle status: " + progressEvent.getDescription()) 124 | ) 125 | .forTasks(tasks.toArray(new String[0])); 126 | launcher.run(); 127 | } catch (Exception e) { 128 | throw new RuntimeException("Gradle invocation failed: " + this, e); 129 | } finally { 130 | projectConnection.close(); 131 | } 132 | } 133 | 134 | private static void putIfNotNull(HashMap env, String key, String val) { 135 | if (val != null) { 136 | env.put(key, val); 137 | } 138 | } 139 | 140 | @Override 141 | public void close() throws IOException { 142 | // Shut down the daemon so it doesn't hold the lock on any of the files. 143 | // Note that this is internal Gradle API, but is used by Studio and Intellij so is 144 | // relatively stable. 145 | // Because this circumvents the connector we must set gradle.user.home for it to work 146 | System.setProperty("gradle.user.home", getGradleUserHome().getAbsolutePath()); 147 | DefaultGradleConnector.close(); 148 | maybeCopyProfiles(); 149 | try { 150 | FileUtils.cleanOutputDir(outDir); 151 | } catch (Exception e) { 152 | // Allow this to fail, as it will be cleaned up by the next run (b/77804450) 153 | // This is an issue on windows without the sandbox and with stricter file locking 154 | System.err.println( 155 | "Failed to cleanup output directory. Will be cleaned up at next invocation"); 156 | } 157 | } 158 | 159 | private void maybeCopyProfiles() throws IOException { 160 | Path profiles = project.toPath().resolve("build").resolve("reports").resolve("profile"); 161 | if (!Files.isDirectory(profiles)) { 162 | return; 163 | } 164 | Path destination = TestUtils.getTestOutputDir().resolve("gradle_profiles"); 165 | copyDirectory(profiles, destination); 166 | } 167 | 168 | private static void copyDirectory(Path from, Path to) throws IOException { 169 | Files.walkFileTree( 170 | from, 171 | new SimpleFileVisitor() { 172 | @Override 173 | public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) 174 | throws IOException { 175 | Files.createDirectory(to.resolve(from.relativize(dir))); 176 | return FileVisitResult.CONTINUE; 177 | } 178 | @Override 179 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 180 | throws IOException { 181 | Files.copy(file, to.resolve(from.relativize(file))); 182 | return FileVisitResult.CONTINUE; 183 | } 184 | }); 185 | } 186 | 187 | private File getGradleUserHome() { 188 | return new File(outDir, "_home"); 189 | } 190 | 191 | public File getBuildDir() { 192 | return outDir; 193 | } 194 | 195 | public Path getLocalMavenRepo() { 196 | return outDir.toPath().resolve("_tmp_local_maven"); 197 | } 198 | 199 | private File getRepoDir() { 200 | return new File(outDir, "_repo"); 201 | } 202 | 203 | private static void createInitScript(File initScript, File repoDir) throws IOException { 204 | String content = 205 | "allprojects {\n" 206 | + " buildscript {\n" 207 | + " repositories {\n" 208 | + " maven { url '" 209 | + repoDir.toURI().toString() 210 | + "'}\n" 211 | + " }\n" 212 | + " }\n" 213 | + " repositories {\n" 214 | + " maven {\n" 215 | + " url '" 216 | + repoDir.toURI().toString() 217 | + "'\n" 218 | + " metadataSources {\n" 219 | + " mavenPom()\n" 220 | + " artifact()\n" 221 | + " }\n" 222 | + " }\n" 223 | + " }\n" 224 | + "}\n" 225 | + "rootProject {\n" 226 | + " task cleanLocalCaches(type: Delete) {\n" 227 | + " delete fileTree(gradle.gradleUserHomeDir.toString() + '/caches/transforms-2') { " 228 | + " exclude '*.lock'\n" 229 | + " }\n" 230 | + " }\n" 231 | + "}\n"; 232 | try (FileWriter writer = new FileWriter(initScript)) { 233 | writer.write(content); 234 | } 235 | } 236 | 237 | public static void unzip(File zip, File out) throws IOException { 238 | byte[] buffer = new byte[1024]; 239 | try (FileInputStream fis = new FileInputStream(zip); 240 | BufferedInputStream bis = new BufferedInputStream(fis); 241 | ZipInputStream zis = new ZipInputStream(bis)) { 242 | ZipEntry zipEntry = zis.getNextEntry(); 243 | while (zipEntry != null) { 244 | String fileName = zipEntry.getName(); 245 | File newFile = new File(out, fileName); 246 | if (!fileName.endsWith("/")) { 247 | newFile.getParentFile().mkdirs(); 248 | try (FileOutputStream fos = new FileOutputStream(newFile)) { 249 | int len; 250 | while ((len = zis.read(buffer)) > 0) { 251 | fos.write(buffer, 0, len); 252 | } 253 | } 254 | } 255 | zipEntry = zis.getNextEntry(); 256 | } 257 | } 258 | } 259 | 260 | private static ProjectConnection getProjectConnection( 261 | File home, File projectDirectory, File distribution) { 262 | return GradleConnector.newConnector() 263 | .useDistribution(distribution.toURI()) 264 | .useGradleUserHomeDir(home) 265 | .forProjectDirectory(projectDirectory) 266 | .connect(); 267 | } 268 | 269 | @Override 270 | public String toString() { 271 | return MoreObjects.toStringHelper(this) 272 | .add("outDir", outDir) 273 | .add("distribution", distribution) 274 | .add("project", project) 275 | .add("arguments", arguments) 276 | .toString(); 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /WORKSPACE.bazel: -------------------------------------------------------------------------------- 1 | workspace(name = "rules_gradle") 2 | 3 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file") 4 | load( 5 | "//internal:config.bzl", 6 | "GO_VERSION", 7 | "GRAALVM_DISTRIBUTION", 8 | "GRAALVM_JAVA_VERSION", 9 | "GRAALVM_VERSION", 10 | "GRADLE_VERSION", 11 | "GUAVA_VERSION", 12 | "KOTLIN_VERSION", 13 | "LOGBACK_VERSION", 14 | "NODE_VERSION", 15 | "PICOCLI_VERSION", 16 | "PROTOBUF_SHA", 17 | "PROTOBUF_VERSION", 18 | "RULES_JVM_EXTERNAL_SHA", 19 | "RULES_JVM_EXTERNAL_TAG", 20 | "RULES_KOTLIN_SHA", 21 | "RULES_KOTLIN_VERSION", 22 | "SLF4J_VERSION", 23 | ) 24 | 25 | http_archive( 26 | name = "platforms", 27 | sha256 = "3a561c99e7bdbe9173aa653fd579fe849f1d8d67395780ab4770b1f381431d51", 28 | urls = [ 29 | "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.7/platforms-0.0.7.tar.gz", 30 | "https://github.com/bazelbuild/platforms/releases/download/0.0.7/platforms-0.0.7.tar.gz", 31 | ], 32 | ) 33 | 34 | http_archive( 35 | name = "googleapis", 36 | sha256 = "9d1a930e767c93c825398b8f8692eca3fe353b9aaadedfbcf1fca2282c85df88", 37 | strip_prefix = "googleapis-64926d52febbf298cb82a8f472ade4a3969ba922", 38 | urls = [ 39 | "https://github.com/googleapis/googleapis/archive/64926d52febbf298cb82a8f472ade4a3969ba922.zip", 40 | ], 41 | ) 42 | 43 | http_file( 44 | name = "gradle", 45 | sha256 = "591855b517fc635b9e04de1d05d5e76ada3f89f5fc76f87978d1b245b4f69225", 46 | url = "https://dl.less.build/toolchains/gradle/gradle-8.3-bin.zip", 47 | ) 48 | 49 | http_archive( 50 | name = "rules_graalvm", 51 | sha256 = "be69ffbf1e0cdcebce2e7e2491f2c27c61d3cffc106a5ea2f1030cf8297b496e", 52 | strip_prefix = "rules_graalvm-167f5c6a96e67921d8d960bac7461fc94f9960ce", 53 | url = "https://github.com/sgammon/rules_graalvm/archive/167f5c6a96e67921d8d960bac7461fc94f9960ce/rules_graalvm-167f5c6a96e67921d8d960bac7461fc94f9960ce.tar.gz", 54 | ) 55 | 56 | http_archive( 57 | name = "bazel_toolchains", 58 | sha256 = "179ec02f809e86abf56356d8898c8bd74069f1bd7c56044050c2cd3d79d0e024", 59 | strip_prefix = "bazel-toolchains-4.1.0", 60 | urls = [ 61 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/releases/download/4.1.0/bazel-toolchains-4.1.0.tar.gz", 62 | "https://github.com/bazelbuild/bazel-toolchains/releases/download/4.1.0/bazel-toolchains-4.1.0.tar.gz", 63 | ], 64 | ) 65 | 66 | http_archive( 67 | name = "bazel_features", 68 | sha256 = "9fcb3d7cbe908772462aaa52f02b857a225910d30daa3c252f670e3af6d8036d", 69 | strip_prefix = "bazel_features-1.0.0", 70 | url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.0.0/bazel_features-v1.0.0.tar.gz", 71 | ) 72 | 73 | http_archive( 74 | name = "bazel_skylib", 75 | sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa", 76 | urls = [ 77 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz", 78 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz", 79 | ], 80 | ) 81 | 82 | http_archive( 83 | name = "rules_java", 84 | sha256 = "27abf8d2b26f4572ba4112ae8eb4439513615018e03a299f85a8460f6992f6a3", 85 | urls = [ 86 | "https://github.com/bazelbuild/rules_java/releases/download/6.4.0/rules_java-6.4.0.tar.gz", 87 | ], 88 | ) 89 | 90 | http_archive( 91 | name = "rules_cc", 92 | sha256 = "ae46b722a8b8e9b62170f83bfb040cbf12adb732144e689985a66b26410a7d6f", 93 | strip_prefix = "rules_cc-0.0.8", 94 | urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.8/rules_cc-0.0.8.tar.gz"], 95 | ) 96 | 97 | http_archive( 98 | name = "io_bazel_rules_go", 99 | sha256 = "278b7ff5a826f3dc10f04feaf0b70d48b68748ccd512d7f98bf442077f043fe3", 100 | urls = [ 101 | "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.41.0/rules_go-v0.41.0.zip", 102 | "https://github.com/bazelbuild/rules_go/releases/download/v0.41.0/rules_go-v0.41.0.zip", 103 | ], 104 | ) 105 | 106 | http_archive( 107 | name = "gazelle", 108 | sha256 = "727f3e4edd96ea20c29e8c2ca9e8d2af724d8c7778e7923a854b2c80952bc405", 109 | urls = [ 110 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.30.0/bazel-gazelle-v0.30.0.tar.gz", 111 | "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.30.0/bazel-gazelle-v0.30.0.tar.gz", 112 | ], 113 | ) 114 | 115 | http_archive( 116 | name = "rules_kotlin", 117 | sha256 = RULES_KOTLIN_SHA, 118 | strip_prefix = "rules_kotlin-%s" % RULES_KOTLIN_VERSION, 119 | urls = ["https://github.com/bazelbuild/rules_kotlin/archive/%s/%s.tar.gz" % (RULES_KOTLIN_VERSION, RULES_KOTLIN_VERSION)], 120 | ) 121 | 122 | http_archive( 123 | name = "com_google_protobuf", 124 | sha256 = PROTOBUF_SHA, 125 | strip_prefix = "protobuf-%s" % PROTOBUF_VERSION, 126 | urls = ["https://github.com/protocolbuffers/protobuf/archive/v%s.tar.gz" % PROTOBUF_VERSION], 127 | ) 128 | 129 | http_archive( 130 | name = "remote_java_tools", 131 | sha256 = "942b3d88ebd785a5face38049077a1f8dab5a3500f5ebd0c0df090244acc4e16", 132 | urls = [ 133 | "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.5/java_tools-v12.5.zip", 134 | "https://github.com/bazelbuild/java_tools/releases/download/java_v12.5/java_tools-v12.5.zip", 135 | ], 136 | ) 137 | 138 | http_archive( 139 | name = "remote_java_tools_linux", 140 | sha256 = "45dda5441b46385e8ec95d3bc4a04b9337a6ff837bb41bdaa6247d8d36edceae", 141 | urls = [ 142 | "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.5/java_tools_linux-v12.5.zip", 143 | "https://github.com/bazelbuild/java_tools/releases/download/java_v12.5/java_tools_linux-v12.5.zip", 144 | ], 145 | ) 146 | 147 | http_archive( 148 | name = "remote_java_tools_windows", 149 | sha256 = "0b319cf762e256133f8d0f5f99fd7d35ca4cf00f35e7c0e8aea1b9fcd9cf4fb0", 150 | urls = [ 151 | "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.5/java_tools_windows-v12.5.zip", 152 | "https://github.com/bazelbuild/java_tools/releases/download/java_v12.5/java_tools_windows-v12.5.zip", 153 | ], 154 | ) 155 | 156 | http_archive( 157 | name = "remote_java_tools_darwin_x86_64", 158 | sha256 = "7e96d0310222e9c27e4c87987978c0c59a0acb97cebdbd838ff652a13abbed77", 159 | urls = [ 160 | "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.5/java_tools_darwin_x86_64-v12.5.zip", 161 | "https://github.com/bazelbuild/java_tools/releases/download/java_v12.5/java_tools_darwin_x86_64-v12.5.zip", 162 | ], 163 | ) 164 | 165 | http_archive( 166 | name = "remote_java_tools_darwin_arm64", 167 | sha256 = "5fb927b24043dd79010b54be31ec5f18b38ee9dbd9fd03d8353232431a7e2392", 168 | urls = [ 169 | "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.5/java_tools_darwin_arm64-v12.5.zip", 170 | "https://github.com/bazelbuild/java_tools/releases/download/java_v12.5/java_tools_darwin_arm64-v12.5.zip", 171 | ], 172 | ) 173 | 174 | http_archive( 175 | name = "bazel_gazelle", 176 | sha256 = "29218f8e0cebe583643cbf93cae6f971be8a2484cdcfa1e45057658df8d54002", 177 | urls = [ 178 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.32.0/bazel-gazelle-v0.32.0.tar.gz", 179 | "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.32.0/bazel-gazelle-v0.32.0.tar.gz", 180 | ], 181 | ) 182 | 183 | http_archive( 184 | name = "bazel_skylib_gazelle_plugin", 185 | sha256 = "3327005dbc9e49cc39602fb46572525984f7119a9c6ffe5ed69fbe23db7c1560", 186 | urls = [ 187 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-gazelle-plugin-1.4.2.tar.gz", 188 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-gazelle-plugin-1.4.2.tar.gz", 189 | ], 190 | ) 191 | 192 | http_archive( 193 | name = "io_bazel_stardoc", 194 | sha256 = "62bd2e60216b7a6fec3ac79341aa201e0956477e7c8f6ccc286f279ad1d96432", 195 | urls = [ 196 | "https://mirror.bazel.build/github.com/bazelbuild/stardoc/releases/download/0.6.2/stardoc-0.6.2.tar.gz", 197 | "https://github.com/bazelbuild/stardoc/releases/download/0.6.2/stardoc-0.6.2.tar.gz", 198 | ], 199 | ) 200 | 201 | http_archive( 202 | name = "rules_jvm_external", 203 | sha256 = RULES_JVM_EXTERNAL_SHA, 204 | strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG, 205 | url = "https://github.com/bazelbuild/rules_jvm_external/releases/download/%s/rules_jvm_external-%s.tar.gz" % (RULES_JVM_EXTERNAL_TAG, RULES_JVM_EXTERNAL_TAG), 206 | ) 207 | 208 | http_archive( 209 | name = "contrib_rules_jvm", 210 | sha256 = "bd0f82def1879df85ff0a80767e6455911e1c9c1eac5db1de8f68dcccd4a3d7a", 211 | strip_prefix = "rules_jvm-0.18.0", 212 | url = "https://github.com/bazel-contrib/rules_jvm/releases/download/v0.18.0/rules_jvm-v0.18.0.tar.gz", 213 | ) 214 | 215 | http_archive( 216 | name = "aspect_rules_js", 217 | sha256 = "7ab2fbe6d79fb3909ad2bf6dcacfae39adcb31c514efa239dd730b4f147c8097", 218 | strip_prefix = "rules_js-1.32.1", 219 | url = "https://github.com/aspect-build/rules_js/releases/download/v1.32.1/rules_js-v1.32.1.tar.gz", 220 | ) 221 | 222 | # -------------------------------------------------------------------------------------------------------------- 223 | # Dev Dependencies: 224 | 225 | # - Go / Gazelle 226 | 227 | load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") 228 | 229 | go_rules_dependencies() 230 | 231 | go_register_toolchains(version = GO_VERSION) 232 | 233 | load("@googleapis//:repository_rules.bzl", "switched_rules_by_language") 234 | 235 | switched_rules_by_language( 236 | name = "com_google_googleapis_imports", 237 | ) 238 | 239 | load("@gazelle//:deps.bzl", "gazelle_dependencies") 240 | 241 | gazelle_dependencies() 242 | 243 | # - JavaScript 244 | 245 | load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies") 246 | 247 | rules_js_dependencies() 248 | 249 | load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains") 250 | 251 | nodejs_register_toolchains( 252 | name = "nodejs", 253 | node_version = NODE_VERSION, 254 | ) 255 | 256 | load("@aspect_rules_js//npm:repositories.bzl", "npm_translate_lock") 257 | 258 | npm_translate_lock( 259 | name = "npm", 260 | npmrc = "@//:.npmrc", 261 | pnpm_lock = "//:pnpm-lock.yaml", 262 | verify_node_modules_ignored = "//:.bazelignore", 263 | ) 264 | 265 | load("@npm//:repositories.bzl", "npm_repositories") 266 | 267 | npm_repositories() 268 | 269 | # - GraalVM 270 | 271 | load("@rules_graalvm//graalvm:workspace.bzl", "register_graalvm_toolchains", "rules_graalvm_repositories") 272 | 273 | rules_graalvm_repositories() 274 | 275 | register_graalvm_toolchains(register_java_toolchain = False) 276 | 277 | load("@rules_graalvm//graalvm:repositories.bzl", "graalvm_repository") 278 | 279 | graalvm_repository( 280 | name = "graalvm", 281 | distribution = GRAALVM_DISTRIBUTION, 282 | java_version = GRAALVM_JAVA_VERSION, 283 | version = GRAALVM_VERSION, 284 | ) 285 | 286 | # - JVM 287 | 288 | load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains") 289 | 290 | rules_java_dependencies() 291 | 292 | rules_java_toolchains() 293 | 294 | # - Kotlin 295 | 296 | load("@rules_kotlin//kotlin:dependencies.bzl", "kt_download_local_dev_dependencies") 297 | 298 | kt_download_local_dev_dependencies() 299 | 300 | load("@rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories", "kotlinc_version") 301 | 302 | kotlin_repositories( 303 | compiler_release = kotlinc_version( 304 | release = KOTLIN_VERSION, 305 | sha256 = None, 306 | ), 307 | ) 308 | 309 | register_toolchains("//tools/defs/kt:toolchain") 310 | 311 | # - Maven 312 | 313 | load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps") 314 | 315 | rules_jvm_external_deps() 316 | 317 | load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup") 318 | 319 | rules_jvm_external_setup() 320 | 321 | load("@rules_jvm_external//:defs.bzl", "maven_install") 322 | load("@rules_jvm_external//:specs.bzl", "maven") 323 | 324 | maven_install( 325 | artifacts = [ 326 | maven.artifact( 327 | artifact = "gradle-tooling-api", 328 | group = "org.gradle", 329 | version = GRADLE_VERSION, 330 | ), 331 | maven.artifact( 332 | artifact = "slf4j-api", 333 | group = "org.slf4j", 334 | version = SLF4J_VERSION, 335 | ), 336 | maven.artifact( 337 | artifact = "logback-core", 338 | group = "ch.qos.logback", 339 | version = LOGBACK_VERSION, 340 | ), 341 | maven.artifact( 342 | artifact = "logback-classic", 343 | group = "ch.qos.logback", 344 | version = LOGBACK_VERSION, 345 | ), 346 | maven.artifact( 347 | artifact = "jul-to-slf4j", 348 | group = "org.slf4j", 349 | version = "2.0.7", 350 | ), 351 | maven.artifact( 352 | artifact = "kotlin-stdlib", 353 | group = "org.jetbrains.kotlin", 354 | version = KOTLIN_VERSION, 355 | ), 356 | maven.artifact( 357 | artifact = "guava", 358 | group = "com.google.guava", 359 | version = GUAVA_VERSION, 360 | ), 361 | maven.artifact( 362 | artifact = "picocli", 363 | group = "info.picocli", 364 | version = PICOCLI_VERSION, 365 | ), 366 | maven.artifact( 367 | artifact = "picocli-codegen", 368 | group = "info.picocli", 369 | version = PICOCLI_VERSION, 370 | ), 371 | ], 372 | maven_install_json = "@//:maven_install.json", 373 | repositories = [ 374 | "https://maven.pkg.st", 375 | "https://gradle.pkg.st", 376 | "https://repo1.maven.org/maven2", 377 | "https://repo.gradle.org/gradle/libs-releases", 378 | ], 379 | ) 380 | 381 | load("@maven//:defs.bzl", "pinned_maven_install") 382 | 383 | pinned_maven_install() 384 | 385 | # Provide a repository hint for Gazelle to inform it that the go package 386 | # github.com/bazelbuild/rules_go is available from io_bazel_rules_go and it 387 | # doesn't need to duplicatively fetch it. 388 | 389 | # gazelle:repository go_repository name=io_bazel_rules_go importpath=github.com/bazelbuild/rules_go 390 | -------------------------------------------------------------------------------- /maven_install.json: -------------------------------------------------------------------------------- 1 | { 2 | "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", 3 | "__INPUT_ARTIFACTS_HASH": 1859536758, 4 | "__RESOLVED_ARTIFACTS_HASH": -646144578, 5 | "conflict_resolution": { 6 | "org.slf4j:slf4j-api:1.7.10": "org.slf4j:slf4j-api:2.0.7" 7 | }, 8 | "artifacts": { 9 | "ch.qos.logback:logback-classic": { 10 | "shasums": { 11 | "jar": "05850fca185dfa652969ed1e3864e365c0d724737a0f4ec68574baad1d855a0e" 12 | }, 13 | "version": "1.4.11" 14 | }, 15 | "ch.qos.logback:logback-core": { 16 | "shasums": { 17 | "jar": "37ee7367bd24ca87ef77430119a1cb814a76b240afab5c17f802ea383f58aca1" 18 | }, 19 | "version": "1.4.11" 20 | }, 21 | "com.google.code.findbugs:jsr305": { 22 | "shasums": { 23 | "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7" 24 | }, 25 | "version": "3.0.2" 26 | }, 27 | "com.google.errorprone:error_prone_annotations": { 28 | "shasums": { 29 | "jar": "9e6814cb71816988a4fd1b07a993a8f21bb7058d522c162b1de849e19bea54ae" 30 | }, 31 | "version": "2.18.0" 32 | }, 33 | "com.google.guava:failureaccess": { 34 | "shasums": { 35 | "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26" 36 | }, 37 | "version": "1.0.1" 38 | }, 39 | "com.google.guava:guava": { 40 | "shasums": { 41 | "jar": "bc65dea7cfd9e4dacf8419d8af0e741655857d27885bb35d943d7187fc3a8fce" 42 | }, 43 | "version": "32.1.2-jre" 44 | }, 45 | "com.google.guava:listenablefuture": { 46 | "shasums": { 47 | "jar": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99" 48 | }, 49 | "version": "9999.0-empty-to-avoid-conflict-with-guava" 50 | }, 51 | "com.google.j2objc:j2objc-annotations": { 52 | "shasums": { 53 | "jar": "f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed" 54 | }, 55 | "version": "2.8" 56 | }, 57 | "info.picocli:picocli": { 58 | "shasums": { 59 | "jar": "e83a906fb99b57091d1d68ac11f7c3d2518bd7a81a9c71b259e2c00d1564c8e8" 60 | }, 61 | "version": "4.7.5" 62 | }, 63 | "info.picocli:picocli-codegen": { 64 | "shasums": { 65 | "jar": "c1c1b15e3f21ceb2a39146241fcd0f2fe3b5233bf0e34548f6d744edec0df896" 66 | }, 67 | "version": "4.7.5" 68 | }, 69 | "org.checkerframework:checker-qual": { 70 | "shasums": { 71 | "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1" 72 | }, 73 | "version": "3.33.0" 74 | }, 75 | "org.gradle:gradle-tooling-api": { 76 | "shasums": { 77 | "jar": "728a693ad046ff9ab35d2c684000caa74465b3a091a6a60fb329e34796428208" 78 | }, 79 | "version": "8.2.1" 80 | }, 81 | "org.jetbrains.kotlin:kotlin-stdlib": { 82 | "shasums": { 83 | "jar": "4395647b1961d9fb730a34e8dbe56c293157bc0759004cca63d9b5ee6653e5c7" 84 | }, 85 | "version": "1.8.20" 86 | }, 87 | "org.jetbrains.kotlin:kotlin-stdlib-common": { 88 | "shasums": { 89 | "jar": "fa20188abaa8ecf1d0035e93a969b071f10e45a1c8378c314521eade73f75fd5" 90 | }, 91 | "version": "1.8.20" 92 | }, 93 | "org.jetbrains:annotations": { 94 | "shasums": { 95 | "jar": "ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478" 96 | }, 97 | "version": "13.0" 98 | }, 99 | "org.slf4j:jul-to-slf4j": { 100 | "shasums": { 101 | "jar": "eaba65483bb38c93e68d557a19e5738962322de1946545dbf40e5e32f6293008" 102 | }, 103 | "version": "2.0.7" 104 | }, 105 | "org.slf4j:slf4j-api": { 106 | "shasums": { 107 | "jar": "5d6298b93a1905c32cda6478808ac14c2d4a47e91535e53c41f7feeb85d946f4" 108 | }, 109 | "version": "2.0.7" 110 | } 111 | }, 112 | "dependencies": { 113 | "ch.qos.logback:logback-classic": [ 114 | "ch.qos.logback:logback-core", 115 | "org.slf4j:slf4j-api" 116 | ], 117 | "com.google.guava:guava": [ 118 | "com.google.code.findbugs:jsr305", 119 | "com.google.errorprone:error_prone_annotations", 120 | "com.google.guava:failureaccess", 121 | "com.google.guava:listenablefuture", 122 | "com.google.j2objc:j2objc-annotations", 123 | "org.checkerframework:checker-qual" 124 | ], 125 | "info.picocli:picocli-codegen": [ 126 | "info.picocli:picocli" 127 | ], 128 | "org.gradle:gradle-tooling-api": [ 129 | "org.slf4j:slf4j-api" 130 | ], 131 | "org.jetbrains.kotlin:kotlin-stdlib": [ 132 | "org.jetbrains.kotlin:kotlin-stdlib-common", 133 | "org.jetbrains:annotations" 134 | ], 135 | "org.slf4j:jul-to-slf4j": [ 136 | "org.slf4j:slf4j-api" 137 | ] 138 | }, 139 | "packages": { 140 | "ch.qos.logback:logback-classic": [ 141 | "ch.qos.logback.classic", 142 | "ch.qos.logback.classic.boolex", 143 | "ch.qos.logback.classic.encoder", 144 | "ch.qos.logback.classic.filter", 145 | "ch.qos.logback.classic.helpers", 146 | "ch.qos.logback.classic.html", 147 | "ch.qos.logback.classic.joran", 148 | "ch.qos.logback.classic.joran.action", 149 | "ch.qos.logback.classic.joran.sanity", 150 | "ch.qos.logback.classic.joran.serializedModel", 151 | "ch.qos.logback.classic.jul", 152 | "ch.qos.logback.classic.layout", 153 | "ch.qos.logback.classic.log4j", 154 | "ch.qos.logback.classic.model", 155 | "ch.qos.logback.classic.model.processor", 156 | "ch.qos.logback.classic.model.util", 157 | "ch.qos.logback.classic.net", 158 | "ch.qos.logback.classic.net.server", 159 | "ch.qos.logback.classic.pattern", 160 | "ch.qos.logback.classic.pattern.color", 161 | "ch.qos.logback.classic.selector", 162 | "ch.qos.logback.classic.selector.servlet", 163 | "ch.qos.logback.classic.servlet", 164 | "ch.qos.logback.classic.sift", 165 | "ch.qos.logback.classic.spi", 166 | "ch.qos.logback.classic.turbo", 167 | "ch.qos.logback.classic.util" 168 | ], 169 | "ch.qos.logback:logback-core": [ 170 | "ch.qos.logback.core", 171 | "ch.qos.logback.core.boolex", 172 | "ch.qos.logback.core.encoder", 173 | "ch.qos.logback.core.filter", 174 | "ch.qos.logback.core.helpers", 175 | "ch.qos.logback.core.hook", 176 | "ch.qos.logback.core.html", 177 | "ch.qos.logback.core.joran", 178 | "ch.qos.logback.core.joran.action", 179 | "ch.qos.logback.core.joran.conditional", 180 | "ch.qos.logback.core.joran.event", 181 | "ch.qos.logback.core.joran.event.stax", 182 | "ch.qos.logback.core.joran.node", 183 | "ch.qos.logback.core.joran.sanity", 184 | "ch.qos.logback.core.joran.spi", 185 | "ch.qos.logback.core.joran.util", 186 | "ch.qos.logback.core.joran.util.beans", 187 | "ch.qos.logback.core.layout", 188 | "ch.qos.logback.core.model", 189 | "ch.qos.logback.core.model.conditional", 190 | "ch.qos.logback.core.model.processor", 191 | "ch.qos.logback.core.model.processor.conditional", 192 | "ch.qos.logback.core.model.util", 193 | "ch.qos.logback.core.net", 194 | "ch.qos.logback.core.net.server", 195 | "ch.qos.logback.core.net.ssl", 196 | "ch.qos.logback.core.pattern", 197 | "ch.qos.logback.core.pattern.color", 198 | "ch.qos.logback.core.pattern.parser", 199 | "ch.qos.logback.core.pattern.util", 200 | "ch.qos.logback.core.property", 201 | "ch.qos.logback.core.read", 202 | "ch.qos.logback.core.recovery", 203 | "ch.qos.logback.core.rolling", 204 | "ch.qos.logback.core.rolling.helper", 205 | "ch.qos.logback.core.sift", 206 | "ch.qos.logback.core.spi", 207 | "ch.qos.logback.core.status", 208 | "ch.qos.logback.core.subst", 209 | "ch.qos.logback.core.testUtil", 210 | "ch.qos.logback.core.util" 211 | ], 212 | "com.google.code.findbugs:jsr305": [ 213 | "javax.annotation", 214 | "javax.annotation.concurrent", 215 | "javax.annotation.meta" 216 | ], 217 | "com.google.errorprone:error_prone_annotations": [ 218 | "com.google.errorprone.annotations", 219 | "com.google.errorprone.annotations.concurrent" 220 | ], 221 | "com.google.guava:failureaccess": [ 222 | "com.google.common.util.concurrent.internal" 223 | ], 224 | "com.google.guava:guava": [ 225 | "com.google.common.annotations", 226 | "com.google.common.base", 227 | "com.google.common.base.internal", 228 | "com.google.common.cache", 229 | "com.google.common.collect", 230 | "com.google.common.escape", 231 | "com.google.common.eventbus", 232 | "com.google.common.graph", 233 | "com.google.common.hash", 234 | "com.google.common.html", 235 | "com.google.common.io", 236 | "com.google.common.math", 237 | "com.google.common.net", 238 | "com.google.common.primitives", 239 | "com.google.common.reflect", 240 | "com.google.common.util.concurrent", 241 | "com.google.common.xml", 242 | "com.google.thirdparty.publicsuffix" 243 | ], 244 | "com.google.j2objc:j2objc-annotations": [ 245 | "com.google.j2objc.annotations" 246 | ], 247 | "info.picocli:picocli": [ 248 | "picocli" 249 | ], 250 | "info.picocli:picocli-codegen": [ 251 | "picocli.codegen.annotation.processing", 252 | "picocli.codegen.aot.graalvm", 253 | "picocli.codegen.aot.graalvm.processor", 254 | "picocli.codegen.docgen.manpage", 255 | "picocli.codegen.util" 256 | ], 257 | "org.checkerframework:checker-qual": [ 258 | "org.checkerframework.checker.builder.qual", 259 | "org.checkerframework.checker.calledmethods.qual", 260 | "org.checkerframework.checker.compilermsgs.qual", 261 | "org.checkerframework.checker.fenum.qual", 262 | "org.checkerframework.checker.formatter.qual", 263 | "org.checkerframework.checker.guieffect.qual", 264 | "org.checkerframework.checker.i18n.qual", 265 | "org.checkerframework.checker.i18nformatter.qual", 266 | "org.checkerframework.checker.index.qual", 267 | "org.checkerframework.checker.initialization.qual", 268 | "org.checkerframework.checker.interning.qual", 269 | "org.checkerframework.checker.lock.qual", 270 | "org.checkerframework.checker.mustcall.qual", 271 | "org.checkerframework.checker.nullness.qual", 272 | "org.checkerframework.checker.optional.qual", 273 | "org.checkerframework.checker.propkey.qual", 274 | "org.checkerframework.checker.regex.qual", 275 | "org.checkerframework.checker.signature.qual", 276 | "org.checkerframework.checker.signedness.qual", 277 | "org.checkerframework.checker.tainting.qual", 278 | "org.checkerframework.checker.units.qual", 279 | "org.checkerframework.common.aliasing.qual", 280 | "org.checkerframework.common.initializedfields.qual", 281 | "org.checkerframework.common.reflection.qual", 282 | "org.checkerframework.common.returnsreceiver.qual", 283 | "org.checkerframework.common.subtyping.qual", 284 | "org.checkerframework.common.util.report.qual", 285 | "org.checkerframework.common.value.qual", 286 | "org.checkerframework.dataflow.qual", 287 | "org.checkerframework.framework.qual" 288 | ], 289 | "org.gradle:gradle-tooling-api": [ 290 | "org.gradle", 291 | "org.gradle.api", 292 | "org.gradle.api.artifacts.verification", 293 | "org.gradle.api.internal", 294 | "org.gradle.api.internal.classpath", 295 | "org.gradle.api.internal.file", 296 | "org.gradle.api.launcher.cli", 297 | "org.gradle.api.logging", 298 | "org.gradle.api.logging.configuration", 299 | "org.gradle.api.reflect", 300 | "org.gradle.api.specs", 301 | "org.gradle.cache", 302 | "org.gradle.cli", 303 | "org.gradle.concurrent", 304 | "org.gradle.initialization", 305 | "org.gradle.initialization.layout", 306 | "org.gradle.internal", 307 | "org.gradle.internal.agents", 308 | "org.gradle.internal.buildoption", 309 | "org.gradle.internal.classloader", 310 | "org.gradle.internal.classpath", 311 | "org.gradle.internal.concurrent", 312 | "org.gradle.internal.deprecation", 313 | "org.gradle.internal.dispatch", 314 | "org.gradle.internal.event", 315 | "org.gradle.internal.exceptions", 316 | "org.gradle.internal.featurelifecycle", 317 | "org.gradle.internal.impldep.com.google.common.annotations", 318 | "org.gradle.internal.impldep.com.google.common.base", 319 | "org.gradle.internal.impldep.com.google.common.collect", 320 | "org.gradle.internal.impldep.com.google.common.math", 321 | "org.gradle.internal.impldep.com.google.common.primitives", 322 | "org.gradle.internal.impldep.com.google.common.reflect", 323 | "org.gradle.internal.impldep.com.google.common.util.concurrent", 324 | "org.gradle.internal.impldep.com.google.common.util.concurrent.internal", 325 | "org.gradle.internal.impldep.javax.annotation", 326 | "org.gradle.internal.impldep.javax.annotation.concurrent", 327 | "org.gradle.internal.impldep.javax.annotation.meta", 328 | "org.gradle.internal.impldep.javax.inject", 329 | "org.gradle.internal.impldep.org.apache.commons.io", 330 | "org.gradle.internal.impldep.org.apache.commons.lang", 331 | "org.gradle.internal.impldep.org.apache.commons.lang.builder", 332 | "org.gradle.internal.impldep.org.apache.commons.lang.exception", 333 | "org.gradle.internal.impldep.org.apache.commons.lang.math", 334 | "org.gradle.internal.impldep.org.apache.commons.lang.reflect", 335 | "org.gradle.internal.impldep.org.apache.commons.lang.text", 336 | "org.gradle.internal.impldep.org.jetbrains.annotations", 337 | "org.gradle.internal.installation", 338 | "org.gradle.internal.io", 339 | "org.gradle.internal.logging", 340 | "org.gradle.internal.logging.events", 341 | "org.gradle.internal.logging.events.operations", 342 | "org.gradle.internal.logging.progress", 343 | "org.gradle.internal.operations", 344 | "org.gradle.internal.operations.logging", 345 | "org.gradle.internal.reflect", 346 | "org.gradle.internal.scripts", 347 | "org.gradle.internal.service", 348 | "org.gradle.internal.service.scopes", 349 | "org.gradle.internal.time", 350 | "org.gradle.internal.util", 351 | "org.gradle.internal.watch.registry", 352 | "org.gradle.scripts", 353 | "org.gradle.tooling", 354 | "org.gradle.tooling.events", 355 | "org.gradle.tooling.events.configuration", 356 | "org.gradle.tooling.events.configuration.internal", 357 | "org.gradle.tooling.events.download", 358 | "org.gradle.tooling.events.download.internal", 359 | "org.gradle.tooling.events.internal", 360 | "org.gradle.tooling.events.lifecycle", 361 | "org.gradle.tooling.events.lifecycle.internal", 362 | "org.gradle.tooling.events.task", 363 | "org.gradle.tooling.events.task.internal", 364 | "org.gradle.tooling.events.task.internal.java", 365 | "org.gradle.tooling.events.task.java", 366 | "org.gradle.tooling.events.test", 367 | "org.gradle.tooling.events.test.internal", 368 | "org.gradle.tooling.events.transform", 369 | "org.gradle.tooling.events.transform.internal", 370 | "org.gradle.tooling.events.work", 371 | "org.gradle.tooling.events.work.internal", 372 | "org.gradle.tooling.exceptions", 373 | "org.gradle.tooling.internal.adapter", 374 | "org.gradle.tooling.internal.build", 375 | "org.gradle.tooling.internal.consumer", 376 | "org.gradle.tooling.internal.consumer.async", 377 | "org.gradle.tooling.internal.consumer.connection", 378 | "org.gradle.tooling.internal.consumer.converters", 379 | "org.gradle.tooling.internal.consumer.loader", 380 | "org.gradle.tooling.internal.consumer.parameters", 381 | "org.gradle.tooling.internal.consumer.versioning", 382 | "org.gradle.tooling.internal.gradle", 383 | "org.gradle.tooling.internal.protocol", 384 | "org.gradle.tooling.internal.protocol.cpp", 385 | "org.gradle.tooling.internal.protocol.events", 386 | "org.gradle.tooling.internal.protocol.exceptions", 387 | "org.gradle.tooling.internal.protocol.test", 388 | "org.gradle.tooling.model", 389 | "org.gradle.tooling.model.build", 390 | "org.gradle.tooling.model.cpp", 391 | "org.gradle.tooling.model.eclipse", 392 | "org.gradle.tooling.model.gradle", 393 | "org.gradle.tooling.model.idea", 394 | "org.gradle.tooling.model.internal", 395 | "org.gradle.tooling.model.java", 396 | "org.gradle.tooling.model.kotlin.dsl", 397 | "org.gradle.util", 398 | "org.gradle.util.internal", 399 | "org.gradle.wrapper" 400 | ], 401 | "org.jetbrains.kotlin:kotlin-stdlib": [ 402 | "kotlin", 403 | "kotlin.annotation", 404 | "kotlin.collections", 405 | "kotlin.collections.builders", 406 | "kotlin.collections.jdk8", 407 | "kotlin.collections.unsigned", 408 | "kotlin.comparisons", 409 | "kotlin.concurrent", 410 | "kotlin.contracts", 411 | "kotlin.coroutines", 412 | "kotlin.coroutines.cancellation", 413 | "kotlin.coroutines.intrinsics", 414 | "kotlin.coroutines.jvm.internal", 415 | "kotlin.enums", 416 | "kotlin.experimental", 417 | "kotlin.internal", 418 | "kotlin.internal.jdk7", 419 | "kotlin.internal.jdk8", 420 | "kotlin.io", 421 | "kotlin.io.encoding", 422 | "kotlin.io.path", 423 | "kotlin.jdk7", 424 | "kotlin.js", 425 | "kotlin.jvm", 426 | "kotlin.jvm.functions", 427 | "kotlin.jvm.internal", 428 | "kotlin.jvm.internal.markers", 429 | "kotlin.jvm.internal.unsafe", 430 | "kotlin.jvm.jdk8", 431 | "kotlin.jvm.optionals", 432 | "kotlin.math", 433 | "kotlin.properties", 434 | "kotlin.random", 435 | "kotlin.random.jdk8", 436 | "kotlin.ranges", 437 | "kotlin.reflect", 438 | "kotlin.sequences", 439 | "kotlin.streams.jdk8", 440 | "kotlin.system", 441 | "kotlin.text", 442 | "kotlin.text.jdk8", 443 | "kotlin.time", 444 | "kotlin.time.jdk8" 445 | ], 446 | "org.jetbrains:annotations": [ 447 | "org.intellij.lang.annotations", 448 | "org.jetbrains.annotations" 449 | ], 450 | "org.slf4j:jul-to-slf4j": [ 451 | "org.slf4j.bridge" 452 | ], 453 | "org.slf4j:slf4j-api": [ 454 | "org.slf4j", 455 | "org.slf4j.event", 456 | "org.slf4j.helpers", 457 | "org.slf4j.spi" 458 | ] 459 | }, 460 | "repositories": { 461 | "https://maven.pkg.st/": [ 462 | "ch.qos.logback:logback-classic", 463 | "ch.qos.logback:logback-core", 464 | "com.google.code.findbugs:jsr305", 465 | "com.google.errorprone:error_prone_annotations", 466 | "com.google.guava:failureaccess", 467 | "com.google.guava:guava", 468 | "com.google.guava:listenablefuture", 469 | "com.google.j2objc:j2objc-annotations", 470 | "info.picocli:picocli", 471 | "info.picocli:picocli-codegen", 472 | "org.checkerframework:checker-qual", 473 | "org.gradle:gradle-tooling-api", 474 | "org.jetbrains.kotlin:kotlin-stdlib", 475 | "org.jetbrains.kotlin:kotlin-stdlib-common", 476 | "org.jetbrains:annotations", 477 | "org.slf4j:jul-to-slf4j", 478 | "org.slf4j:slf4j-api" 479 | ], 480 | "https://gradle.pkg.st/": [ 481 | "ch.qos.logback:logback-classic", 482 | "ch.qos.logback:logback-core", 483 | "com.google.code.findbugs:jsr305", 484 | "com.google.errorprone:error_prone_annotations", 485 | "com.google.guava:failureaccess", 486 | "com.google.guava:guava", 487 | "com.google.guava:listenablefuture", 488 | "com.google.j2objc:j2objc-annotations", 489 | "info.picocli:picocli", 490 | "info.picocli:picocli-codegen", 491 | "org.checkerframework:checker-qual", 492 | "org.gradle:gradle-tooling-api", 493 | "org.jetbrains.kotlin:kotlin-stdlib", 494 | "org.jetbrains.kotlin:kotlin-stdlib-common", 495 | "org.jetbrains:annotations", 496 | "org.slf4j:jul-to-slf4j", 497 | "org.slf4j:slf4j-api" 498 | ], 499 | "https://repo1.maven.org/maven2/": [ 500 | "ch.qos.logback:logback-classic", 501 | "ch.qos.logback:logback-core", 502 | "com.google.code.findbugs:jsr305", 503 | "com.google.errorprone:error_prone_annotations", 504 | "com.google.guava:failureaccess", 505 | "com.google.guava:guava", 506 | "com.google.guava:listenablefuture", 507 | "com.google.j2objc:j2objc-annotations", 508 | "info.picocli:picocli", 509 | "info.picocli:picocli-codegen", 510 | "org.checkerframework:checker-qual", 511 | "org.gradle:gradle-tooling-api", 512 | "org.jetbrains.kotlin:kotlin-stdlib", 513 | "org.jetbrains.kotlin:kotlin-stdlib-common", 514 | "org.jetbrains:annotations", 515 | "org.slf4j:jul-to-slf4j", 516 | "org.slf4j:slf4j-api" 517 | ], 518 | "https://repo.gradle.org/gradle/libs-releases/": [ 519 | "ch.qos.logback:logback-classic", 520 | "ch.qos.logback:logback-core", 521 | "com.google.code.findbugs:jsr305", 522 | "com.google.errorprone:error_prone_annotations", 523 | "com.google.guava:failureaccess", 524 | "com.google.guava:guava", 525 | "com.google.guava:listenablefuture", 526 | "com.google.j2objc:j2objc-annotations", 527 | "info.picocli:picocli", 528 | "info.picocli:picocli-codegen", 529 | "org.checkerframework:checker-qual", 530 | "org.gradle:gradle-tooling-api", 531 | "org.jetbrains.kotlin:kotlin-stdlib", 532 | "org.jetbrains.kotlin:kotlin-stdlib-common", 533 | "org.jetbrains:annotations", 534 | "org.slf4j:jul-to-slf4j", 535 | "org.slf4j:slf4j-api" 536 | ] 537 | }, 538 | "version": "2" 539 | } 540 | --------------------------------------------------------------------------------