Skip to content

fix(builtins): use workspace_indicator for Go package-level analysis tools#803

Merged
jdx merged 3 commits intomainfrom
fix/go-builtins-multi-package
Apr 5, 2026
Merged

fix(builtins): use workspace_indicator for Go package-level analysis tools#803
jdx merged 3 commits intomainfrom
fix/go-builtins-multi-package

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 5, 2026

Summary

  • Switches 7 Go package-level analysis builtins (go_vet, golangci_lint, go_sec, go_vuln_check, staticcheck, revive, err_check) from {{ files }} to workspace_indicator = "go.mod" with ./...
  • Go tools using go/packages fail with "named files must all be in one directory" when files span multiple packages — this is a Go toolchain constraint, not a bug in any linter
  • File-level formatters (go_fmt, go_fumpt, go_imports, go_lines) are unchanged as they don't need package context
  • Adds bats integration tests verifying workspace_indicator behavior for Go builtins

Fixes #802

Test plan

🤖 Generated with Claude Code


Note

Medium Risk
Changes how several Go builtins invoke analyzers by switching from file-list execution to module-wide ./... runs, which can alter coverage/performance and step results in monorepos. Adds new builtin test/tool-stub infrastructure, but the changes are contained to builtin definitions and test scaffolding.

Overview
Updates Go package-level builtin steps (go_vet, golangci_lint, go_sec, go_vuln_check, staticcheck, revive, err_check) to run from the detected Go module root via workspace_indicator = "go.mod" and execute against ./... instead of passing {{files}}.

Adds pkl-level tests for go_vet (including a multi-package case) and introduces mise tool stubs under test/builtin_tool_stubs/ for Go and several Go linters/scanners. Documentation in CLAUDE.md is expanded with guidance on writing/running builtin tests and using tool stubs.

Reviewed by Cursor Bugbot for commit aa8c16b. Bugbot is set up for automated code reviews on this repo. Configure here.

…tools

Go tools that use go/packages internally (go vet, golangci-lint, gosec,
govulncheck, staticcheck, revive, errcheck) fail when {{ files }} expands
to paths spanning multiple packages, because go list requires all named
files to be in one directory. Switch these builtins to use
workspace_indicator = "go.mod" with ./... instead of {{ files }}.

File-level formatters (gofmt, gofumpt, goimports, golines) are unchanged
as they operate on individual files without needing package context.

Fixes #802

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 5, 2026

Greptile Summary

Fixes the "named files must all be in one directory" error that occurs when Go package-level analysis tools receive files spanning multiple packages. Seven Go analysis builtins are switched from passing {{ files }} directly to each tool, to using workspace_indicator = "go.mod" and cd {{workspace}} && <tool> ./..., correctly operating at the module level. File-level formatters (go_fmt, go_fumpt, go_imports, go_lines) are intentionally left unchanged.

  • 7 builtins updated (go_vet, golangci_lint, go_sec, go_vuln_check, staticcheck, revive, err_check): each now sets workspace_indicator = "go.mod" and runs cd {{workspace}} && <tool> ./...
  • Pkl-level tests added to go_vet covering a valid single-package file, an invalid file (unused import "fmt" triggers a compile error that go vet catches), and a multi-package workspace — these run via test/builtins_tests.bats
  • Five new tool stubs added in test/builtin_tool_stubs/ (go, golangci-lint, gosec, revive, staticcheck) to support on-demand tool installation during test runs
  • CLAUDE.md updated with a "Testing Builtins" section documenting the Pkl tests field, tool stubs, and the 4-step workflow for adding new builtins with tests

Confidence Score: 5/5

Safe to merge — all 7 builtins receive the same correct workspace-scoped fix with no logic errors or regressions

No P0 or P1 issues found. The root cause (Go toolchain rejecting multi-directory file lists) is well-understood and the fix is the canonical approach used across Go tooling. The only remaining gap is that 6 of 7 changed builtins lack Pkl-level tests, but this was already flagged in a prior review thread and does not affect the correctness of the changes.

