Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aspect based proto impl #22

Merged
merged 8 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ build:nix --host_platform=@rules_nixpkgs_core//platforms:host
build:nix --host_cxxopt=-std=c++14
build:nix --cxxopt=c++14
# bazel run @rules_bazel_integration_test//tools:update_deleted_packages
build:nix --deleted_packages=examples/elm-binary,examples/elm-proto,examples/elm-test,examples/elm-todomvc
query:nix --deleted_packages=examples/elm-binary,examples/elm-proto,examples/elm-test,examples/elm-todomvc
build:nix --deleted_packages=examples/elm-binary,examples/elm-proto,examples/elm-proto/foo,examples/elm-test,examples/elm-todomvc
query:nix --deleted_packages=examples/elm-binary,examples/elm-proto,examples/elm-proto/foo,examples/elm-test,examples/elm-todomvc

14 changes: 2 additions & 12 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,15 @@ module(
compatibility_level = 1,
)

# bazel_dep(name = "rules_nixpkgs_core", version = "0.11.1")
bazel_dep(name = "aspect_rules_js", version = "2.0.0-rc4")
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "aspect_bazel_lib", version = "2.7.7")
bazel_dep(name = "rules_nodejs", version = "6.1.0")
bazel_dep(name = "rules_proto_grpc", version = "5.0.0")
archive_override(
module_name = "rules_proto_grpc",
urls = [
"https://github.com/rules-proto-grpc/rules_proto_grpc/archive/refs/tags/5.0.0.tar.gz"
],
strip_prefix = "rules_proto_grpc-5.0.0/modules/core",
integrity = "sha256-xrMPlUcHkvmJTjtrasJxgTp7WfbLQ6CbyhUhPTCdRfk="
)

bazel_dep(name = "cgrindel_bazel_starlib", version = "0.20.2")
bazel_dep(name = "rules_proto", version = "6.0.2")
bazel_dep(name = "rules_nixpkgs_core", version = "0.12.0", dev_dependency = True)
bazel_dep(name = "rules_bazel_integration_test", version = "0.24.1", dev_dependency = True)
bazel_dep(name = "cgrindel_bazel_starlib", version = "0.20.2", dev_dependency = True)

