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

Expose proto fragment fields necessary for writing proto_toolchain to Starlark #9000

Closed

Conversation

Yannic
Copy link
Contributor

@Yannic Yannic commented Jul 28, 2019

This change exposes some of the Protobuf-related command-line flags to Starlark.

There is a risk of adding these fields, so we gave them a scary name and documented how users are supposed to access them. Hopefully, this will be enough to fight Hyrum's Law.

Blocking #10006

Working towards #10005

Design doc:
https://docs.google.com/document/d/1u95vlQ1lWeQNR4bUw5T4cMeHTGJla2_e1dHHx7v4Dvg/edit#

@jin jin added the team-Rules-Server Issues for serverside rules included with Bazel label Jul 28, 2019
@Yannic Yannic marked this pull request as ready for review October 13, 2019 15:23
@Yannic Yannic requested a review from hlopko as a code owner October 13, 2019 15:23
@Yannic
Copy link
Contributor Author

Yannic commented Oct 13, 2019

@lberki This is ready for review now.

//cc @hlopko

Copy link
Contributor

@lberki lberki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind also adding some rudimentary tests?

@SkylarkConfigurationField(
// Must match the value of `_protoc_key`
// in `@rules_proto//proto/private/rules:proto_toolchain.bzl`.
name = "protoc_do_not_use_or_we_will_break_you_without_mercy",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the plan for this command line option?

The usual thing we do is to have rules like CcToolchainAliasRule, although those can just as well be implemented in Starlark. That way, you don't need to have a late-bound default. Even better, you can prescribe a particular name for that rule so that people use it as little as possible (although we don't do that for the rest of the alias rules)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these options here are meant for use in a new proto_toolchain rule that is eventually going to replace the command-line options.

i.e. Now, proto_toolchain exposes the options and looks like this: https://github.com/bazelbuild/rules_proto/blob/919671ef0f73f5a82037eaabedc39c938c13cf60/proto/BUILD#L8, and eventually, it will look like this, and the command-line options are deprecated and removed:

proto_toolchain(
    name = "default_toolchain_impl",
    compiler = "@com_google_protobuf//:protoc",
    protocopt = ["--foo", "--bar"],
    strict_deps = "ERROR",
    visibility = ["//visibility:public"],
)

I guess we could also implement proto_toolchain as native rule first, but since we're going to replace it with a Starlark rule eventually, we can also implement it Starlark now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my question I already sent is answered here :) So you plan to replace command line options completely?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, long-term (>1y), I'd like to get rid of the (native) command-line options.

return "OFF";

case WARN:
return "WARN";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually use "WARN"? AFAIU it's only used for the Java sandwich, but that's passed in from Starlark. And if not, how about using a Boolean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Today, WARN==ERROR (and DEFAULT==OFF [1], but the default value for --strict_proto_deps is error 🤷‍♀). I'd like proto_library to support WARN eventually, and also print some nice buildozer commands when there are errors or warnings, similar to what Java does.

[1] https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java;l=616?q=areDepsStrict

doc = "Do not use this field, its only purpose is to help with migration of "
+ "Protobuf rules to Starlark.",
structField = true)
default void configurationFieldProtocExists() {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this used for? To check for the presence of other fields? Then why not check directly for their presence instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used to check whether --proto_compiler is available. Unfortunately, it's the only way to feature-detect late-bound defaults. https://github.com/bazelbuild/rules_proto/blob/919671ef0f73f5a82037eaabedc39c938c13cf60/proto/private/rules/proto_toolchain.bzl#L35

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative is to check for Bazel version (like we do e.g. here: https://github.com/bazelbuild/rules_rust/blob/master/rust/private/rustc.bzl#L138). That requires creating an external repository to write the bazel version.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @laurentlb your thoughts on this? This is an example of users having to jump through hoops because we don't have a way to test if constant is defined?

@SkylarkCallable(
// Must match the value of `_protocopt_key`
// in `@rules_proto//proto/private/rules:proto_toolchain.bzl`.
name = "protocopt_do_not_use_or_we_will_break_you_without_mercy",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hlopko , how about living without the scary "this is not a supported API" suffix?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought you like these suffices :) For my perspective I don't think this can cause too much trouble if we expose it under short name. And removing the option using an incompatible flag won't be too bad either. So feel free to use the short name Yannic, if you don't feel strongly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel strongly either way. @lberki originally suggested them, so it's your call whether we use long or short names :). I'd like to keep the access them through proto_toolchain-suggestion, though.

@Yannic
Copy link
Contributor Author

Yannic commented Oct 14, 2019

Thanks! I'll add some tests to verify the fields are there and return the correct values.

As I said, the goal is to eventually remove the command-line options, thus the fields, so I'd like to keep the usage as low as possible.

@lberki
Copy link
Contributor

lberki commented Oct 15, 2019

Do we want to remove the command-line options? I thought --protocopt is something we want to keep indefinitely because it's useful functionality. --proto_compiler should arguably be done in a platformized way, but it'll be a good while until we platformize all of Google and until then so I don't think it makes sense to prepare for its removal.

@Yannic
Copy link
Contributor Author

Yannic commented Oct 15, 2019

When I talked about removing command-line options, I was talking about the native ones in ProtoConfiguration. For those that provide value to users, we'll keep them as Starlark flags (and if we ever get shorthand mapping of flag labels, they'll even have the same name).

The reason I'm submitting this PR is to get the work on rewriting {cc,java}_proto_library started, which obviously need to honor the existing configuration mechanisms, and to allow other proto rules to use these configurations (rather than requiring them to be set on a per-library base, or not allowing configuration at all). I'm unsure about whether inventing something more complicated as this is worth the effort and doing it this feature-detectable way (rather than adding a new native rule) has the advantage that, e.g., go_proto_library, closure_proto_library, gRPC-rules, ..., can adopt it today.

@hlopko
Copy link
Member

hlopko commented Oct 15, 2019

Is this PR about preparing for proto_toolchain? or proto_lang_toolchain? (The former is a desire to be able to use system installed protoc, the later is a desire to specify which plugin to use with which lang_proto_library)

@Yannic
Copy link
Contributor Author

Yannic commented Oct 15, 2019

This is about creating proto_toolchain (but actually using the system installed protoc/runtime is a long way to go).

Copy link
Contributor Author

@Yannic Yannic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some tests and comments. ptal.

return "OFF";

case WARN:
return "WARN";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Today, WARN==ERROR (and DEFAULT==OFF [1], but the default value for --strict_proto_deps is error 🤷‍♀). I'd like proto_library to support WARN eventually, and also print some nice buildozer commands when there are errors or warnings, similar to what Java does.

[1] https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java;l=616?q=areDepsStrict

@Yannic
Copy link
Contributor Author

Yannic commented Nov 28, 2019

@lberki Friendly ping?

@hlopko hlopko removed their request for review November 29, 2019 16:11
@aiuto
Copy link
Contributor

aiuto commented Apr 23, 2020

ping

@Yannic
Copy link
Contributor Author

Yannic commented Apr 23, 2020

Closing in favor of #10937

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes team-Rules-Server Issues for serverside rules included with Bazel
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants