buildtools icon indicating copy to clipboard operation
buildtools copied to clipboard

allow buildozer to operate on WORKSPACE files

Open nlewycky opened this issue 7 years ago • 15 comments

WORKSPACE files are written in the same format as BUILD files and can be formatted by buildifier. I would like to use buildozer in a script that queries the contents of a WORKSPACE file, uses that output to check for newer upstream versions of the packages, then writes out the updates to the WORKSPACE as buildozer commands.

If I rename my WORKSPACE to BUILD, it works just fine. For example:

$ bazel run //tools:buildozer -- 'print label urls strip_prefix' //:%http_archive
INFO: Analysed target //tools:buildozer (0 packages loaded).
INFO: Found 1 target...
Target //tools:buildozer up-to-date:
  bazel-bin/tools/buildozer
INFO: Elapsed time: 0.460s, Critical Path: 0.00s
INFO: Build completed successfully, 1 total action
rule "//:gmaven_rules" has no attribute "urls"
//:io_grpc_grpc_java [https://github.com/grpc/grpc-java/archive/v1.12.0.tar.gz] grpc-java-1.12.0
//:gmaven_rules (missing) "gmaven_rules-%s" % GMAVEN_TAG
//:com_google_protobuf [https://github.com/google/protobuf/archive/3.5.1.1.zip] protobuf-3.5.1.1
//:com_google_googletest [https://github.com/google/googletest/archive/08d5b1f33af8c18785fb8ca02792b5fac81e248f.zip] googletest-08d5b1f33af8c18785fb8ca02792b5fac81e248f
//:com_github_google_benchmark [https://github.com/google/benchmark/archive/6d74c0625b8e88c1afce72b4f383c91b9a99dbe6.zip] benchmark-6d74c0625b8e88c1afce72b4f383c91b9a99dbe6
//:com_google_absl [https://github.com/abseil/abseil-cpp/archive/59ae4d5a0e833bedd9d7cc059ac15a9dc130e3f7.zip] abseil-cpp-59ae4d5a0e833bedd9d7cc059ac15a9dc130e3f7

Another way to achieve this would be to allow the user to pass in the path to a single BUILD file, though I'm not sure whether buildozer needs to open other BUILD files relative to the first.

nlewycky avatar May 22 '18 17:05 nlewycky

current hack: buildozer does accept input on stdin which it writes to stdout.

Problem if there is a BUILD and WORKSPACE file in //, how does buildozer distinguish? Maybe a distinguishing syntax, like @@xxx where @ is already used to mean this repo, and then after that @ rather than // or : means 'this workspace' followed by the name of the workspace entry. No such standard labeling exists in bazel so it is a stretch.

pmbethe09 avatar May 24 '18 15:05 pmbethe09

If we add a syntax for workspaces I would suggest it have a special name like __workspace__ similar to __pkg__, for instance @workspace//__workspace__:com_google_absl. Thanks for the stdin trick!

nlewycky avatar May 25 '18 01:05 nlewycky

ah, that could work, then it could just be //__workspace__:com_google_absl

@laurentlb what do you think?

pmbethe09 avatar May 25 '18 13:05 pmbethe09

@laurentlb what do you think?

@laurentlb Ping.

JensRantil avatar Jun 18 '19 20:06 JensRantil

Looks good to me. Instead of adding it a special case for WORKSPACE (as proposed), we could also imagine a generic way to refer to any file on the disk.

For example, //foo/bar:baz could mean with either the target baz in foo/bar/BUILD or in foo/bar (if bar is a file and not a directory).

laurentlb avatar Jun 21 '19 21:06 laurentlb

I just recently tested this, and I think this is fixed?

jgavris avatar Jun 26 '20 12:06 jgavris

@jgavris Maybe I'm blind to a recent change but I don't think this is fixed -- can you provide a working example?

sudoforge avatar Aug 28 '20 21:08 sudoforge

@sudoforge My mistake, I actually meant to say that buildifier works on WORKSPACE files. It had not previously and then this was fixed. I haven't tried to use buildozer directly, sorry.

jgavris avatar Sep 08 '20 22:09 jgavris

Bummer, thanks for the heads up.

sudoforge avatar Sep 08 '20 22:09 sudoforge

For the record, it doesn't appear that buildozer supports reading from stdin anymore (I'm unsure if it ever did, except for the earlier comments in this thread):

➜ buildozer 'print urls' //:%http_archive <<< WORKSPACE
<no output>

➜ cat WORKSPACE | buildozer 'print urls' //:%http_archive
<no output>

I'm going to take a stab at solving this using the __workspace__ idea from @nlewycky. This is a pretty necessary feature and would really simplify repository management.

sudoforge avatar Oct 14 '20 04:10 sudoforge

I just found a neat work-around for this.

tmp="$(mktemp -d)"
touch "$tmp/WORKSPACE"
ln WORKSPACE "$tmp/BUILD"
buildozer -root_dir="$tmp" '<buildozer commands>' //:<target>
rm -rf "$tmp"

karlhepler avatar Dec 04 '20 18:12 karlhepler

Yeah, that and similar methods have been the only way to accomplish the goal here thus far. I haven't had time to work on the __workspace__ implementation so far, but will over the next couple of weeks.

sudoforge avatar Dec 04 '20 18:12 sudoforge

This works too, but I'm not sure why I have to use echo. I feel like I should be able to redirect the output directly to WORKSPACE, but it doesn't work.

echo "$(cat WORKSPACE | buildozer '<buildozer commands>' -:<target>)" > WORKSPACE

karlhepler avatar Dec 04 '20 18:12 karlhepler

This works too, but I'm not sure why I have to use echo. I feel like I should be able to redirect the output directly to WORKSPACE, but it doesn't work.

echo "$(cat WORKSPACE | buildozer '<buildozer commands>' -:<target>)" > WORKSPACE

The shell truncates WORKSPACE to zero bytes for writing due to the > WORKSPACE before the cat runs to dump its contents.

nlewycky avatar Dec 04 '20 19:12 nlewycky

Ah. Makes sense. Thanks!

karlhepler avatar Dec 04 '20 19:12 karlhepler

While looking into fixing this issue, I learned that this had already been implemented well before this issue was created: https://github.com/bazelbuild/buildtools/commit/5fa18d247b23dd7a66e4ce5f829fda1d1bf06dc0

The syntax is:

buildozer '<buildozer commands>' WORKSPACE:<target>

More generally, WORKSPACE can be replaced with any file name. A good reminder to add docs when adding features - I will submit a PR.

fmeum avatar Dec 09 '22 08:12 fmeum