| # protoc-gen-clojure — a protoc/buf plugin that emits Clojure. |
| # |
| # The dependency split here is deliberate and is what makes this module cheap to |
| # consume. Everything needed to RUN the plugin from Bazel is a normal dep; |
| # everything needed to BUILD it from Clojure source is a dev_dependency. |
| # |
| # A consumer uses the prebuilt native binary (see clojure/extensions.bzl), so it |
| # never needs rules_clojure, a JVM toolchain, or GraalVM to generate one .clj |
| # file. That also sidesteps a hard BCR constraint: a published module's non-dev |
| # deps must all resolve from BCR, and rules_clojure currently needs a Bazel 9 |
| # compatibility patch that is still in review upstream (griffinbank#108). As a |
| # dev_dependency it is ignored entirely when this module is consumed, and the |
| # git_override below only applies when this module is the root — exactly the |
| # semantics we want. |
| # |
| # 0.2.0, not 0.1.1: the public load paths moved from //bazel to //clojure, so |
| # every consumer's `load` and `use_extension` lines change. |
| # |
| # No compatibility_level: Bazel 9.2 reports it as a no-op slated for removal |
| # ("The attribute 'compatibility_level' in module() is a no-op"), and this module |
| # is Bazel 9 only, so declaring it buys nothing but a warning. |
| module( |
| name = "protoc_gen_clojure", |
| version = "0.2.0", |
| ) |
| |
| bazel_dep(name = "platforms", version = "1.1.0") |
| bazel_dep(name = "bazel_skylib", version = "1.9.0") |
| |
| # For @protobuf//:protoc, which clojure_proto_library drives, and for the |
| # ProtoInfo provider it reads. Bazel 9 removed ProtoInfo from the Starlark |
| # globals, so it has to come from the module. |
| bazel_dep(name = "protobuf", version = "35.1") |
| |
| # --- build-only, from here down -------------------------------------------- |
| |
| # Stardoc, for the generated API reference in //docs. bazel.build/rules/deploying |
| # asks for exactly this: rules documented with docstrings, rendered automatically, |
| # and the Markdown kept in the repo so it cannot drift. The drift guard is |
| # //docs:update_docs_*_test, wired the same way as the golden files in //test. |
| bazel_dep(name = "stardoc", version = "0.8.1", dev_dependency = True) |
| bazel_dep(name = "rules_java", version = "9.7.1", dev_dependency = True) |
| bazel_dep(name = "rules_jvm_external", version = "7.1", dev_dependency = True) |
| bazel_dep(name = "rules_shell", version = "0.8.0", dev_dependency = True) |
| |
| # Builds the module source archive that BCR serves (//bazel/dev:module_archive). pkg_tar |
| # rather than `tar -czf`: deterministic bytes, and immune to BSD-vs-GNU tar |
| # differences between a local run and CI. |
| bazel_dep(name = "rules_pkg", version = "1.3.0", dev_dependency = True) |
| |
| # The container image for BSR remote plugin execution (//bazel/dev:image). |
| # rules_img rather than a Dockerfile: hermetic, no Docker daemon, and it consumes |
| # the native binary straight from the build graph. |
| # |
| # dev_dependency, together with the pull below — a consumer never builds images, |
| # and a non-dev repo rule referencing a dev-only module would make @rules_img |
| # invisible to them and break module resolution outright. |
| bazel_dep(name = "rules_img", version = "0.3.19", dev_dependency = True) |
| |
| pull = use_repo_rule("@rules_img//img:pull.bzl", "pull") |
| |
| # base-debian12, not static-debian12: GraalVM's Linux output is dynamically linked, |
| # so the image needs glibc. `static` has none, which is what made the old |
| # `FROM scratch` Dockerfile unable to start the plugin at all. |
| # |
| # Pinned by digest because a tag is mutable; `latest` here only records where the |
| # digest came from. |
| pull( |
| name = "distroless_base", |
| dev_dependency = True, |
| digest = "sha256:62730825d3cf03571e0a1b8f014748de94d0404500f063593b614c23da38841d", |
| registry = "gcr.io", |
| repository = "distroless/base-debian12", |
| tag = "latest", |
| ) |
| |
| # write_source_files: the golden-file pattern as a rule. Replaces a hand-rolled |
| # pair of scripts that did the same diff-and-update dance, including my own |
| # guards against a vacuously passing comparison. |
| bazel_dep(name = "aspect_bazel_lib", version = "2.22.5", dev_dependency = True) |
| |
| # Hermetic buf for the distribution test, so CI needs no buf-setup-action and the |
| # version cannot drift from what we claim to support. Pinned for the same reason |
| # clj-grpc pins it: buf older than ~1.60 rejects edition 2024 outright with |
| # 'edition value "2024" not recognized'. |
| bazel_dep(name = "rules_buf", version = "0.5.4", dev_dependency = True) |
| |
| # Lint, wired as ordinary Bazel tests (see bazel/lint/linters.bzl), so CI needs no |
| # separate lint job and `bazel test //...` covers protos and shell. |
| # Version matches nubank/park, which already runs this setup. |
| bazel_dep(name = "aspect_rules_lint", version = "2.7.2", dev_dependency = True) |
| |
| # buildifier, for Starlark. Reachable through the FORMAT path (//bazel/dev:format, |
| # //bazel/dev:format_test) but not through a lint_test: the lint aspect looks for the |
| # binary in runfiles, where the buildifier_prebuilt extension's repos are not |
| # visible. nubank/park does the same — it wires buildifier into format only. |
| bazel_dep(name = "buildifier_prebuilt", version = "8.5.1.3", dev_dependency = True) |
| |
| buf = use_extension("@rules_buf//buf:extensions.bzl", "buf", dev_dependency = True) |
| buf.toolchains(version = "v1.72.0") |
| use_repo(buf, "rules_buf_toolchains") |
| |
| # GraalVM, for the SDK ONLY — deliberately not for its native_image rule. |
| # |
| # The distinction is the whole point. Fetching a pinned GraalVM through |
| # rules_graalvm is exactly what we want: hermetic, version-pinned, and it drops |
| # graalvm/setup-graalvm (and its GitHub token) from CI. Its native_image RULE is |
| # what cannot be used: on macOS it routes through apple_support.run, which puts |
| # SDKROOT in the action env, and Bazel's XcodeLocalEnvProvider then injects |
| # SDKROOT again — "Multiple entries with same key: SDKROOT", which crashes Bazel |
| # outright. So //bazel:native_image.bzl invokes @graalvm//:native-image itself. |
| # |
| # No register_toolchains here on purpose: we want the SDK on disk, not GraalVM |
| # substituted as the build's Java toolchain. |
| # |
| # BCR's newest rules_graalvm is 0.11.1 (January 2024) and fails on Bazel 9 with |
| # "name 'JavaInfo' is not defined", hence the override. It is dev-only, so it |
| # never reaches a consumer or blocks BCR publication. |
| bazel_dep(name = "rules_graalvm", version = "0.12.0", dev_dependency = True) |
| git_override( |
| module_name = "rules_graalvm", |
| remote = "https://github.com/sgammon/rules_graalvm.git", |
| tag = "v0.12.0", |
| ) |
| |
| graalvm = use_extension("@rules_graalvm//:extensions.bzl", "graalvm", dev_dependency = True) |
| graalvm.graalvm( |
| name = "graalvm", |
| distribution = "ce", |
| java_version = "21", |
| version = "21.0.2", |
| ) |
| use_repo(graalvm, "graalvm") |
| |
| # The Bazel 9 compatibility patches live on a personal fork pending |
| # griffinbank/rules_clojure#108. git_override is honoured only in the root |
| # module, which is precisely why rules_clojure must be a dev_dependency. |
| bazel_dep(name = "rules_clojure", version = "0.5", dev_dependency = True) |
| git_override( |
| module_name = "rules_clojure", |
| branch = "bazel-9-compat", |
| remote = "https://github.com/bpalermo/rules_clojure.git", |
| ) |
| |
| maven = use_extension( |
| "@rules_jvm_external//:extensions.bzl", |
| "maven", |
| dev_dependency = True, |
| ) |
| maven.install( |
| name = "maven", |
| artifacts = [ |
| "org.clojure:clojure:1.12.0", |
| # The plugin's entire runtime surface: parse a CodeGeneratorRequest, |
| # probe editions, write a CodeGeneratorResponse. Edition 2024 gencode |
| # needs the 4.x runtime. |
| "com.google.protobuf:protobuf-java:4.35.1", |
| ], |
| known_contributing_modules = ["protobuf"], |
| ) |
| |
| # clojure -> spec.alpha -> clojure is a real cycle in the Maven metadata and |
| # Bazel's analysis phase rejects it. Cutting the back-edge resolves it; clojure |
| # itself is pinned above, so nothing leaves the classpath. |
| maven.artifact( |
| name = "maven", |
| artifact = "spec.alpha", |
| exclusions = ["org.clojure:clojure"], |
| group = "org.clojure", |
| version = "0.5.238", |
| ) |
| maven.artifact( |
| name = "maven", |
| artifact = "core.specs.alpha", |
| exclusions = ["org.clojure:clojure"], |
| group = "org.clojure", |
| version = "0.4.74", |
| ) |
| use_repo(maven, "maven") |