npm = use_extension("@aspect_rules_js//npm:extensions.bzl", "npm", dev_dependency = True)
npm.npm_translate_lock(
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,19 @@ sufficient to use `elm_repository()`.
```python
load("@com_github_edschouten_rules_elm//proto:def.bzl", "elm_proto_library")

elm_proto_library(name, proto, visibility)
elm_proto_library(name, proto, deps, plugin_opt_json, plugin_opt_grpc, visibility)
```

**Purpose:** generate Elm bindings for [Protocol Buffers](https://developers.google.com/protocol-buffers/)
definitions using [tiziano88/elm-protobuf](https://github.com/tiziano88/elm-protobuf)
definitions using [protoc-gen-elm](https://www.npmjs.com/package/protoc-gen-elm)
and package them as an `elm_library()`.

- `proto`: The `proto_library()` that should be converted to Elm.
- `deps`: Elm deps required to compile generated code.
- `plugin_opt_json`: One of {json, json=encode, json=decode},
see [protoc-gen-elm docs](https://www.npmjs.com/package/protoc-gen-elm)
- `plugin_opt_grpc`: One of {grpc, grpc=false, grpc=true},
see [protoc-gen-elm docs](https://www.npmjs.com/package/protoc-gen-elm)

**Note:** This function is implemented using [Bazel aspects](https://docs.bazel.build/versions/master/skylark/aspects.html),
meaning that it automatically instantiates build rules for all
Expand Down
1 change: 1 addition & 0 deletions elm/generate_test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

all_tests = tests_found

# TODO: there's a bug: when multiple functions are found, then List.map fails to unify the type
# Emit a main source file that calls the tests.
# TODO(edsch): What about the seed?
with open(output_file, "w") as f:
Expand Down
27 changes: 19 additions & 8 deletions examples/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ Passed: 4
Failed: 0""",
)

# Due to macos protoc compilation issues, this test works only with bazel7
# Due to macos protoc compilation issues, protoc test works only with bazel7
# as it is using bazel7's --incompatible_enable_proto_toolchain_resolution
rules_elm_integration_test(
name = "elm_proto",
name = "elm_proto_simple",
test_runner = ":output_match_runner",
workspace_path = "elm-proto",
bazel_cmd = "test :spec_proto --test_output=all",
bazel_cmd = "test :spec --test_output=all",
expected_output = """TEST RUN PASSED

Duration: 0 ms
Expand All @@ -91,10 +91,20 @@ Failed: 0""",
tags = [ "bazel7" ]
)

# bazel7 cmd:
# bazel query 'attr("tags", "[\[ ]bazel7[,\]]", deps("//examples:integration_tests"))' | xargs -L1 bazel run --config=nix
# bazel6 cmd:
# bazel test //examples:integration_tests --config=nix --test_tag_filters=bazel6
rules_elm_integration_test(
name = "elm_proto_complex",
test_runner = ":output_match_runner",
workspace_path = "elm-proto",
bazel_cmd = "test //foo:spec --test_output=all",
expected_output = """TEST RUN PASSED

Duration: 0 ms
Passed: 1
Failed: 0""",
bazel_binary = bazel_binaries["bazel7"],
tags = [ "bazel7" ]
)

test_suite(
name = "integration_tests",
tests = gen_test_names_each(
Expand All @@ -107,7 +117,8 @@ test_suite(
],
bazel_binaries = bazel_binaries,
) + [
"elm_proto"
"elm_proto_simple",
"elm_proto_complex",
],
visibility = ["//:__subpackages__"],
)
1 change: 1 addition & 0 deletions examples/elm-proto/.bazelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
build --host_platform=@rules_nixpkgs_core//platforms:host
common --enable_bzlmod
# common --protocopt="--elm_opt=json"
# to use nixpkgs provided protoc bin
common --incompatible_enable_proto_toolchain_resolution
# getting rid of [...]execroot/_main/bazel-out/k8-fastbuild/bin/elm_book_proto_elm_proto_compile is a dangling symbolic link
Expand Down
43 changes: 25 additions & 18 deletions examples/elm-proto/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
load("@com_github_edschouten_rules_elm//proto:def.bzl", "elm_proto_library", "elm_grpc_library")
load("@com_github_edschouten_rules_elm//proto:def.bzl", "elm_proto_library", "ELM_PROTO_TOOLCHAIN", "ELM_PROTO_DEPS")
load("@com_github_edschouten_rules_elm//proto:elm_proto_toolchain_rule.bzl", "elm_proto_toolchain")
load("@com_github_edschouten_rules_elm//elm:def.bzl", "elm_test")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_proto//proto:proto_toolchain.bzl", "proto_toolchain")
load("@rules_nodejs//nodejs:toolchain.bzl", "nodejs_toolchain")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_proto//proto/private/rules:proto_toolchain_rule.bzl", "proto_toolchain")

nodejs_toolchain(
Expand All @@ -27,36 +27,43 @@ proto_toolchain(
toolchain(
name = "nixpkgs_protobuf_toolchain",
toolchain_type = "@rules_proto//proto:toolchain_type",
exec_compatible_with = [ "@rules_nixpkgs_core//constraints:support_nix" ],
exec_compatible_with = [
"@rules_nixpkgs_core//constraints:support_nix"
],
toolchain = ":nixpkgs_protoc_toolchain",
)

elm_proto_toolchain(
name = "elm_proto_toolchain_opt_json",
proto_compiler = "@nixpkgs_protobuf//:bin/protoc",
)

toolchain(
name = "nixpkgs_elm_protobuf_toolchain",
toolchain_type = ELM_PROTO_TOOLCHAIN,
exec_compatible_with = [ "@rules_nixpkgs_core//constraints:support_nix" ],
toolchain = ":elm_proto_toolchain_opt_json",
)

proto_library(
name = "book_proto",
srcs = [ "book.proto" ]
srcs = [ "book.proto" ],
visibility = ["//visibility:public"],
)

elm_proto_library(
name = "elm_book_proto",
protos = [ "book_proto" ],
plugin_opts = [ "json" ],
deps = [
"@elm_package_anmolitor_elm_protocol_buffers",
"@elm_package_elm_protoc_utils",
"@elm_package_danfishgold_base64_bytes",
"@elm_package_rtfeldman_elm_iso8601_date_strings",
"@elm_package_elm_http",
"@elm_package_elm_file",
"@elm_package_elm_parser",
]
proto = ":book_proto",
plugin_opt_json = "json=decode",
deps = ELM_PROTO_DEPS,
)

elm_test(
name = "spec_proto",
name = "spec",
main = "Spec.elm",
deps = [
":elm_book_proto",
"@elm_package_elm_test",
],
]
)

75 changes: 2 additions & 73 deletions examples/elm-proto/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,7 @@ bazel_dep(name = "rules_nodejs", version = "6.1.0")
bazel_dep(name = "aspect_bazel_lib", version = "2.7.7")
bazel_dep(name = "aspect_rules_js", version = "2.0.0-rc4")
bazel_dep(name = "rules_proto", version = "6.0.2")
bazel_dep(name = "rules_proto_grpc", version = "5.0.0")
archive_override(
module_name = "rules_proto_grpc",
urls = [
"https://github.com/rules-proto-grpc/rules_proto_grpc/archive/refs/tags/5.0.0.tar.gz"
],
strip_prefix = "rules_proto_grpc-5.0.0/modules/core",
integrity = "sha256-xrMPlUcHkvmJTjtrasJxgTp7WfbLQ6CbyhUhPTCdRfk="
)

# TODO: remove rules_proto dependency
# In the time of writing, there still exists wired dependency between protobuf <-> rules_proto
# To get rid of this mess, git_override was used.
# git_override(
# module_name = "protobuf",
# remote = "https://github.com/protocolbuffers/protobuf",
# commit = "eceb8ccc0db3512e305c1b5a6128d7c421f62655"
# )
bazel_dep(name = "protobuf", version = "23.1", repo_name = "com_google_protobuf")

nix_repo = use_extension("@rules_nixpkgs_core//extensions:repository.bzl", "nix_repo")
nix_pkg = use_extension("@rules_nixpkgs_core//extensions:package.bzl", "nix_pkg")
Expand All @@ -44,69 +27,15 @@ nix_pkg.attr(
repo = "@nixpkgs",
)

nix_pkg.expr(
name = "com_github_tiziano88_elm_protobuf",
repo = "@nixpkgs",
attr = "",
expr = """
{ pkgs ? import <nixpkgs> {} }:

with pkgs;
let
osSuffix = if stdenv.isDarwin then "osx" else "linux";
sha256Darwin = "sha256-lD73CVQC6srB2/3bg6J5BiOSWUvN+1V8UZ2Eg1Atn5k=";
sha256Linux = "sha256-0JZ3WCGybG4pVC0JYVnX3KlC9U1R7s0so4l7fLbaaF4=";
checkSum = if stdenv.isDarwin then sha256Darwin else sha256Linux;
in
pkgs.stdenv.mkDerivation {
name = "protoc-gen-elm";
src = fetchurl {
url = "https://github.com/tiziano88/elm-protobuf/releases/download/3.0.0/elm-protobuf-3.0.0-${osSuffix}-x86_64.tar.gz";
sha256 = checkSum;
};

sourceRoot = "bin/elm-protobuf-3.0.0-${osSuffix}-x86_64";

installPhase = ''
install -m755 -D protoc-gen-elm $out/bin/protoc-gen-elm
mkdir -p $out/protoc-gen-elm/
ln -sf $out/bin/protoc-gen-elm $out/protoc-gen-elm/protoc-elm
cat <<EOF > $out/protoc-gen-elm/BUILD
filegroup(
name = "protoc-gen-elm",
srcs = ["protoc-elm"],
visibility = ["//visibility:public"],
)
EOF
'';
}""",
build_file_content = """
package(default_visibility = ["//visibility:public"])
""",
)

# nix_pkg.attr(
# name = "com_google_protobuf",
# repo = "@nixpkgs",
# attr = "protobuf",
# build_file_content = """
# package(default_visibility = ["//visibility:public"])
# filegroup(
# name = "protoc",
# srcs = ["bin/protoc"],
# )""",
# )

use_repo(
nix_pkg,
"nixpkgs_nodejs",
"nixpkgs_protobuf",
"com_github_tiziano88_elm_protobuf",
# "com_google_protobuf",
)

register_toolchains(
"//:nixpkgs_nodejs_toolchain",
"//:nixpkgs_elm_protobuf_toolchain",
"//:nixpkgs_protobuf_toolchain",
)

Loading