feat: add language examples
diff --git a/.bazelrc b/.bazelrc index 8eb97f0..6a3045f 100644 --- a/.bazelrc +++ b/.bazelrc
@@ -2,8 +2,9 @@ # Take care to document any settings that you expect users to apply. # Settings that apply only to CI are in .github/workflows/ci.bazelrc -# Required until this is the default; expected in Bazel 7 -common --enable_bzlmod +# 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 # 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
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5692aa8..a98eab8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml
@@ -16,11 +16,14 @@ group: concurrency-group::${{ github.workflow }}::${{ github.event.pull_request.number > 0 && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}${{ github.ref_name == 'main' && format('::{0}', github.run_id) || ''}} cancel-in-progress: ${{ github.ref_name != 'main' }} +env: + RULES_PYTHON_ENABLE_PYSTAR: 0 + jobs: test: uses: bazel-contrib/.github/.github/workflows/bazel.yaml@v6 with: - folders: '["e2e/smoke"]' + folders: '[".", "e2e/smoke"]' exclude: | [ {"bazelversion": "6.4.0"}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7bc22bb..9480e1e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml
@@ -8,6 +8,9 @@ tags: - "v*.*.*" +env: + RULES_PYTHON_ENABLE_PYSTAR: 0 + jobs: release: uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v6
diff --git a/MODULE.bazel b/MODULE.bazel index 0d9ec07..951361e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel
@@ -10,11 +10,27 @@ bazel_dep(name = "rules_proto", version = "6.0.0-rc2") bazel_dep(name = "platforms", version = "0.0.8") -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) - protoc = use_extension("//protoc:extensions.bzl", "protoc") protoc.toolchain(version = "v25.3") use_repo(protoc, "toolchains_protoc_hub") register_toolchains("@toolchains_protoc_hub//:all") + +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.31.0", dev_dependency = True) + +# Update to include +# https://github.com/bazelbuild/rules_python/pull/1577 +git_override( + module_name = "rules_python", + commit = "3edcae33dcc43051ca6f200c2d0cb3692df79d03", + remote = "https://github.com/bazelbuild/rules_python.git", +) + +register_toolchains( + "//examples/lang_toolchains:all", + dev_dependency = True, +)
diff --git a/README.md b/README.md index 99e330e..56ba26b 100644 --- a/README.md +++ b/README.md
@@ -17,8 +17,8 @@ This repo simply contains a toolchain that resolves those pre-built binaries. -A full example including several language rules like `py_proto_library` and `java_proto_library` may be found at -https://github.com/bazelbuild/examples/tree/never_compile_protoc_again/proto +See `examples` for several language rules like `py_proto_library` and `java_proto_library`. +There is NO dependency on `@com_google_protobuf` anywhere. ## Design
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index 53b52af..1bfea0e 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel
@@ -1 +1,19 @@ # Marker that this is the root of a Bazel workspace. + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file", "http_jar") + +# Fetch the runtime package that applications need to marshal proto files. +# This does NOT do any code generation of .pb2.py files, we still use protoc for that. +# From https://pypi.org/project/protobuf/4.25.3/ +http_file( + name = "protobuf_4_25_3", + downloaded_file_path = "protobuf-4.25.3-py3-none-any.whl", + sha256 = "f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9", + urls = ["https://files.pythonhosted.org/packages/f4/d5/db585a5e8d64af6b384c7b3a63da13df2ff86933e486ba78431736c67c25/protobuf-4.25.3-py3-none-any.whl"], +) + +http_jar( + name = "protobuf-java_3_25_3", + sha256 = "e90d8ddb963b20a972a6a59b5093ade2b07cbe546cab3279aaf4383260385f58", + urls = ["https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.25.3/protobuf-java-3.25.3.jar"], +)
diff --git a/examples/BUILD b/examples/BUILD new file mode 100644 index 0000000..8f3509a --- /dev/null +++ b/examples/BUILD
@@ -0,0 +1,19 @@ +load("@rules_proto//proto:defs.bzl", "proto_library") +load("@rules_python//python:proto.bzl", "py_proto_library") + +package(default_visibility = ["//visibility:public"]) + +proto_library( + name = "foo_proto", + srcs = ["foo.proto"], +) + +py_proto_library( + name = "foo_py_proto", + deps = [":foo_proto"], +) + +java_proto_library( + name = "foo_java_proto", + deps = [":foo_proto"], +)
diff --git a/examples/foo.proto b/examples/foo.proto new file mode 100644 index 0000000..f81f088 --- /dev/null +++ b/examples/foo.proto
@@ -0,0 +1,7 @@ +syntax = "proto3"; + +option java_package = "proto"; + +message Foo { + string msg = 1; +}
diff --git a/examples/java/BUILD b/examples/java/BUILD new file mode 100644 index 0000000..004b088 --- /dev/null +++ b/examples/java/BUILD
@@ -0,0 +1,9 @@ +java_binary( + name = "java", + srcs = ["Main.java"], + main_class = "Main", + deps = [ + "//examples:foo_java_proto", + "@protobuf-java_3_25_3//jar", + ], +)
diff --git a/examples/java/Main.java b/examples/java/Main.java new file mode 100644 index 0000000..dd8deae --- /dev/null +++ b/examples/java/Main.java
@@ -0,0 +1,14 @@ +import com.google.protobuf.InvalidProtocolBufferException; +import static proto.FooOuterClass.Foo; + +public class Main { + public static void main(String[] args) throws InvalidProtocolBufferException { + System.out.println(makeMessage("Hello World!")); + } + + public static Foo makeMessage(String msg) { + Foo.Builder person = Foo.newBuilder(); + person.setMsg(msg); + return person.build(); + } +}
diff --git a/examples/lang_toolchains/BUILD b/examples/lang_toolchains/BUILD new file mode 100644 index 0000000..023e4e4 --- /dev/null +++ b/examples/lang_toolchains/BUILD
@@ -0,0 +1,39 @@ +load("@aspect_rules_py//py:defs.bzl", "py_unpacked_wheel") +load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain") + +# See WORKSPACE.bazel for fetch instructions of "protobuf_4_25_3". +# Turn the downloaded .whl file into a py_library-shape (provides PyInfo) +# Avoids the need for any pip, requirements files, python interpreter for wheel unpacking, etc +py_unpacked_wheel( + name = "protobuf_wheel", + src = "@protobuf_4_25_3//file", + py_package_name = "protobuf", +) + +# 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 = ":protobuf_wheel", +) + +proto_lang_toolchain( + name = "protoc_java_toolchain", + command_line = "--java_out=%s", + progress_message = "Generating Java proto_library %{label}", + runtime = "@protobuf-java_3_25_3//jar", +) + +# Adapters to the register_toolchains call, adding the toolchain_type to above +toolchain( + name = "protoc_py_toolchain.registration", + toolchain = ":protoc_py_toolchain", + toolchain_type = "@rules_python//python/proto:toolchain_type", +) + +toolchain( + name = "protoc_java_toolchain.registration", + toolchain = ":protoc_java_toolchain", + toolchain_type = "@rules_java//java/proto:toolchain_type", +)
diff --git a/examples/python/BUILD b/examples/python/BUILD new file mode 100644 index 0000000..89d9d95 --- /dev/null +++ b/examples/python/BUILD
@@ -0,0 +1,5 @@ +py_test( + name = "message_test", + srcs = ["message_test.py"], + deps = ["//examples:foo_py_proto"], +)
diff --git a/examples/python/message_test.py b/examples/python/message_test.py new file mode 100644 index 0000000..431efa2 --- /dev/null +++ b/examples/python/message_test.py
@@ -0,0 +1,15 @@ +import sys +import unittest + +from examples import foo_pb2 + +class TestCase(unittest.TestCase): + def test_message(self): + got = foo_pb2.Foo( + msg = "hello world", + ) + self.assertIsNotNone(got) + + +if __name__ == "__main__": + sys.exit(unittest.main())