You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We would like to run rustfmt directly through bazel to check formatting from our CI system. For example: bazel run @io_bazel_rules_rust//:rustfmt --. Is this somehow possible?
@mfarrugi If there is interest in integrating this into this repo, please let me know. It probably won't work if there are thousands of files matched by the glob.
@dae I think that'd be useful to incorporate, but I imagine it probably working as an aspect, similar to the clippy integration. That way you could run:
Another reason for this: tonic_build runs rustfmt on its generated
code. You can turn this off with Builder::format, but this makes
the generated code mega-ugly (5000-character lines with whole submodules
in them). Not the end of the world since it’s gencode, but it’d be much
nicer to just be able to write
my_rule( # genrule, cargo_build_script, etc.
...,
data= ["@io_bazel_rules_rust//:rustfmt"],
)
Without any data dependency, it appears to be implicitly nonhermetic—it
works on my machine but fails on our CI.
Another reason for this: tonic_build runs rustfmt on its generated
code. You can turn this off with Builder::format, but this makes
the generated code mega-ugly (5000-character lines with whole submodules
in them). Not the end of the world since it’s gencode, but it’d be much
nicer to just be able to write
my_rule( # genrule, cargo_build_script, etc.
...,
data= ["@io_bazel_rules_rust//:rustfmt"],
)
You can already do this in the platform-specific toolchains, we make executable targets like @rust_darwin_x86_64//:rustfmt in
Yep! I saw that, indeed. But directly depending on a platform-specific
target like @rust_linux_x86_64//:rustfmt would of course make the
build itself non-portable, and I’d like to avoid that.
ERROR: .../BUILD:6:19: in _build_script_run rule //common:build_script: label '@rust_linux_x86_64//:rustfmt' in $(location) expression expands to more than one file, please use $(locations @rust_linux_x86_64//:rustfmt) instead. Files (at most 5 shown) are: [bazel-out/k8-fastbuild/bin/external/rust_linux_x86_64/rustfmt, external/rust_linux_x86_64/bin/rustfmt]
However using locations as suggested would result in passing an env var looking like RUSTFMT="bazel-out/k8-fastbuild/bin/external/rust_linux_x86_64/rustfmt external/rust_linux_x86_64/bin/rustfmt" which doesn't work when the env var is expected to be a single path to the executable. Have I missed something about how to set this up?
It seems worth noting as well that the protoc execpath is a full path, not just a partial relative path, e.g /home/vagrant/.cache/bazel/_bazel_vagrant/71ed060a30795ab0736b520a305b19cd/sandbox/linux-sandbox/897/execroot/__main__/bazel-out/k8-fastbuild/bin/external/com_google_protobuf/protoc
ERROR: .../BUILD:6:19: in _build_script_run rule //common:build_script: label '@rust_linux_x86_64//:rustfmt' in $(location) expression expands to more than one file, please use $(locations @rust_linux_x86_64//:rustfmt) instead. Files (at most 5 shown) are: [bazel-out/k8-fastbuild/bin/external/rust_linux_x86_64/rustfmt, external/rust_linux_x86_64/bin/rustfmt]
However using locations as suggested would result in passing an env var looking like RUSTFMT="bazel-out/k8-fastbuild/bin/external/rust_linux_x86_64/rustfmt external/rust_linux_x86_64/bin/rustfmt" which doesn't work when the env var is expected to be a single path to the executable. Have I missed something about how to set this up?
Interesting - can you try either @rust_linux_x86_64//:rustfmt_bin or @rust_linux_x86_64//:bin/rustfmt instead?
It seems worth noting as well that the protoc execpath is a full path, not just a partial relative path, e.g /home/vagrant/.cache/bazel/_bazel_vagrant/71ed060a30795ab0736b520a305b19cd/sandbox/linux-sandbox/897/execroot/__main__/bazel-out/k8-fastbuild/bin/external/com_google_protobuf/protoc
Yeah, this is expected - build scripts run in $CARGO_MANIFEST_DIR instead of the exec root, to maximise compatibility with cargo, so we need to use absolute paths because execpaths would be relative to the wrong directory. The alternative is to run build scripts in the exec root, but then most build scripts which try to read files will be broken - both options are bad :)
Activity
mfarrugi commentedon Aug 7, 2020
It should be somewhere under the toolchain repository (
@rust_linux_x86_64//...).dae commentedon Oct 20, 2020
Here are some simple cross-platform rules you can use. Put the following in a .bzl file:
Then you can add the following to your BUILD:
To check if your files are formatted:
To fix any files that are formatted incorrectly:
@mfarrugi If there is interest in integrating this into this repo, please let me know. It probably won't work if there are thousands of files matched by the glob.
dfreese commentedon Oct 22, 2020
@dae I think that'd be useful to incorporate, but I imagine it probably working as an aspect, similar to the clippy integration. That way you could run:
bazel build --aspects=@io_bazel_rules_rust//rust:rust.bzl%rust_rustfmt_aspect //...
dfreese commentedon Oct 22, 2020
Otherwise I see it being difficult to manage the editions, and the number of files.
wchargin commentedon Nov 12, 2020
Another reason for this:
tonic_buildrunsrustfmton its generatedcode. You can turn this off with
Builder::format, but this makesthe generated code mega-ugly (5000-character lines with whole submodules
in them). Not the end of the world since it’s gencode, but it’d be much
nicer to just be able to write
Without any data dependency, it appears to be implicitly nonhermetic—it
works on my machine but fails on our CI.
illicitonion commentedon Nov 12, 2020
You can already do this in the platform-specific toolchains, we make executable targets like
@rust_darwin_x86_64//:rustfmtinrules_rust/rust/repositories.bzl
Lines 248 to 254 in f33e3b3
wchargin commentedon Nov 13, 2020
Yep! I saw that, indeed. But directly depending on a platform-specific
target like
@rust_linux_x86_64//:rustfmtwould of course make thebuild itself non-portable, and I’d like to avoid that.
illicitonion commentedon Nov 13, 2020
We could maybe add to
io_bazel_rules_rustsomething along the lines of:so that there's a single target you can point at which acts differently depending on your platform?
djmarcin commentedon Nov 22, 2020
@rust_linux_x86_64//:rustfmtdoes not seem to work currently, because it resolves to multiple paths.However using
locationsas suggested would result in passing an env var looking likeRUSTFMT="bazel-out/k8-fastbuild/bin/external/rust_linux_x86_64/rustfmt external/rust_linux_x86_64/bin/rustfmt"which doesn't work when the env var is expected to be a single path to the executable. Have I missed something about how to set this up?It seems worth noting as well that the protoc execpath is a full path, not just a partial relative path, e.g
/home/vagrant/.cache/bazel/_bazel_vagrant/71ed060a30795ab0736b520a305b19cd/sandbox/linux-sandbox/897/execroot/__main__/bazel-out/k8-fastbuild/bin/external/com_google_protobuf/protocillicitonion commentedon Nov 24, 2020
Interesting - can you try either
@rust_linux_x86_64//:rustfmt_binor@rust_linux_x86_64//:bin/rustfmtinstead?Yeah, this is expected - build scripts run in $CARGO_MANIFEST_DIR instead of the exec root, to maximise compatibility with cargo, so we need to use absolute paths because execpaths would be relative to the wrong directory. The alternative is to run build scripts in the exec root, but then most build scripts which try to read files will be broken - both options are bad :)
djmarcin commentedon Nov 24, 2020
Thanks --
@rust_linux_x86_64//:bin/rustfmtis not visible, but@rust_linux_x86_64//:rustfmt_binworks 👍UebelAndre commentedon Nov 24, 2020
I love the idea of a
rustfmttarget. I'd expect it to work similar to buildifier if possible though 😅damienmg commentedon Dec 1, 2020
This is a dupe of #87. Closing in favor of the one that has the most history.