No files require special attention; all changes are consistent and well-scoped

Important Files Changed

Filename Overview
CLAUDE.md Adds Testing Builtins documentation covering Pkl-level tests, tool stubs, and the workflow for new builtins
pkl/builtins/go_vet.pkl Switches to workspace_indicator+./... and adds three Pkl-level tests (good file, bad file, multi-package)
pkl/builtins/golangci_lint.pkl Switches both check and fix commands to workspace_indicator+./... pattern
pkl/builtins/go_sec.pkl Switches gosec from per-file to workspace_indicator+./... pattern
pkl/builtins/go_vuln_check.pkl Switches govulncheck from per-file to workspace_indicator+./... pattern
pkl/builtins/revive.pkl Switches revive from per-file to workspace_indicator+./... pattern
pkl/builtins/staticcheck.pkl Switches staticcheck from per-file to workspace_indicator+./... pattern
pkl/builtins/err_check.pkl Switches errcheck from per-file to workspace_indicator+./... pattern
test/builtin_tool_stubs/go New mise tool-stub pinning Go 1.25 for builtin test runs
test/builtin_tool_stubs/golangci-lint New mise tool-stub for golangci-lint v2 via aqua:golangci/golangci-lint
test/builtin_tool_stubs/gosec New mise tool-stub for gosec v2 via aqua:securego/gosec
test/builtin_tool_stubs/revive New mise tool-stub for revive v1 via aqua:mgechev/revive
test/builtin_tool_stubs/staticcheck New mise tool-stub for staticcheck 2025 release via aqua:dominikh/go-tools/staticcheck

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Go .go file staged] --> B{glob matches?}
    B -- No --> C[Step skipped]
    B -- Yes --> D{workspace_indicator
go.mod found?}
    D -- No --> C
    D -- Yes --> E[Resolve workspace dir]
    E --> F[cd workspace]
    F --> G[tool ./...]
    G --> H{Exit code}
    H -- 0 --> I[Step passes]
    H -- non-0 --> J[Step fails / reported]
Loading

Reviews (3): Last reviewed commit: "fix(builtins): add go tool stub for go_v..." | Re-trigger Greptile

Comment thread test/go_builtins.bats Outdated
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates several Go-related builtin analysis tools to use workspace-based execution (cd {{workspace}} && ... ./...) instead of individual file lists, enabling support for multi-package projects and monorepos. A new test suite was added to verify these changes. The review feedback consistently recommends enclosing the {{workspace}} variable in double quotes across all modified files to ensure the commands remain robust when workspace paths contain spaces.

glob = "**/*.go"
check = "errcheck {{ files }}"
workspace_indicator = "go.mod"
check = "cd {{workspace}} && errcheck ./..."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The {{workspace}} variable should be enclosed in double quotes to ensure the command remains robust if the workspace path contains spaces. Since this command is executed via a shell, unquoted paths with spaces will cause the cd command to fail or behave unexpectedly.

  check = "cd \"{{workspace}}\" && errcheck ./..."

Comment thread pkl/builtins/go_sec.pkl
glob = "**/*.go"
check = "gosec {{ files }}"
workspace_indicator = "go.mod"
check = "cd {{workspace}} && gosec ./..."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The {{workspace}} variable should be enclosed in double quotes to handle paths that contain spaces. Without quotes, the shell will split the path into multiple arguments, causing the cd command to fail.

  check = "cd \"{{workspace}}\" && gosec ./..."

Comment thread pkl/builtins/go_vet.pkl
glob = "**/*.go"
check = "go vet {{ files }}"
workspace_indicator = "go.mod"
check = "cd {{workspace}} && go vet ./..."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Enclose {{workspace}} in double quotes to ensure the command works correctly in environments where directory names contain spaces.

  check = "cd \"{{workspace}}\" && go vet ./..."

