refactor: examples folder standalone (#25)
diff --git a/.bazelignore b/.bazelignore index 2559413..7bd5d5c 100644 --- a/.bazelignore +++ b/.bazelignore
@@ -1 +1,2 @@ -e2e/ \ No newline at end of file +e2e/ +examples/
diff --git a/.bazelrc b/.bazelrc index 3c13c42..2d791cb 100644 --- a/.bazelrc +++ b/.bazelrc
@@ -2,21 +2,6 @@ # Take care to document any settings that you expect users to apply. # Settings that apply only to CI are in .github/workflows/ci.bazelrc -# The main ingredient: allow us to register toolchains other than com_google_protobuf targets -common --incompatible_enable_proto_toolchain_resolution -common --@aspect_rules_py//py:interpreter_version=3.9.18 - -# See https://github.com/bazelbuild/rules_python/issues/1069#issuecomment-1942053014 -common --action_env=RULES_PYTHON_ENABLE_PYSTAR=0 - -# Don’t want to push a rules author to update their deps if not needed. -# https://bazel.build/reference/command-line-reference#flag--check_direct_dependencies -# https://bazelbuild.slack.com/archives/C014RARENH0/p1691158021917459?thread_ts=1691156601.420349&cid=C014RARENH0 -common --check_direct_dependencies=off - -# Force rules_go to disable CGO even though we have a (fake) C++ toolchain registered. -common --host_platform=//:no_cgo_host_platform - # Load any settings specific to the current user. # .bazelrc.user should appear in .gitignore so that settings are not shared with team members # This needs to be last statement in this
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2d15f9e..e21346c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml
@@ -20,10 +20,11 @@ test: uses: bazel-contrib/.github/.github/workflows/bazel.yaml@v6 with: - folders: '[".", "e2e/smoke"]' + folders: '[".", "e2e/smoke", "examples"]' exclude: | [ {"bazelversion": "6.4.0"}, {"folder": ".", "bzlmodEnabled": false}, + {"folder": "examples", "bzlmodEnabled": false}, {"folder": ".", "os": "windows-latest"} ]
diff --git a/.github/workflows/release_prep.sh b/.github/workflows/release_prep.sh index e931644..be6752e 100755 --- a/.github/workflows/release_prep.sh +++ b/.github/workflows/release_prep.sh
@@ -16,9 +16,9 @@ SHA=$(shasum -a 256 $ARCHIVE | awk '{print $1}') cat << EOF -## Using Bzlmod with Bazel 6 +## Using Bzlmod with Bazel 6 or later -1. Enable with \`common --enable_bzlmod\` in \`.bazelrc\`. +1. (Bazel 6 only) Enable with \`common --enable_bzlmod\` in \`.bazelrc\`. 2. Add to your \`MODULE.bazel\` file: \`\`\`starlark @@ -33,6 +33,9 @@ # Pin to any version of protoc version = "v26.0", ) +use_repo(protoc, "com_google_protobuf", "toolchains_protoc_hub") + +register_toolchains("@toolchains_protoc_hub//:all") \`\`\` ## Using WORKSPACE
diff --git a/BUILD.bazel b/BUILD.bazel index 60d5013..8400706 100644 --- a/BUILD.bazel +++ b/BUILD.bazel
@@ -1,8 +1,7 @@ -load("@platforms//host:constraints.bzl", "HOST_CONSTRAINTS") +load("@bazel_skylib//rules:build_test.bzl", "build_test") -platform( - name = "no_cgo_host_platform", - constraint_values = HOST_CONSTRAINTS + [ - "@rules_go//go/toolchain:cgo_off", - ], +# Placeholder until there are docs tests +build_test( + name = "tautology", + targets = ["//:BUILD.bazel"], )
diff --git a/MODULE.bazel b/MODULE.bazel index e65604e..940b2fb 100644 --- a/MODULE.bazel +++ b/MODULE.bazel
@@ -11,43 +11,13 @@ bazel_dep(name = "rules_proto", version = "6.0.0") bazel_dep(name = "platforms", version = "0.0.10") -protoc = use_extension("//protoc:extensions.bzl", "protoc") +bazel_dep(name = "aspect_bazel_lib", version = "2.8.1", dev_dependency = True) +bazel_dep(name = "buildifier_prebuilt", version = "6.1.2", dev_dependency = True) + +protoc = use_extension("@toolchains_protoc//protoc:extensions.bzl", "protoc") protoc.toolchain( - google_protobuf = "com_google_protobuf", version = "v27.3", ) -use_repo(protoc, "com_google_protobuf", "toolchains_protoc_hub") +use_repo(protoc, "toolchains_protoc_hub") register_toolchains("@toolchains_protoc_hub//:all") - -# Assert no CC compilation occurs -register_toolchains( - "//tools/toolchains:all", - dev_dependency = True, -) - -bazel_dep(name = "aspect_bazel_lib", version = "1.32.1", dev_dependency = True) -bazel_dep(name = "buildifier_prebuilt", version = "6.1.2", dev_dependency = True) -bazel_dep(name = "aspect_rules_py", version = "0.7.1", dev_dependency = True) -bazel_dep(name = "rules_java", version = "7.4.0", dev_dependency = True) -bazel_dep(name = "rules_python", version = "0.32.2", dev_dependency = True) -bazel_dep(name = "rules_go", version = "0.48.0", dev_dependency = True) -bazel_dep(name = "rules_uv", version = "0.10.0", dev_dependency = True) - -register_toolchains( - "//examples/lang_toolchains:all", - dev_dependency = True, -) - -# Shows how a typical Python user fetches all the dependencies of their app, including the protobuf runtime -dev_pip = use_extension( - "@rules_python//python/extensions:pip.bzl", - "pip", - dev_dependency = True, -) -dev_pip.parse( - hub_name = "pypi", - python_version = "3.11", - requirements_lock = "//examples/lang_toolchains:requirements.txt", -) -use_repo(dev_pip, "pypi")
diff --git a/README.md b/README.md index e4deb90..c6be85c 100644 --- a/README.md +++ b/README.md
@@ -9,7 +9,7 @@ - Nearly every Bazel user has waited for `protoc` to compile from sources many, MANY times. This universally slows down builds, especially due to issues like https://github.com/bazelbuild/bazel/issues/7095 where it is observed to be easily cache-busted. - The protobuf Bazel module is quite complex and maintenance and support from the protobuf team has been inconsistent. - By using pre-built artifacts, Bazel users can follow the same well-tested as users of other build systems. + By using pre-built artifacts, Bazel users can follow the same well-tested codepaths as users of other build systems. - Relying on the protobuf runtime for each language from the `@com_google_protobuf` repo forces you to use the same version of the runtime for all languages in a monorepo, and matching protoc. This makes it difficult to migrate to a monorepo, allowing some applications to move from their separate repo without
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index 1633df2..53b52af 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel
@@ -1,11 +1 @@ # Marker that this is the root of a Bazel workspace. - -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") - -# Note: this is simpler than using rules_jvm_external with a maven installation, -# but users would probably get this JAR file that way. -http_jar( - name = "protobuf-java", - sha256 = "0532ad1024d62361561acaedb974d7d16889e7670b36e23e9321dd6b9d334ef9", - urls = ["https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/4.27.0-RC3/protobuf-java-4.27.0-RC3.jar"], -)
diff --git a/examples/.bazelrc b/examples/.bazelrc new file mode 100644 index 0000000..7e8772b --- /dev/null +++ b/examples/.bazelrc
@@ -0,0 +1,9 @@ +# The main ingredient: allow us to register toolchains other than com_google_protobuf targets +common --incompatible_enable_proto_toolchain_resolution +common --@aspect_rules_py//py:interpreter_version=3.9.18 + +# See https://github.com/bazelbuild/rules_python/issues/1069#issuecomment-1942053014 +common --action_env=RULES_PYTHON_ENABLE_PYSTAR=0 + +# Force rules_go to disable CGO even though we have a (fake) C++ toolchain registered. +common --host_platform=//tools:no_cgo_host_platform
diff --git a/examples/.bazelversion b/examples/.bazelversion new file mode 100644 index 0000000..1502020 --- /dev/null +++ b/examples/.bazelversion
@@ -0,0 +1 @@ +7.3.0
diff --git a/examples/BUILD b/examples/BUILD.bazel similarity index 100% rename from examples/BUILD rename to examples/BUILD.bazel
diff --git a/examples/MODULE.bazel b/examples/MODULE.bazel new file mode 100644 index 0000000..8ce28f5 --- /dev/null +++ b/examples/MODULE.bazel
@@ -0,0 +1,58 @@ +bazel_dep(name = "toolchains_protoc", version = "0.0.0") +bazel_dep(name = "aspect_bazel_lib", version = "2.8.1") +bazel_dep(name = "aspect_rules_py", version = "0.7.1") +bazel_dep(name = "rules_java", version = "7.6.5") +bazel_dep(name = "rules_proto", version = "6.0.0") +bazel_dep(name = "rules_python", version = "0.32.2") +bazel_dep(name = "rules_go", version = "0.48.0") +bazel_dep(name = "rules_uv", version = "0.10.0") + +# This example is in the same repo with the ruleset, so we should point to the code at HEAD +# rather than use any release on the Bazel Central Registry. +local_path_override( + module_name = "toolchains_protoc", + path = "..", +) + +####### PROTOBUF ########## +protoc = use_extension("@toolchains_protoc//protoc:extensions.bzl", "protoc") +protoc.toolchain( + google_protobuf = "com_google_protobuf", + # Demonstrate overriding the default version + version = "v28.0", +) +use_repo(protoc, "com_google_protobuf", "toolchains_protoc_hub") + +register_toolchains("@toolchains_protoc_hub//:all") + +register_toolchains("//tools/toolchains:all") + +####### PYTHON ########## +# Shows how a typical Python user fetches all the dependencies of their app, including the protobuf runtime +dev_pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") +dev_pip.parse( + hub_name = "pypi", + python_version = "3.11", + requirements_lock = "//tools:requirements.txt", +) +use_repo(dev_pip, "pypi") + +####### JAVA ########## +# Note: this is simpler than using rules_jvm_external with a maven installation, +# however it can cause version skew on the classpath if Coursier resolves a different version +# from the constraint solution. +# Users with a maven.install should instead do something like +# maven.install( +# artifacts = [ +# "com.google.protobuf:protobuf-java:4.27.1", +# "io.grpc:grpc-all:1.51.1", +# ], +# lock_file = "//:maven_install.json", +# ) +http_jar = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") + +http_jar( + name = "protobuf-java", + sha256 = "0532ad1024d62361561acaedb974d7d16889e7670b36e23e9321dd6b9d334ef9", + urls = ["https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/4.27.0-RC3/protobuf-java-4.27.0-RC3.jar"], +)
diff --git a/examples/WORKSPACE.bazel b/examples/WORKSPACE.bazel new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/examples/WORKSPACE.bazel
diff --git a/examples/go/BUILD b/examples/go/BUILD index 5777ee9..db2b107 100644 --- a/examples/go/BUILD +++ b/examples/go/BUILD
@@ -3,5 +3,5 @@ go_test( name = "foo_proto_test", srcs = ["foo_proto_test.go"], - deps = ["//examples:foo_go_proto"], + deps = ["//:foo_go_proto"], )
diff --git a/examples/java/BUILD b/examples/java/BUILD index 43adca8..fe35ad5 100644 --- a/examples/java/BUILD +++ b/examples/java/BUILD
@@ -3,7 +3,7 @@ srcs = ["Main.java"], main_class = "Main", deps = [ - "//examples:foo_java_proto", + "//:foo_java_proto", "@protobuf-java//jar", ], )
diff --git a/examples/lang_toolchains/BUILD b/examples/lang_toolchains/BUILD deleted file mode 100644 index d72db69..0000000 --- a/examples/lang_toolchains/BUILD +++ /dev/null
@@ -1,25 +0,0 @@ -load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain") -load("@rules_uv//uv:pip.bzl", "pip_compile") - -pip_compile( - name = "generate_requirements_txt", - requirements_in = "requirements.in", - requirements_txt = "requirements.txt", -) - -# Configure protoc to have the right arguments for generating Python stubs. -proto_lang_toolchain( - name = "protoc_py_toolchain", - command_line = "--python_out=%s", - progress_message = "Generating Python proto_library %{label}", - runtime = "@pypi//protobuf", - toolchain_type = "@rules_python//python/proto:toolchain_type", -) - -proto_lang_toolchain( - name = "protoc_java_toolchain", - command_line = "--java_out=%s", - progress_message = "Generating Java proto_library %{label}", - runtime = "@protobuf-java//jar", - toolchain_type = "@rules_java//java/proto:toolchain_type", -)
diff --git a/examples/lang_toolchains/requirements.in b/examples/lang_toolchains/requirements.in deleted file mode 100644 index ec5c8b1..0000000 --- a/examples/lang_toolchains/requirements.in +++ /dev/null
@@ -1 +0,0 @@ -protobuf==5.27.3
diff --git a/examples/lang_toolchains/requirements.txt b/examples/lang_toolchains/requirements.txt deleted file mode 100644 index a7ba71e..0000000 --- a/examples/lang_toolchains/requirements.txt +++ /dev/null
@@ -1,17 +0,0 @@ -# This file was autogenerated by uv via the following command: -# bazel run @@//examples/lang_toolchains:generate_requirements_txt ---index-url https://pypi.org/simple - -protobuf==5.27.3 \ - --hash=sha256:043853dcb55cc262bf2e116215ad43fa0859caab79bb0b2d31b708f128ece035 \ - --hash=sha256:16ddf3f8c6c41e1e803da7abea17b1793a97ef079a912e42351eabb19b2cffe7 \ - --hash=sha256:68248c60d53f6168f565a8c76dc58ba4fa2ade31c2d1ebdae6d80f969cdc2d4f \ - --hash=sha256:82460903e640f2b7e34ee81a947fdaad89de796d324bcbc38ff5430bcdead82c \ - --hash=sha256:8572c6533e544ebf6899c360e91d6bcbbee2549251643d32c52cf8a5de295ba5 \ - --hash=sha256:a55c48f2a2092d8e213bd143474df33a6ae751b781dd1d1f4d953c128a415b25 \ - --hash=sha256:af7c0b7cfbbb649ad26132e53faa348580f844d9ca46fd3ec7ca48a1ea5db8a1 \ - --hash=sha256:b8a994fb3d1c11156e7d1e427186662b64694a62b55936b2b9348f0a7c6625ce \ - --hash=sha256:c2a105c24f08b1e53d6c7ffe69cb09d0031512f0b72f812dd4005b8112dbe91e \ - --hash=sha256:c84eee2c71ed83704f1afbf1a85c3171eab0fd1ade3b399b3fad0884cbcca8bf \ - --hash=sha256:dcb307cd4ef8fec0cf52cb9105a03d06fbb5275ce6d84a6ae33bc6cf84e0a07b - # via -r examples/lang_toolchains/requirements.in
diff --git a/examples/python/BUILD b/examples/python/BUILD index 89d9d95..a55aab0 100644 --- a/examples/python/BUILD +++ b/examples/python/BUILD
@@ -1,5 +1,5 @@ py_test( name = "message_test", srcs = ["message_test.py"], - deps = ["//examples:foo_py_proto"], + deps = ["//:foo_py_proto"], )
diff --git a/examples/python/message_test.py b/examples/python/message_test.py index 431efa2..0ea0782 100644 --- a/examples/python/message_test.py +++ b/examples/python/message_test.py
@@ -1,7 +1,7 @@ import sys import unittest -from examples import foo_pb2 +from _main import foo_pb2 class TestCase(unittest.TestCase): def test_message(self):
diff --git a/examples/tools/BUILD.bazel b/examples/tools/BUILD.bazel new file mode 100644 index 0000000..2a4a2f4 --- /dev/null +++ b/examples/tools/BUILD.bazel
@@ -0,0 +1,18 @@ +load("@platforms//host:constraints.bzl", "HOST_CONSTRAINTS") +load("@rules_uv//uv:pip.bzl", "pip_compile") + +pip_compile( + name = "generate_requirements_txt", + requirements_in = "requirements.in", + requirements_txt = "requirements.txt", +) + +# Don't allow rules_go to compile the Go SDK with cgo enabled, as that +# would cause a dependency on a functional C++ toolchain. +# This value is referenced in the .bazelrc +platform( + name = "no_cgo_host_platform", + constraint_values = HOST_CONSTRAINTS + [ + "@rules_go//go/toolchain:cgo_off", + ], +)
diff --git a/examples/tools/requirements.in b/examples/tools/requirements.in new file mode 100644 index 0000000..07c7637 --- /dev/null +++ b/examples/tools/requirements.in
@@ -0,0 +1 @@ +protobuf==5.28.0
diff --git a/examples/tools/requirements.txt b/examples/tools/requirements.txt new file mode 100644 index 0000000..acd4713 --- /dev/null +++ b/examples/tools/requirements.txt
@@ -0,0 +1,17 @@ +# This file was autogenerated by uv via the following command: +# bazel run @@//tools:generate_requirements_txt +--index-url https://pypi.org/simple + +protobuf==5.28.0 \ + --hash=sha256:018db9056b9d75eb93d12a9d35120f97a84d9a919bcab11ed56ad2d399d6e8dd \ + --hash=sha256:510ed78cd0980f6d3218099e874714cdf0d8a95582e7b059b06cabad855ed0a0 \ + --hash=sha256:532627e8fdd825cf8767a2d2b94d77e874d5ddb0adefb04b237f7cc296748681 \ + --hash=sha256:6206afcb2d90181ae8722798dcb56dc76675ab67458ac24c0dd7d75d632ac9bd \ + --hash=sha256:66c3edeedb774a3508ae70d87b3a19786445fe9a068dd3585e0cefa8a77b83d0 \ + --hash=sha256:6d7cc9e60f976cf3e873acb9a40fed04afb5d224608ed5c1a105db4a3f09c5b6 \ + --hash=sha256:853db610214e77ee817ecf0514e0d1d052dff7f63a0c157aa6eabae98db8a8de \ + --hash=sha256:d001a73c8bc2bf5b5c1360d59dd7573744e163b3607fa92788b7f3d5fefbd9a5 \ + --hash=sha256:dde74af0fa774fa98892209992295adbfb91da3fa98c8f67a88afe8f5a349add \ + --hash=sha256:dde9fcaa24e7a9654f4baf2a55250b13a5ea701493d904c54069776b99a8216b \ + --hash=sha256:eef7a8a2f4318e2cb2dee8666d26e58eaf437c14788f3a2911d0c3da40405ae8 + # via -r tools/requirements.in
diff --git a/examples/tools/toolchains/BUILD.bazel b/examples/tools/toolchains/BUILD.bazel new file mode 100644 index 0000000..1febe31 --- /dev/null +++ b/examples/tools/toolchains/BUILD.bazel
@@ -0,0 +1,55 @@ +"""Define a non-functional cc toolchain. + +To fail-fast in cases where we are forced to compile third-party C++ code, +define a cc toolchain that doesn't work, by using 'false' as the compiler. +See https://bazel.build/tutorials/ccp-toolchain-config +""" + +load("defs.bzl", "cc_toolchain_config") +load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain") + +# Configure protoc to have the right arguments for generating Python stubs. +# NB: the protobuf team intends to remove --python_out and instead use a protoc plugin for Python stub emit. +proto_lang_toolchain( + name = "protoc_py_toolchain", + command_line = "--python_out=%s", + progress_message = "Generating Python proto_library %{label}", + runtime = "@pypi//protobuf", + toolchain_type = "@rules_python//python/proto:toolchain_type", +) + +# Same as above, but for Java +proto_lang_toolchain( + name = "protoc_java_toolchain", + command_line = "--java_out=%s", + progress_message = "Generating Java proto_library %{label}", + runtime = "@protobuf-java//jar", + toolchain_type = "@rules_java//java/proto:toolchain_type", +) + +################ +# Setup a non-functional C++ toolchain, so we're assured that no C++ compilation +# will be expected for engineers working in our repo. +# That's the critical guarantee of toolchains_protoc +filegroup(name = "empty") + +cc_toolchain_config(name = "noop_toolchain_config") + +cc_toolchain( + name = "noop_toolchain", + all_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 0, + toolchain_config = ":noop_toolchain_config", + toolchain_identifier = "noop-toolchain", +) + +toolchain( + name = "cc_toolchain", + toolchain = ":noop_toolchain", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +)
diff --git a/tools/toolchains/defs.bzl b/examples/tools/toolchains/defs.bzl similarity index 100% rename from tools/toolchains/defs.bzl rename to examples/tools/toolchains/defs.bzl
diff --git a/tools/toolchains/BUILD.bazel b/tools/toolchains/BUILD.bazel deleted file mode 100644 index eecadd0..0000000 --- a/tools/toolchains/BUILD.bazel +++ /dev/null
@@ -1,31 +0,0 @@ -"""Define a non-functional cc toolchain. - -To fail-fast in cases where we are forced to compile third-party C++ code, -define a cc toolchain that doesn't work, by using 'false' as the compiler. -See https://bazel.build/tutorials/ccp-toolchain-config -""" - -load("defs.bzl", "cc_toolchain_config") - -filegroup(name = "empty") - -cc_toolchain_config(name = "noop_toolchain_config") - -cc_toolchain( - name = "noop_toolchain", - all_files = ":empty", - compiler_files = ":empty", - dwp_files = ":empty", - linker_files = ":empty", - objcopy_files = ":empty", - strip_files = ":empty", - supports_param_files = 0, - toolchain_config = ":noop_toolchain_config", - toolchain_identifier = "noop-toolchain", -) - -toolchain( - name = "cc_toolchain", - toolchain = ":noop_toolchain", - toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", -)