Rule to call other rules

2,714 views
Skip to first unread message

Trevor Radcliffe

unread,
Jan 6, 2020, 1:24:25 PM1/6/20
to bazel-...@googlegroups.com
Hello!

I know Google generally doesn’t use Blaze/Bazel for linting, but I have seen conflicting opinions online and don’t necessarily understand why. I was looking into doing so for our NodeJS project. The main motivations here are twofold:
  • Ideally, all major tasks (lint/build/test/maybe deploy) would be done using the same interface in every project/language. I think Bazel is great for this.
  • Package.json sucks. I’d like to have a better way to define my build/test/lint scripts in a modular way that allows me to separate out common scripts to packages used by multiple projects and have more/clearer control over the process. The main things I want more control over are
    • Dependencies
    • Sources to lint
    •  Formatting of the script definitions
    • COMMENTS!!!

Now, using Bazel for linting is not a hill I will die on. I could be convinced that it is a bad idea, and accept that maybe I just don’t fully understand the reasoning yet. All I really got for arguments against is that a build system should only be used for producing build artifacts, but I don’t really see why that matters. I also would argue that, if that were the case, wouldn’t it also not be used for testing or deployment? Anyway, if someone wants to provide arguments either way, I’m all ears, but would also like to hear more about how this could be done.

Thanks!

Trevor Radcliffe

unread,
Jan 6, 2020, 1:32:05 PM1/6/20
to bazel-...@googlegroups.com
I guess I should have either made this question about linting or actually stated the question I have about the subject line! I actually already have some idea of how to run eslint using nodejs_binary, but would love any tips or gotchas anyone has for that.

Anyway, I want to know how to write a rule that will simply call other rules. The motivation here is that I want individual rules for eslint/stylelint/prettier, but I also want a combined rule that calls all of them. I know there is no built in rule for this, but I would love some tips on how to create such a rule. I haven’t really gotten too deep into how to create bazel rules yet, so I’m not really sure where to start.

Thanks again!

Brian Silverman

unread,
Jan 6, 2020, 2:36:06 PM1/6/20
to Trevor Radcliffe, bazel-...@googlegroups.com
Hi,

macro is the way to "bundle" multiple rule instantiations together. It's not a rule, so you can't tell what select evaluates to, or look at providers, etc. For just calling several rules with the same set of source files, a macro will work well.

If you want to do anything more sophisticated (filtering source files by extension, for example), I've found combing a macro with a custom rule to be a powerful combination. The rule can do the complex filtering, and coordinate with the macro which instantiates other rules with the relevant attribute values.

I don't have much to say about the broader questions around linting.

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/50776521-6A31-49BB-94F4-27FB6A1DA9AB%40nextraq.com.

Trevor Radcliffe

unread,
Jan 7, 2020, 10:36:13 AM1/7/20
to Brian Silverman, bazel-...@googlegroups.com
Hey Brian,

Thanks for the reply! I’m trying out your macro solution, but I’m having trouble getting it to actually run all of the targets specified by the macro…I’m only able to run individual targets created by instantiating the macro; not all of them together.

I’m also running into an issue where it’s saying spaces in filenames are an issue, but this only occurs when I use the macro (i.e., if I use the same target specified normally, the issue does not appear).

Any thoughts on any of this?

This email was screened for spam and malicious content but exercise caution anyway.

Mikhail Mazursky

unread,
Jan 7, 2020, 9:43:55 PM1/7/20
to Trevor Radcliffe, bazel-...@googlegroups.com
Hi Trevor,

I've used nogo from rules_go (https://github.com/bazelbuild/rules_go/blob/master/go/nogo.rst) for linting Go code and it works well and is probably the way linting should work in bazel. It's incremental and results are cacheable. I don't see why linting with/via bazel is a bad idea. As with e.g. compilation, why lint the same code more than once (if no inputs to the linting action have changed)?
 
Before nogo became available I've built a runner for gometalinter (a Go linter aggregator) that is not "bazel-native". And then folks contributed similar runners for other Go linters. Have a look at:
https://github.com/atlassian/bazel-tools/tree/master/golangcilint
https://github.com/atlassian/bazel-tools/tree/master/gometalinter
https://github.com/atlassian/bazel-tools/tree/master/gorevive

They are all hacks in a way. They have assumptions about file/directory/project layout and, even though they worked for my use case, they are not going to work e.g. with Go modules in non-vendoring mode or with bazel-managed dependencies in the state they are in as of today.

As for running other rules, have a look at https://github.com/atlassian/bazel-tools/tree/master/multirun. Maybe you can learn or borrow something from it.

Cheers,
Mikhail.

Trevor Radcliffe

unread,
Jan 9, 2020, 9:58:37 AM1/9/20
to Mikhail Mazursky, bazel-...@googlegroups.com
Thanks Mikhail! This is exactly what I was looking for!

Reply all
Reply to author
Forward
0 new messages