glob = "**/*.go"
check = "govulncheck {{ files }}"
workspace_indicator = "go.mod"
check = "cd {{workspace}} && govulncheck ./..."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The {{workspace}} variable should be quoted to prevent shell word-splitting issues when the path contains spaces.

  check = "cd \"{{workspace}}\" && govulncheck ./..."

Comment on lines +14 to +15
check = "cd {{workspace}} && golangci-lint run --fix=false ./..."
fix = "cd {{workspace}} && golangci-lint run --fix ./..."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Both the check and fix commands should have {{workspace}} wrapped in double quotes to safely handle workspace paths containing spaces.

  check = "cd \"{{workspace}}\" && golangci-lint run --fix=false ./..."
  fix = "cd \"{{workspace}}\" && golangci-lint run --fix ./..."

Comment thread pkl/builtins/revive.pkl
glob = "**/*.go"
check = "revive {{ files }}"
workspace_indicator = "go.mod"
check = "cd {{workspace}} && revive ./..."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Quote the {{workspace}} variable to ensure compatibility with paths that include spaces.

  check = "cd \"{{workspace}}\" && revive ./..."

glob = "**/*.go"
check = "staticcheck {{ files }}"
workspace_indicator = "go.mod"
check = "cd {{workspace}} && staticcheck ./..."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The {{workspace}} variable should be quoted to handle directory names with spaces correctly in the shell.

  check = "cd \"{{workspace}}\" && staticcheck ./..."

jdx and others added 2 commits April 5, 2026 14:04
Replace bats integration test with proper pkl-level tests for go_vet
that exercise the workspace_indicator + ./... pattern with real Go code.
Add mise tool stubs for golangci-lint, staticcheck, revive, and gosec.
Document builtin testing patterns in CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The go_vet pkl tests need the `go` binary, which isn't available in all
CI environments. Add a mise tool-stub for `go` so the builtins test
harness can auto-install it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jdx jdx enabled auto-merge (squash) April 5, 2026 17:04
@jdx jdx merged commit bc18ca2 into main Apr 5, 2026
20 checks passed
@jdx jdx deleted the fix/go-builtins-multi-package branch April 5, 2026 17:12
@jdx jdx mentioned this pull request Apr 5, 2026
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Apr 8, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [hk](https://github.com/jdx/hk) | minor | `1.40.0` → `1.41.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>jdx/hk (hk)</summary>

### [`v1.41.0`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1410---2026-04-05)

[Compare Source](jdx/hk@v1.40.0...v1.41.0)

##### 🚀 Features

- **(hook)** support per-worktree hooks via extensions.worktreeConfig by [@&#8203;nkakouros](https://github.com/nkakouros) in [#&#8203;789](jdx/hk#789)

##### 🐛 Bug Fixes

- **(builtins)** use workspace\_indicator for Go package-level analysis tools by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;803](jdx/hk#803)
- **(config)** use XDG\_CONFIG\_HOME for config path instead of dirs::config\_dir() by [@&#8203;fukuchancat](https://github.com/fukuchancat) in [#&#8203;801](jdx/hk#801)

##### 📦️ Dependency Updates

- update anthropics/claude-code-action digest to [`0432df8`](jdx/hk@0432df8) by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;791](jdx/hk#791)
- update rust crate indexmap to v2.13.1 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;792](jdx/hk#792)
- update actions/configure-pages action to v6 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;795](jdx/hk#795)
- update rust crate strum to 0.28 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;794](jdx/hk#794)
- update actions/deploy-pages action to v5 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;796](jdx/hk#796)
- update dependency globals to v17 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;797](jdx/hk#797)
- update github artifact actions (major) by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;798](jdx/hk#798)
- update jdx/mise-action action to v4 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;799](jdx/hk#799)

##### New Contributors

- [@&#8203;fukuchancat](https://github.com/fukuchancat) made their first contribution in [#&#8203;801](jdx/hk#801)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDQuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwNC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
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

Successfully merging this pull request may close these issues.

1 participant