Search code examples
bazel

How do I wrap a remote executable in an sh_binary in Bazel?


Suppose I have a tool hosted on an HTTP server. I would like to use this tool in Bazel build rules as an sh_binary.

How do I get Bazel to the following?

  1. Download the tool
  2. Unpack it (it is a zip)
  3. Wrap the executable in an sh_binary
  4. Use the sh_binary in an sh_test or a genrule

So far I have only achieved step (1), which is to fetch the archive:

WORKSPACE

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")

http_file(
  name = "fantomas_nuget",
  sha256 = "98f2604859a377687c9a63b5a0148a47153224f19856142cc20705a96e1ea211",
  urls = [ "https://www.nuget.org/api/v2/package/fantomas/5.0.0-alpha-010" ],
)

Solution

  • Are you using rules_dotnet? It has some tools for using nuget packages: https://github.com/bazelbuild/rules_dotnet/blob/master/docs/nuget2bazel.md

    In particular, this package has two dependencies

    FSharp.Compiler.Service (= 41.0.3)
    FSharp.Core (>= 6.0.3)
    

    I don't know if you get those automatically from the F# runtime environment, but if those are needed, http_file / http_archive won't download those dependencies.

    I notice that this is a code formatter. Note that in general, bazel actions (e.g. genrule and other rule actions) aren't designed to modify the source tree.

    Coincidentally, there was just recently a thread on bazel-discuss that discussed formatters and linters: https://groups.google.com/g/bazel-discuss/c/GXyZkKEzgTE/m/mjvUQS5CAQAJ


    Something like this might get you started:

    WORKSPACE:

    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
      name = "fantomas_nuget",
      type = "zip",
      build_file = "@//:BUILD.fantomas",
      sha256 = "98f2604859a377687c9a63b5a0148a47153224f19856142cc20705a96e1ea211",
      urls = [ "https://www.nuget.org/api/v2/package/fantomas/5.0.0-alpha-010" ],
    )
    

    BUILD.fantomas:

    filegroup(
        name = "fantomas",
        srcs = glob([
            "**/*.dll",
            "**/*.xml",
            "**/*.json",
        ]),
        visibility = ["//visibility:public"],
    )
    

    BUILD:

    sh_binary(
      name = "fantomas",
      srcs = ["fantomas.sh"],
      data = ["@fantomas_nuget//:fantomas"],
    )
    
    sh_test(
      name = "sources_test",
      srcs = ["test_sources.sh"],
      data = [
          "my_fsharp_file",
          ":fantomas",
      ],
      args = ["$(location my_fsharp_file)"],
    )
    

    test_sources.sh:

    echo Running the test
    fantomas $@
    

    fantomas.sh:

    echo args:
    echo $@
    
    echo
    echo find:
    find .
    
    echo
    echo stat:
    stat $@
    
    echo
    echo line count:
    wc -l $@
    

    my_fsharp_file:

    F#