(Tangentially related to <this discussion> about p...
# general
b
(Tangentially related to this discussion about programmatically modifying BUILD files by running Buildifier on them) Follow-up from this discussion about the lowest-bar way to introduce Pants for linting/formatting. šŸ§µ
The top-level
BUILD
file had a few bumps, so I got clever and sliced our repo another way.
Introducing
pants-plugins/bazel-compat-macros.py
Copy code
# Macros for Bazel defintions
def alias(*args, **kwargs): ...
def genrule(*args, **kwargs): ...
def exports_files(*args, **kwargs): ...
def load(*args, **kwargs): ...
def requirement(arg): ...
# ... you get the idea ;)
def glob(*args, **kwargs): return []

# Ones we do care about
def py_library(**kwargs):
    srcs = kwargs.get("srcs", [])
    if srcs:
        return python_sources(name=kwargs["name"], sources=srcs)

def py_test(**kwargs):
    srcs = kwargs.get("srcs", [])
    if srcs:
        return python_sources(name=kwargs["name"], sources=srcs)
Then to do the other side:
Copy code
# In pants-compat.bzl
def python_requirements(**kwargs):
  pass
And finally, the top-level
BUILD
Copy code
load("//:pants-compat.bzl", "python_requirements")

package(default_visibility = ["//visibility:public"])

# Bazel stuff

python_requirements(
    module_mapping = {
        "absl-py": ["absl"],
        # ...
    },
)
Now Pants will pick up on all my files already known to Bazel šŸŽ‰
šŸ˜ˆ
c
Hahaā€¦ thatā€™s awesome! šŸ˜„
šŸ™Œ 1
b
It works for format, going to try and finagle it for
lint
I'm wondering if Pants should maybe have a "ignore-unrecognized-definitions" option for this use case. šŸ¤” We'll have to see how it pans out for: ā€¢ linting (w.r.t. deps) ā€¢ when we want to incrementally migrate to using
pants
for more than format/linting/checking
@hundreds-father-404 who seems to be my sounding board for crazy ideas šŸ¤“
c
maybe have a ā€œignore-unrecognized-definitionsā€ option
is it too many definitions to ā€œstubā€ out with macros? or are there other constructs that doesnā€™t map to a macro syntactically ?
b
No, and actually now that I think about it, it's likely a bad idea. Take a look at my definition for
glob
For
lint
, it's much more complicated šŸ˜‚ . Bazel is cool with double-ownership, but Pants not so much
The jist of the issue is that some of our
py_binary
rules are used in
py_test
, but declare
srcs=[...]
for their sources. But there may or may not be a
py_library
which also has the declared
srcs
, leading to ambiguous ownership. The solution is to scrub the `py_binary`s that use an already-owned
py_library
to use the
:foo/bar
syntax instead of declaring ownership
I think I'm going to make Bazel error if
py_binary
contains an actual src in
srcs
, and then
py_binary
is empty to Pants
Copy code
def py_binary(
    srcs = [],
    **kwargs
):
    for src in srcs:
        if src.endswith(".py"):
            # This is valid Bazel, but for Pants-compat to work, each src should be owned
            # once-and-only-once. And the easiest way to do that is throught `py_library`.
            fail(
                "`py_binary` cannot claim a Python src. Use `py_library` instead and depend on it.\n\n"
                + "E.g. declare:\n\n"
                + "py_library(\n"
                + '  name = "{}",\n'.format(src[:-3])
                + '  srcs = ["{}"],\n'.format(src)
                + ")\n\n"
                + 'Then set the `py_binary` `srcs` attribute to ":{}"'.format(src[:-3])
            )
    _py_binary(
        srcs=srcs,
        **kwargs,
    )