diff --git a/README.md b/README.md index e03f99ff2..cca4f0073 100644 --- a/README.md +++ b/README.md @@ -494,7 +494,7 @@ with the following `scala_toolchains()` parameters: ```py scala_toolchains( scala_proto = True, - scala_proto_enable_all_options = True, + scala_proto_options = [], ) ``` @@ -819,6 +819,60 @@ under WORKSPACE](#6.5.0), with the maximum dependency versions specified in that section. While this may continue to work for some time, it is not officially supported. +### `scala_proto_toolchain` changes and new `scalapb_toolchain` macro + +`scala_proto_toolchain` has a more flexible plugin configuration schema. The +new `generators` and `generators_opts` attributes replace the following +attributes: + +- `with_grpc` +- `with_flat_package` +- `with_single_line_to_string` +- `main_generator` +- `named_generators` + +Now each generator (plugin) will get a corresponding name +that can be used for further plugin options setup: + +```py +scala_proto_toolchain( + name = "example", + generators = { + "scala": "scripts.ScalaPbCodeGenerator", + "jvm_extra_protobuf_generator": "scalarules.test.extra_protobuf_generator.ExtraProtobufGenerator", + }, + generators_opts = { + "scala": [ + "grpc", + "single_line_to_proto_string", + ], + "jvm_extra_protobuf_generator": [ + "grpc", + "single_line_to_proto_string", + ], + }, +) +``` + +`scalapb_grpc_deps` no longer exists since it's now the user's responsibility +to configure dependencies based on the provided generators and their options. + +The new `scalapb_toolchain` convenience macro wraps `scala_proto_toolchain` +to provide the default [ScalaPB](https://scalapb.github.io/) implementation: + +```py +load("//scala_proto:scala_proto_toolchain.bzl", "scalapb_toolchain") + +scalapb_toolchain( + name = "my_toolchain", + opts = [ + "grpc", + "single_line_to_proto_string", + ], + visibility = ["//visibility:public"], +) +``` + ### Removal of `bind()` aliases for `twitter_scrooge` dependencies `rules_scala` 7.x removes all of the obsolete [`bind()`][] aliases under diff --git a/docs/scala_proto_library.md b/docs/scala_proto_library.md index 4ebe76bcb..ab77b6077 100644 --- a/docs/scala_proto_library.md +++ b/docs/scala_proto_library.md @@ -7,6 +7,11 @@ which adds a few dependencies needed for ScalaPB: scala_toolchains( # Other toolchains settings... scala_proto = True, + scala_proto_options = [ + "grpc", + "flat_package", + "scala3_sources", + ], ) scala_register_toolchains() @@ -47,9 +52,13 @@ load( scala_proto_toolchain( name = "scala_proto_toolchain", - with_grpc = False, - with_flat_package = False, - with_single_line_to_string = False, + generators_opts = { + "scala": [ + "grpc", + "flat_package", + "scala3_sources", + ] + }, visibility = ["//visibility:public"], ) @@ -66,12 +75,10 @@ toolchain( | Attribute name | Description | | ----------------------------- | ----------------------------------------------------- | | name | `Name, required`
A unique name for this toolchain. | -| with_grpc | `boolean, optional (default False)`
Enables generation of grpc service bindings for services. | -| with_flat_package | `boolean, optional (default False)`
When true, ScalaPB will not append the protofile base name to the package name. | -| with_single_line_to_string | `boolean, optional (default False)`
Enables generation of toString() methods that use a single line format. | +| generators_opts | `List of strings, optional`
Additional protobuf options like 'grpc', 'flat_package' or 'scala3_sources'. | | blacklisted_protos | `List of labels, optional`
List of protobuf targets to exclude from recursive building. | | code_generator | `Label, optional (has default)`
Which code generator to use. A sensible default is provided. | -| named_generators | `String dict, optional` | +| generators | `String dict, optional` | | extra_generator_dependencies | `List of labels, optional` | | scalac | `Label, optional (has default)`
Target for scalac. A sensible default is provided. | @@ -89,7 +96,6 @@ scala_proto_deps_toolchain( visibility = ["//visibility:public"], dep_providers = [ ":my_compile_deps", - ":my_grpc_deps", ], ) @@ -105,17 +111,10 @@ declare_deps_provider( deps = ["@dep1", "@dep2"], visibility = ["//visibility:public"], ) - -declare_deps_provider( - name = "my_grpc_deps", - deps_id = "scalapb_grpc_deps", - deps = ["@dep3", "@dep4"], - visibility = ["//visibility:public"], -) ``` ### `scala_proto_deps_toolchain` Toolchain Attributes | Attribute name | Description | | ----------------------------- | ----------------------------------------------------- | -| dep_providers | `List of labels, optional (has default)`
allows injection of gRPC (deps_id - `scalapb_grpc_deps`) and ScalaPB (deps_id `scalapb_compile_deps`) dependencies | +| dep_providers | `List of labels, optional (has default)`
allows injection of gRPC (deps_id - `scalapb_worker_deps`) and ScalaPB (deps_id `scalapb_compile_deps`) dependencies | diff --git a/scala/toolchains.bzl b/scala/toolchains.bzl index a0d2e017e..8d041a871 100644 --- a/scala/toolchains.bzl +++ b/scala/toolchains.bzl @@ -42,7 +42,7 @@ def scala_toolchains( scalafmt = False, scalafmt_default_config_path = ".scalafmt.conf", scala_proto = False, - scala_proto_enable_all_options = False, + scala_proto_options = [], jmh = False, twitter_scrooge = False, twitter_scrooge_deps = {}): @@ -84,9 +84,8 @@ def scala_toolchains( scalafmt_default_config_path: the relative path to the default Scalafmt config file within the repository scala_proto: whether to instantiate the scala_proto toolchain - scala_proto_enable_all_options: whether to instantiate the scala_proto - toolchain with all options enabled; `scala_proto` must also be - `True` for this to take effect + scala_proto_options: protobuf options, like 'scala3_sources' or 'grpc'; + `scala_proto` must also be `True` for this to take effect jmh: whether to instantiate the Java Microbenchmarks Harness toolchain twitter_scrooge: whether to instantiate the twitter_scrooge toolchain twitter_scrooge_deps: dictionary of string to Label containing overrides @@ -180,7 +179,7 @@ def scala_toolchains( specs2 = specs2, scalafmt = scalafmt, scala_proto = scala_proto, - scala_proto_enable_all_options = scala_proto_enable_all_options, + scala_proto_options = scala_proto_options, jmh = jmh, twitter_scrooge = twitter_scrooge, twitter_scrooge_deps = twitter_scrooge_deps, diff --git a/scala/toolchains_repo.bzl b/scala/toolchains_repo.bzl index 1e4c01b12..3fd256a56 100644 --- a/scala/toolchains_repo.bzl +++ b/scala/toolchains_repo.bzl @@ -46,7 +46,7 @@ def _scala_toolchains_repo_impl(repository_ctx): repo_attr = repository_ctx.attr format_args = { "rules_scala_repo": Label("//:all").repo_name, - "proto_enable_all_options": repo_attr.scala_proto_enable_all_options, + "proto_options": repo_attr.scala_proto_options, } toolchains = {} @@ -96,9 +96,9 @@ _scala_toolchains_repo = repository_rule( "scala_proto": attr.bool( doc = "Instantiate the scala_proto toolchain", ), - "scala_proto_enable_all_options": attr.bool( + "scala_proto_options": attr.string_list( doc = ( - "Enable all scala_proto_options; " + + "Protobuf generator options; " + "scala_proto must also be True for this to take effect" ), ), @@ -216,21 +216,14 @@ load( setup_scala_proto_toolchains( name = "scala_proto", - enable_all_options = {proto_enable_all_options}, + default_gen_opts = {proto_options}, ) declare_deps_provider( name = "scalapb_compile_deps_provider", deps_id = "scalapb_compile_deps", visibility = ["//visibility:public"], - deps = DEFAULT_SCALAPB_COMPILE_DEPS, -) - -declare_deps_provider( - name = "scalapb_grpc_deps_provider", - deps_id = "scalapb_grpc_deps", - visibility = ["//visibility:public"], - deps = DEFAULT_SCALAPB_GRPC_DEPS, + deps = DEFAULT_SCALAPB_COMPILE_DEPS + DEFAULT_SCALAPB_GRPC_DEPS, ) declare_deps_provider( diff --git a/scala_proto/default/default_deps.bzl b/scala_proto/default/default_deps.bzl index a6a8945ab..fb9d2e925 100644 --- a/scala_proto/default/default_deps.bzl +++ b/scala_proto/default/default_deps.bzl @@ -17,9 +17,8 @@ _DEFAULT_DEP_PROVIDER_FORMAT = ( def scala_proto_deps_providers( compile = _DEFAULT_DEP_PROVIDER_FORMAT % "compile", - grpc = _DEFAULT_DEP_PROVIDER_FORMAT % "grpc", worker = _DEFAULT_DEP_PROVIDER_FORMAT % "worker"): - return [compile, grpc, worker] + return [compile, worker] DEFAULT_SCALAPB_COMPILE_DEPS = [ Label("//scala/private/toolchain_deps:scala_library_classpath"), diff --git a/scala_proto/private/scala_proto_aspect.bzl b/scala_proto/private/scala_proto_aspect.bzl index 7abb89b13..c05da751a 100644 --- a/scala_proto/private/scala_proto_aspect.bzl +++ b/scala_proto/private/scala_proto_aspect.bzl @@ -70,7 +70,8 @@ def _generate_sources(ctx, toolchain, proto): args.use_param_file(param_file_arg = "@%s", use_always = True) for gen, out in outputs.items(): args.add("--" + gen + "_out", out) - args.add("--" + gen + "_opt", toolchain.generators_opts) + if gen in toolchain.generators_opts: + args.add_all(toolchain.generators_opts[gen], format_each = "--{}_opt=%s".format(gen)) args.add_joined("--descriptor_set_in", descriptors, join_with = ctx.configuration.host_path_separator) args.add_all(sources) diff --git a/scala_proto/scala_proto_toolchain.bzl b/scala_proto/scala_proto_toolchain.bzl index b579c69d2..51bcb6e55 100644 --- a/scala_proto/scala_proto_toolchain.bzl +++ b/scala_proto/scala_proto_toolchain.bzl @@ -4,12 +4,6 @@ load( _scala_proto_deps_providers = "scala_proto_deps_providers", ) -def _generators(ctx): - return dict( - ctx.attr.named_generators, - scala = ctx.attr.main_generator, - ) - def _generators_jars(ctx): generator_deps = ctx.attr.extra_generator_dependencies + [ ctx.attr._main_generator_dep, @@ -19,22 +13,6 @@ def _generators_jars(ctx): for dep in generator_deps ]) -def _generators_opts(ctx): - opts = [] - if ctx.attr.with_grpc: - opts.append("grpc") - if ctx.attr.with_flat_package: - opts.append("flat_package") - if ctx.attr.with_single_line_to_string: - opts.append("single_line_to_proto_string") - return ",".join(opts) - -def _compile_dep_ids(ctx): - deps = ["scalapb_compile_deps"] - if ctx.attr.with_grpc: - deps.append("scalapb_grpc_deps") - return deps - def _ignored_proto_targets_by_label(ctx): return {p.label: p for p in ctx.attr.blacklisted_protos} @@ -49,13 +27,14 @@ def _worker_flags(ctx, generators, jars): return "--jvm_flags=" + " ".join(["-D%s=%s" % i for i in env.items()]) def _scala_proto_toolchain_impl(ctx): - generators = _generators(ctx) + generators = ctx.attr.generators generators_jars = _generators_jars(ctx) + compile_dep_ids = ["scalapb_compile_deps"] toolchain = platform_common.ToolchainInfo( generators = generators, generators_jars = generators_jars, - generators_opts = _generators_opts(ctx), - compile_dep_ids = _compile_dep_ids(ctx), + generators_opts = ctx.attr.generators_opts, + compile_dep_ids = compile_dep_ids, blacklisted_protos = _ignored_proto_targets_by_label(ctx), protoc = ctx.executable.protoc, scalac = ctx.attr.scalac.files_to_run, @@ -66,17 +45,11 @@ def _scala_proto_toolchain_impl(ctx): return [toolchain] # Args: -# with_grpc: Enables generation of grpc service bindings for services -# with_flat_package: When true, ScalaPB will not append the protofile base name to the package name -# with_single_line_to_string: Enables generation of toString() methods that use the single line format # blacklisted_protos: list of protobuf targets to exclude from recursive building # code_generator: what code generator to use, usually you'll want the default scala_proto_toolchain = rule( implementation = _scala_proto_toolchain_impl, attrs = { - "with_grpc": attr.bool(), - "with_flat_package": attr.bool(), - "with_single_line_to_string": attr.bool(), "blacklisted_protos": attr.label_list(default = []), "code_generator": attr.label( executable = True, @@ -84,17 +57,8 @@ scala_proto_toolchain = rule( default = Label("//src/scala/scripts:scalapb_worker"), allow_files = True, ), - # `scripts.ScalaPbCodeGenerator` and `_main_generator_dep` are currently - # necessary to support protoc-bridge < 0.9.8, specifically 0.7.14 - # required by Scala 2.11. See #1647 and scalapb/ScalaPB#1771. - # - # If we drop 2.11 support, restore `scalapb.ScalaPbCodeGenerator` here, - # remove `_main_generator_dep`, and delete - # `//src/scala/scripts:scalapb_codegenerator_wrapper` and its files. - "main_generator": attr.string( - default = "scripts.ScalaPbCodeGenerator", - ), - "named_generators": attr.string_dict(), + "generators": attr.string_dict(), + "generators_opts": attr.string_list_dict(), "extra_generator_dependencies": attr.label_list( providers = [JavaInfo], ), @@ -121,6 +85,13 @@ scala_proto_toolchain = rule( [proto rules documentation](https://docs.bazel.build/versions/master/be/protocol-buffer.html#proto_library) """, ), + # `scripts.ScalaPbCodeGenerator` and `_main_generator_dep` are currently + # necessary to support protoc-bridge < 0.9.8, specifically 0.7.14 + # required by Scala 2.11. See #1647 and scalapb/ScalaPB#1771. + # + # If we drop 2.11 support, restore `scalapb.ScalaPbCodeGenerator` here, + # remove `_main_generator_dep`, and delete + # `//src/scala/scripts:scalapb_codegenerator_wrapper` and its files. "_main_generator_dep": attr.label( default = Label( "//src/scala/scripts:scalapb_codegenerator_wrapper", @@ -132,6 +103,25 @@ scala_proto_toolchain = rule( }, ) +def scalapb_toolchain(name, opts = [], **kwargs): + """Sets up a scala_proto_toolchain using ScalaPB. + + Args: + name: A unique name for this target + opts: scalapb generator options like 'grpc' or 'flat_package' + kwargs: remaining arguments to `scala_proto_toolchain` + """ + scala_proto_toolchain( + name = name, + generators = { + "scala": "scripts.ScalaPbCodeGenerator", + }, + generators_opts = { + "scala": opts, + }, + **kwargs + ) + def _scala_proto_deps_toolchain(ctx): toolchain = platform_common.ToolchainInfo( dep_providers = ctx.attr.dep_providers, diff --git a/scala_proto/toolchains.bzl b/scala_proto/toolchains.bzl index 866ee19f6..a315732a4 100644 --- a/scala_proto/toolchains.bzl +++ b/scala_proto/toolchains.bzl @@ -1,10 +1,14 @@ load( "//scala_proto:scala_proto_toolchain.bzl", "scala_proto_deps_toolchain", - "scala_proto_toolchain", + "scalapb_toolchain", ) -def setup_scala_proto_toolchains(name, enable_all_options = False): +_default_gen_opts = [ + "grpc", +] + +def setup_scala_proto_toolchains(name, default_gen_opts = _default_gen_opts): """Used by @rules_scala_toolchains//scala_proto/BUILD. See //scala/private:macros/toolchains_repo.bzl for details, especially the @@ -12,14 +16,13 @@ def setup_scala_proto_toolchains(name, enable_all_options = False): Args: name: prefix for all generate toolchains - enable_all_options: set to True to enable the `with_flat_package` and - `with_single_line_to_string` attributes of `scala_proto_toolchain` + default_gen_opts: parameters passed to the default generator """ scala_proto_deps_toolchain( name = "%s_default_deps_toolchain_impl" % name, dep_providers = [ ":scalapb_%s_deps_provider" % p - for p in ["compile", "grpc", "worker"] + for p in ["compile", "worker"] ], visibility = ["//visibility:public"], ) @@ -32,22 +35,11 @@ def setup_scala_proto_toolchains(name, enable_all_options = False): toolchain_name = "%s_default_toolchain" % name toolchain_impl_name = "%s_default_toolchain_impl" % name - toolchain_options = { - "with_flat_package": False, - "with_grpc": True, - "with_single_line_to_string": False, - } - - if enable_all_options: - toolchain_name = "%s_enable_all_options_toolchain" % name - toolchain_impl_name = "%s_enable_all_options_toolchain_impl" % name - toolchain_options["with_flat_package"] = True - toolchain_options["with_single_line_to_string"] = True - - scala_proto_toolchain( + + scalapb_toolchain( name = toolchain_impl_name, + opts = default_gen_opts, visibility = ["//visibility:public"], - **toolchain_options ) native.toolchain( diff --git a/test/proto/BUILD b/test/proto/BUILD index 751edd6f8..7e01ec55f 100644 --- a/test/proto/BUILD +++ b/test/proto/BUILD @@ -24,13 +24,21 @@ scala_proto_toolchain( extra_generator_dependencies = [ "//test/src/main/scala/scalarules/test/extra_protobuf_generator", ], - named_generators = { + generators = { + "scala": "scripts.ScalaPbCodeGenerator", "jvm_extra_protobuf_generator": "scalarules.test.extra_protobuf_generator.ExtraProtobufGenerator", }, + generators_opts = { + "scala": [ + "grpc", + "single_line_to_proto_string", + ], + "jvm_extra_protobuf_generator": [ + "grpc", + "single_line_to_proto_string", + ], + }, visibility = ["//visibility:public"], - with_flat_package = False, - with_grpc = True, - with_single_line_to_string = True, ) toolchain( diff --git a/test/proto/custom_generator/BUILD.bazel b/test/proto/custom_generator/BUILD.bazel index a4585d0e5..261301ac6 100644 --- a/test/proto/custom_generator/BUILD.bazel +++ b/test/proto/custom_generator/BUILD.bazel @@ -62,7 +62,9 @@ toolchain( scala_proto_toolchain( name = "scala_proto_toolchain_def", - main_generator = "test.proto.custom_generator.DummyGenerator", + generators = { + "scala": "test.proto.custom_generator.DummyGenerator", + }, ) toolchain( @@ -100,7 +102,9 @@ toolchain( scala_proto_toolchain( name = "failing_scala_proto_toolchain_def", - main_generator = "test.proto.custom_generator.FailingGenerator", + generators = { + "scala": "test.proto.custom_generator.FailingGenerator", + }, ) toolchain( diff --git a/test_expect_failure/missing_direct_deps/scala_proto_deps/BUILD b/test_expect_failure/missing_direct_deps/scala_proto_deps/BUILD index e3173d0dd..44b0596b1 100644 --- a/test_expect_failure/missing_direct_deps/scala_proto_deps/BUILD +++ b/test_expect_failure/missing_direct_deps/scala_proto_deps/BUILD @@ -2,7 +2,7 @@ load("@rules_proto//proto:defs.bzl", "proto_library") load("@rules_java//java:defs.bzl", "java_library") load("//scala:scala.bzl", "scala_library") load("//scala_proto:scala_proto.bzl", "scala_proto_library") -load("//scala_proto:scala_proto_toolchain.bzl", "scala_proto_toolchain") +load("//scala_proto:scala_proto_toolchain.bzl", "scalapb_toolchain") load(":customized_scala_proto.bzl", "custom_stamping_convention", "custom_stamping_scala_proto_library") proto_library( @@ -28,7 +28,7 @@ java_library( deps = [":some_scala_proto"], ) -scala_proto_toolchain( +scalapb_toolchain( name = "stamp_by_convention_toolchain_impl", stamp_by_convention = True, ) diff --git a/test_version/WORKSPACE.template b/test_version/WORKSPACE.template index 77101c65c..e367fc3aa 100644 --- a/test_version/WORKSPACE.template +++ b/test_version/WORKSPACE.template @@ -65,6 +65,7 @@ load( scala_toolchains( fetch_sources = True, scala_proto = True, + scala_proto_options = ["grpc"], scalatest = True, specs2 = True, )