abergmeier
abergmeier

Reputation: 14071

Wrapping py_binary with arguments

A package //foo has a py_binary:

py_binary(
  name = "foo",
  srcs = ["foo.py"],
  visibility = ["//visibility:public"],
)

foo.py accepts 2 positional commandline arguments.

Now in a package //bar I would like to create an "alias" for invoking foo binary with certain arguments.

The following sadly does not work:

py_binary(
  name = "bar",
  deps = [
    "//foo:foo",
  ],
  args = [
    "$(location first_file)",
    "$(location second_file)",
  ],
  data = [
    ":first_file",
    ":second_file",
  ],
)

The problem is that py_binary wants a main src file in the current package. Is there a other or better to make this work?

Upvotes: 3

Views: 1761

Answers (2)

abergmeier
abergmeier

Reputation: 14071

I solved this by creating a //foo:bind.bzl:

def bind_foo(name, **kwargs):
    copy_file(
        name = "%s.py.create" % name,
        src = "//foo:foo.py",
        dst = "%s.py" % name, # Appease local main search
    ) # Why is no copy_file action provided by Skylark???

    py_binary(
        name = name,
        srcs = [
            "%s.py" % name,
        ],
        deps = [
            "//foo:foo",
        ],
        **kwargs
    )

Which in //bar I can simply use:

load("//foo:bind.bzl", "bind_foo")

bind_foo(
    name = "bar",
    args = [
        "$(location first_file)",
        "$(location second_file)",
    ],
    data = [
        ":first_file",
        ":second_file",
    ],
)

This also makes the whole thing more expressive, so yay :)

Upvotes: 2

kris
kris

Reputation: 23591

You have to use the main attribute, e.g.:

py_binary(
  name = "bar",
  main = "//foo:foo.py",
  srcs = ["//foo:foo"],
...

Note that this means you have to expose foo.py in foo/BUILD:

exports_files(["foo.py"])

Upvotes: 0

Related Questions