Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buildozer fails to find targets that are macros with a return value assigned to a variable #1306

Open
mattnworb opened this issue Nov 14, 2024 · 0 comments

Comments

@mattnworb
Copy link

I'm not sure if this is an actual bug or we are doing something weird, but I've found that if we have a BUILD file with a target which is a macro that returns a value (such as a struct, with the names of a few internally instantiated targets), then a command like buildozer 'print label srcs' //foo will print an error that the rule cannot be found, even if buildozer 'print label srcs' //foo:* shows that the rule exists.

I created a repo which reproduces the issue: https://github.com/mattnworb/buildozer-macro-return-issue

For instance, in //hello-world/BUILD.bazel, there is a target that creates a java_binary via a macro:

macro_java_binary(
    name = "hello-world",
    srcs = ["src/main/java/com/mattnworb/example/Main.java"],
    main_class = "com.mattnworb.example.Main",
)
❯ buildozer 'print label srcs' //hello-world
//hello-world [src/main/java/com/mattnworb/example/Main.java]

but if the macro is made to return something, and that value is assigned to a variable in the BUILD.bazel file, then buildozer can no longer find the rule/target:

foo = macro_java_binary(
    name = "hello-world",
    srcs = ["src/main/java/com/mattnworb/example/Main.java"],
    main_class = "com.mattnworb.example.Main",
)
❯ buildozer 'print label srcs' //hello-world
/Users/mattbrown/code/buildozer-issue-repro/hello-world/BUILD.bazel: error while executing commands [{[print label srcs]}] on target //hello-world: rule 'hello-world' not found

even though buildozer can execute the command against the target in question, when expanding wildcards:

❯ buildozer 'print label srcs' //hello-world:*
//hello-world [src/main/java/com/mattnworb/example/Main.java]

I think a part of the issue is that

buildtools/edit/edit.go

Lines 295 to 325 in be1c24c

func IndexOfRuleByName(f *build.File, name string) (int, *build.Rule) {
linenum := -1
if strings.HasPrefix(name, "%") {
// "%<LINENUM>" will match the rule which begins at LINENUM.
// This is for convenience, "%" is not a valid character in bazel targets.
if result, err := strconv.Atoi(name[1:]); err == nil {
linenum = result
}
}
for i, stmt := range f.Stmt {
call, ok := stmt.(*build.CallExpr)
if !ok {
continue
}
r := f.Rule(call)
start, _ := call.X.Span()
if r.Name() == name || start.Line == linenum {
return i, r
}
// Allow for precisely targeting the package declaration. This
// helps adding new load() and license() rules
if name == "__pkg__" {
if rule, ok := ExprToRule(stmt, "package"); ok {
return i, rule
}
}
}
return -1, nil
}
only examines nodes in the BUILD file AST which are CallExpr, and assigning the return value of a macro (which I can't tell is an unorthodox thing to do?) changes that node to an AssignExpr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant