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

Standardizing the shape of a rule set #6

Open
gravypod opened this issue Oct 19, 2021 · 6 comments
Open

Standardizing the shape of a rule set #6

gravypod opened this issue Oct 19, 2021 · 6 comments

Comments

@gravypod
Copy link
Member

One of the goals of Bazel is to abstract users from the specific toolchains underpinning the implementation of rules. Does it make sense for us to establish standardized functionality that rules should provide? For example:

  1. Should all rules for languages provide a *_binary, *_library, *_test? What about in languages where this doesn't exactly map to the real contents (ex: jsonnet's binary is a json file).
  2. Some things need 100% global support to be useful. We can either have one repo that needs to support all languages (impossible to keep up maintenance on, see: bazelbuild/rules_docker) or every language ruleset needs to implement something they aren't an expert in. Examples of this: should we require *_proto_library and *_grpc_library? What about *_thrift_library? etc

If we decide to go down this path we also need to remember:

  1. We shouldn't exclude rules from this group if they are not 100% ready. This will make it a hard value prop to try and open source internal rules from companies: "You want to spend how much time and have no guarantee they will help maintain this?"
  2. We should make 100% compliance something that a single person could implement and maintain.
@alexeagle
Copy link
Contributor

I think the style guide at https://docs.bazel.build/versions/main/skylark/deploying.html mostly dictates this.

But I could take this issue to suggest that we do more to maintain the style guide for rules authors. It's something the Bazel tech writers have thought about as well.

@aherrmann
Copy link
Member

Agreed, the style guide seems like a good place for things like providing _binary, _library, _test rules.
As you already point out, there are cases where this set is not applicable. There should be a way to handle such exceptions, such that those rule sets don't end up being permanently non-compliant.

Aside from naming, there are other, more subtle, aspects to writing rules such that they fulfill the goal to abstract the specifics of the language toolchain and provide a familiar interface to a Bazel user, e.g.

  • Cross language dependencies where it makes sense, e.g. depending on cc_library targets for a C foreign function interface.
  • Proper handling of runtime dependencies in a data attribute and a corresponding runfiles library.
  • Support for location expansion where it makes sense, e.g. compiler-flags attributes.
  • Whether <lang>_binary can be used as a build tool in a genrule or another custom rule, or whether it can be invoked as a data dependency of another _binary target.

I'm not sure that this can be meaningfully quantified for any given rule set. But, a style-guide or compatibility check-list may be a feasible way to document this.


2. Some things need 100% global support to be useful. We can either have one repo that needs to support all languages (impossible to keep up maintenance on, see: bazelbuild/rules_docker) or every language ruleset needs to implement something they aren't an expert in.

This is a tricky issue. rules_nixpkgs is in a similar situation, where we provide repo-rules for language toolchains provided by the Nix package manager. As I understand this will become more difficult with the upcoming Bazel modules as they don't support conditional dependencies. E.g. if rules_nixpkgs wants to provide a Go toolchain it will need to unconditionally depend on rules_go or if rules_haskell wants to provide Nix integration it will need to unconditionally depend on rules_nixpkgs. A way around this may be to define dedeciated mini-rule-sets, e.g. rules_nixpkgs_go, rules_nixpkgs_haskell, .... But, this is quite noisy.

As you point out, mandating that either side covers all cases seems infeasible. Perhaps a more feasible approach is to document a matrix with language rule set on one axis and things like proto, grpc, ... on the other where the cells document where the corresponding implementation is provided.

@brentleyjones
Copy link

A way around this may be to define dedeciated mini-rule-sets, e.g. rules_nixpkgs_go, rules_nixpkgs_haskell, .... But, this is quite noisy.

I actually like this route, as rules_nixpkgs or rules_nixpkgs_support (similar to https://github.com/bazelbuild/apple_support) can be the core, and rules_nixpkgs_go can be the glue between it and rules_go. It reduces the size/scope of rules_nixpkgs, and plays better with Bzlmod's compatibility_level.

@alexeagle
Copy link
Contributor

We could take a page like https://docs.bazel.build/versions/main/skylark/deploying.html and update from there.

@alexeagle
Copy link
Contributor

It looks like there's movement from the Bazel team at Google on this: bazelbuild/proposals#247

@alexeagle
Copy link
Contributor

Note, the upstream docs are being extended: bazelbuild/bazel#15800

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants