Skip to content

Add Bazel Run/Debug Support to GoTestRunner #2539

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

Open
mnoah1 opened this issue Nov 18, 2022 · 10 comments
Open

Add Bazel Run/Debug Support to GoTestRunner #2539

mnoah1 opened this issue Nov 18, 2022 · 10 comments

Comments

@mnoah1
Copy link

mnoah1 commented Nov 18, 2022

Is your feature request related to a problem? Please describe.
Our team uses Bazel with our Go projects. Currently, this extension is able to discover tests but the run/debug functionalities do not work correctly since they run go commands instead of Bazel.

Describe the solution you'd like
Allow customizable user option to use Bazel to run/debug tests. Override a few of the methods in GoTestRunner with an alternate implementation that runs the Bazel version of the needed command. Add parsing of Bazel build events to report pass/fail status.

Describe alternatives you've considered

  1. Add this to the Bazel for VS Code extension - not ideal because that extension is more focused on Starlark / BUILD file creation, and does not offer language-specific Go support or integration with VS Code's testing API.
  2. Create a separate extension that depends on several of the classes in this vs-code extension, and sets up an alternate version of the GoTestExplorer with the missing Bazel functionality. Users that wish to use this functionality could then turn off the test explorer setting on this extension, then run the separate extension side-by-side with this one. Not ideal due to the overhead of maintaining a separate extension / project where only a few areas of functionality actually differ.

Additional context
Would also be open to any other general feedback about how other teams are supporting Run/Debug functionality in the IDE for Bazel users (other than command line, which is our current state).

@gopherbot gopherbot added this to the Untriaged milestone Nov 18, 2022
@jamalc
Copy link
Contributor

jamalc commented Nov 22, 2022

/cc @hyangah for any feedback on supporting run/debug for Bazel.

@jamalc jamalc modified the milestones: Untriaged, vscode-go/unplanned Nov 22, 2022
@mnoah1
Copy link
Author

mnoah1 commented Jan 12, 2023

@hyangah @jamalc - Just wanted to see if you have any feedback on this issue? We have a working version on our fork and wanted to confirm that you would be interested in having me submit a PR?

@oakad
Copy link

oakad commented Apr 13, 2023

Interestingly enough, this need not be a bazel specific thing. Rather, vscode-go could be made a somewhat more flexible:

  1. vscode-go could add an ability to run a command via launch.json config, while having a desired DAP address in a well known environment variable. It should also be able to wait a little for the server to become available at the specified DAP address (instead of bailing out immediately, like it is doing now). This will allow people to define simple actions of the form bazel run run_under="dlv -l $MY_DAP_ADDR --headless exec" -c dbg //bazel/target -- args. Should not be difficult to implement, will take care of the most pressing need.
  2. Symbol path substitution: also should not be too big of a deal. bazel info output_base will return a path for the bazel build dir. vscode-go should simply provide a hook allowing to invoke this sort of pre-launch task and an ability to produce a bunch of substitute-path items out of it.

To my opinion, making vscode-go work with bazel like build system does not seem like a major undertaking and it's a pity something like this was not done already.

@guw
Copy link

guw commented Mar 27, 2025

I believe we are seeing this issue too. @oakad @mnoah1 Was there any activity on your end to fix this? Anything to share in a draft PR or fork? 🙏

@bluec0re
Copy link

We implemented small wrappers around go and dlv, which will be called by vscode instead of the actual binaries. These wrappers then call bazel with the correct arguments to discover and build artifacts and in the dlv case, forward them to dlv for debugging.

With this, we're able to debug mains and tests (mostly) without issues. Direct support in either this extension or rules_go would be nice though.

Here is for example what I wrote for dlv: https://gist.github.com/bluec0re/af19ded857749fd2ec145f4e06f0e9b3

@csobrinho
Copy link

We implemented small wrappers around go and dlv, which will be called by vscode instead of the actual binaries. These wrappers then call bazel with the correct arguments to discover and build artifacts and in the dlv case, forward them to dlv for debugging.

With this, we're able to debug mains and tests (mostly) without issues. Direct support in either this extension or rules_go would be nice though.

Here is for example what I wrote for dlv: https://gist.github.com/bluec0re/af19ded857749fd2ec145f4e06f0e9b3

Thanks, this is very useful for anyone affected by this. Any chance you could also provide the go.py?

Thanks

@mnoah1
Copy link
Author

mnoah1 commented Mar 28, 2025

We ended up using a fork. This is a bit out of date (https://github.com/uber/vscode-go) but we keep it up to date internally - basically using a modified version of the GoTestExplorer that parses executes via Bazel and then parses the build events. I'm also curious to see what the wrapped Go command above looks like. We took this approach a couple of years ago because there were other issues (such as different output paths for coverage files, parsing the test.xml results from build events, selecting correct flags/test filter formatting) that seem like they might be a bit hard to fully control by just overriding go.

On a related note, @firelizzard18 has been doing some ongoing work to move test discovery into gopls (https://github.com/golang/vscode-go/blob/master/docs/experiments.md#test-explorer, #2504 (comment)) - I have not had a chance to try it out yet but maybe there is opportunity there as well to add some kind of integration point that defers to Bazel and then receives a response in some standard format (thinking something similar to how gopls is able to use gopackagesdriver to request package info, maybe there is possibility to let users to provide their own test executor that can receive/return responses in some standard format and provide a way to delegate the run to Bazel.

cc @firelizzard18

@firelizzard18
Copy link
Contributor

I am open to contributions to Go Companion. If you do contribute, please keep in mind that the eventual goal is to merge my extension (or at least the test explorer system) into vscode-go, so contributions will be held to that standard.

something similar to how gopls is able to use gopackagesdriver to request package info

That would be ideal; however while the gopls team and I have discussed leaning on gopls for test execution that hasn't gotten much past "it would be neat". My point is, currently execution of tests is 100% handled by vscode-go and has nothing to do with gopls. The only way in which the test system interacts with gopls is that the newest version (Go Companion) uses gopls for discovery. So it would be admittedly elegant and powerful if we used something like gopackagesdriver, but that would be a long term project, not something that could get completed in a couple weeks.

If someone wants to work on it today, here is the code; specifically spawnProcess and debugProcess, used for running and debugging tests, respectively. Though they did just recently get more complicated because I added support for treating //go:generate go run ... as tests mostly because for myself because I want it to be easier to debug those. If bazel has a command with the same semantics as go test ... or if there's an easy way to convert flags, updating spawnProcess might not be too hard. I don't know how easy it will be to update debugProcess to use bazel, but I've also never tried to use bazel for anything.

@oakad
Copy link

oakad commented Mar 31, 2025

On my side, I've got a bazel rule + go helper binary. The helper binary diffs and edits the "launch.json" file in the ".vscode" dir under the workspace it's working in. So it's a 2 step process: 1. "run" the appropriate bazel rule. 2. "click" on the magically prepared job in vscode.

@bluec0re
Copy link

@csobrinho I updated the gist with the missing files

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

No branches or pull requests

8 participants