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

nogo with bzlmod and golang.org/x/tools/go/analysis/passes #3993

Closed
albertocavalcante opened this issue Jul 24, 2024 · 1 comment
Closed

Comments

@albertocavalcante
Copy link
Contributor

I didn't fill the template as I'm seeking guidance rather than reporting an issue, but please let me know any other info I should provide.

I am seting up this template that I have to use bzlmod only: https://github.com/albertocavalcante/cli, and right now I am attempting to configure nogo.

By following the "Configuring nogo" step at "Go with Bzlmod" documentation, I was able to setup its target and started with a minimalist configuration that only has vet enabled:

MODULE.bazel

go_sdk.nogo(nogo = "//:cli_nogo")

BUILD.bazel

load("@rules_go//go:def.bzl", "nogo")

nogo(
    name = "cli_nogo",
    vet = True,
    visibility = ["//visibility:public"],
)

It worked! :)

Then, according to the nogo documentation, in order to run all the analyzers from golang.org/x/tools I can use TOOLS_NOGO and that's what I did:

BUILD.bazel

load("@rules_go//go:def.bzl", "nogo", "TOOLS_NOGO")

nogo(
    name = "cli_nogo",
    vet = True,
    visibility = ["//visibility:public"],
    deps = TOOLS_NOGO,
)

Then it incurred into the same issue described at #3592. Ok, I simply removed vet = True and all the analyzers at TOOLS_NOGO executed successfuly.

Now comes my problem, how to I choose only a few analyzers from golang.org/x/tools?

I was taking a look at https://github.com/bazelbuild/bazel-gazelle and noticed it has this setup:

MODULE.bazel

# golang.org/x/tools is not a direct dependency of the go code anymore
# but bazel buildtools and nogo depend on it.
go_deps.module(
    path = "golang.org/x/tools",
    sum = "h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=",
    version = "v0.18.0",
)
use_repo(
    go_deps,
    ...
    "org_golang_x_tools",
    ...
)

BUILD.bazel

load("@io_bazel_rules_go//go:def.bzl", "go_cross_binary", "nogo")

nogo(
    name = "nogo",
    vet = True,
    visibility = ["//visibility:public"],
    deps = ["@org_golang_x_tools//go/analysis/passes/copylock"],
)

That way it only runs copylock, and the way to access org_golang_x_tools was by having a manual go_deps.module entry and add allow it to be accessed with the apparent name @org_golang_x_tools with the use_repo extension, similarly to any direct dependency of the project itself.

I tried to mimic the same behavior and got this error:

$ bazel mod tidy

ERROR: Traceback (most recent call last):
        File "C:/users/alber/_bazel_alber/dyih625r/external/gazelle~/internal/bzlmod/go_deps.bzl", line 309, column 21, in _go_deps_impl
                fail("Duplicate Go module path \"{}\" in module \"{}\".".format(module_tag.path, module.name))
Error in fail: Duplicate Go module path "golang.org/x/tools" in module "cli".
ERROR: error evaluating module extension go_deps in @@gazelle~//:extensions.bzl. Type 'bazel help mod' for syntax and help.                                                                                       
    Fetching module extension go_deps in @@gazelle~//:extensions.bzl; starting 

Am I missing something? So far the only workaround that worked for me was to rely on its canonical name that TOOLS_NOGO uses, as:

nogo(
    name = "cli_nogo",
    vet = True,
    visibility = ["//visibility:public"],
    deps = [
        "@@gazelle~~go_deps~org_golang_x_tools//go/analysis/passes/slog:go_default_library"
    ],
)

But I know this is not sustainable, specially when considered bazelbuild/bazel#22865.

Thanks!

@albertocavalcante
Copy link
Contributor Author

It now worked, in one of my attemps I had done a bazel run @rules_go//go -- get -u golang.org/x/tools which also added it to go.mod and added to go_deps.from_file(go_mod = "//:go.mod") it became duplicated.

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