Skip to content

Instantly share code, notes, and snippets.

@johnynek
Last active January 19, 2018 01:36
Show Gist options
  • Save johnynek/b437cc702774106b338393eb180c7e55 to your computer and use it in GitHub Desktop.
Save johnynek/b437cc702774106b338393eb180c7e55 to your computer and use it in GitHub Desktop.

Simple Bazel Rule for Graphviz

Use rules_nixpkgs to get graphviz:

Make sure you have nix-build installed from nix then add the following to WORKSPACE:

http_archive(
    name = "io_tweag_rules_nixpkgs",
    strip_prefix = "rules_nixpkgs-53700e429928530f1566cfff3ec00283a123f17f",
    urls = ["https://github.com/tweag/rules_nixpkgs/archive/53700e429928530f1566cfff3ec00283a123f17f.tar.gz"],
)

load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository", "nixpkgs_package")

nixpkgs_git_repository(
  name = "nixpkgs",
  revision = "17.09",
)

nixpkgs_package(
    name = "graphviz",
    repository = "@nixpkgs",
    build_file_content = """
package(default_visibility = [ "//visibility:public" ])
exports_files([
  "nix/bin/dot",
  "nix/bin/neato",
])

filegroup(
  name = "bin",
  srcs = glob(["nix/bin/*"]),
)

filegroup(
  name = "lib",
  srcs = glob(["nix/lib/**/*.so"]),
)
""")

to your WORKSPACE. This uses rules_nixpkgs to build dot, a command we will use below.

Make a simple wrapper for a genrule

put the following in the root directory in graphviz.bzl, and make sure there is a BUILD file in that directory (even if it is empty).

def graphviz(name, src):
  native.genrule(
    name = name,
    srcs = [src],
    outs = [name + ".png"],
    tools = ["@graphviz//:nix/bin/dot"],
    cmd = "$(location @graphviz//:nix/bin/dot) $(location {src}) -Tpng > $@".format(src = src))

Call the rule:

add the following to a BUILD file (say at the root of your project).

load("//:graphviz.bzl", "graphviz")

graphviz(
    name = "dot_example",
    src = "foo.dot")

Now add a simple foo.dot in the root, say:

graph {
    a -- b;
    b -- c;
    a -- c;
    d -- c;
    e -- c;
    e -- a;
}

now run:

bazel build :dot_example.png

which should print out:

INFO: Analysed target //tests:dot_example (0 packages loaded).
INFO: Found 1 target...
Target //tests:dot_example up-to-date:
  bazel-genfiles/tests/dot_example.png
INFO: Elapsed time: 0.601s, Critical Path: 0.45s
INFO: Build completed successfully, 2 total actions

or something similar. Now open your new png.

Of course, the source of the dot can also be the output of another rule, and of course caching works on these rules, so if the input does not change, you won't re-run graphviz.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment