datadog-agent / rules
DataDog/datadog-agent/.cursor/rules/go_module_bazel_migration.mdc
Rules for migrating Go modules (L0+) from go.work to Bazel. Use when adjusting gazelle:exclude directives, running Gazelle, or opening new modules for Bazel builds.
Cursor rule3.8k starsChanged 2 days ago
What's in it
- Go Module Bazel Migration
- Recipe per module
- Custom //go:build tags and GAZELLEBUILDTAGS
- BUILD.bazel editing rules
- //go:build test sources
- OS-specific modules
- Proto handling
- gazelle:ignore vs gazelle:exclude
- Known issue: godeps external repo @rulesgo visibility
--- description: Rules for migrating Go modules (L0+) from go.work to Bazel. Use when adjusting gazelle:exclude directives, running Gazelle, or opening new modules for Bazel builds. alwaysApply: false --- # Go Module Bazel Migration ## Recipe per module 1. **Granularize excludes** in root `BUILD.bazel`: replace the broad `# gazelle:exclude pkg/foo` with individual excludes for every sibling directory *except* the target module. Never remove an exclude without adding granular replacements. 2. **Stub intermediate directories**: if any parent directory on the path to the target module contains `.go` files, create a `BUILD.bazel` with only `# gazelle:ignore` and a short comment. This prevents Gazelle from generating targets that pull unmigrated external-repo deps. Check with `ls <dir>/*.go` before deciding. 3. **Run the pipeline**: ```bash bazel run //:gazelle bazel mod tidy bazel test //path/to/module/... ``` 4. **Verify `//...`** still works after migration. ## Custom `//go:build` tags and `_GAZELLE_BUILD_TAGS` Root `BUILD.bazel` defines `_GAZELLE_BUILD_TAGS` (sourced from `tasks/build_tags.py ALL_TAGS` + `"test"`), passed to `gazelle` via `build_tags = _GAZELLE_BUILD_TAGS`. If you migrate a package whose sources use **project-specific** tags (anything beyond plain OS tags), verify the tag is already in this list. Cross-check names with `tasks/build_tags.py` (`ALL_TAGS`) so spelling matches the rest of the repo. **Important:** `_GAZELLE_BUILD_TAGS` affects **Gazelle analysis only**; it does **not** turn on tags for `bazel build` / `bazel test`. Do not bulk-add tags to every test target just because a tag appears in `_GAZELLE_BUILD_TAGS`. **When to add `gotags` on specific `go_test` / `go_library` targets:** - When **`bazel test` / `bazel build` fails** in a way that points to wrong or missing symbols from tag-gated sources — add the needed tags on that package's `go_test` (and/or `go_library`) so the compiler enables the same constraints. - For **k8s-style tags** (`kubeapiserver`, `kubelet`, etc.) — add `gotags` **per package** only when that package's **sources or tests** are actually behind those `//go:build` lines (including tag-gated `*_test.go`). Do not add them speculatively to every test under a tree. - **Do NOT manually add `gotags = ["test"]`** — the `go_build_tags` Gazelle extension (`//bazel/rules/go_build_tags:gazelle_extension`) automatically adds `gotags = ["test"]` to every `go_test` rule during Gazelle generation. ## BUILD.bazel editing rules - **Never manually edit Gazelle-generated BUILD.bazel files** for content that Gazelle manages (srcs, deps, imports). Re-run Gazelle instead. - The **only** manual edits allowed on generated BUILD files: - `target_compatible_with = ["@platforms//os:linux"] # keep` on OS-specific targets (see below). - `# keep` comments to pin specific lines Gazelle would otherwise overwrite. - **Root `BUILD.bazel` only:** extend `_GAZELLE_BUILD_TAGS` when migrating trees that rely on custom build tags not yet in the list (section above). ## `//go:build test` sources Gazelle places files with `//go:build test` into `go_library` srcs (not `go_test`), because it treats `test` as a regular build tag. Bazel does not set the `test` tag during library compilation, so these symbols become undefined in test targets. **Fix:** the `go_build_tags` Gazelle extension (`//bazel/rules/go_build_tags:gazelle_extension`) automatically adds `gotags = ["test"]` to every `go_test` rule. This causes `rules_go` to apply a configuration transition that propagates the `test` build tag to all transitive deps, enabling `//go:build test` files in `go_library` targets to be compiled during test builds but excluded from production builds. No manual intervention is needed — just re-run Gazelle. ## OS-specific modules Gazelle lists all source files unconditionally in `srcs` even when they carry `//go:build linux` (or another OS constraint). `rules_go` filters them at compile time, so compilation is correct. However, `//...` expansion will still attempt to analyze the target on all platforms, producing empty libraries or confusing errors. **Fix:** add `target_compatible_with = ["@platforms//os:linux"] # keep` (or the appropriate OS) to both `go_library` and `go_test` targets. The `# keep` comment prevents Gazelle from stripping the line on re-runs. ## Proto handling The repo uses pre-generated `.pb.go` files everywhere — no `proto_library` or `go_proto_library` targets. Gazelle's `DEFAULT_LANGUAGES` includes `//language/proto`, so the proto extension is always active. **`# gazelle:proto disable`** must be set in the root `BUILD.bazel`. Without it, Gazelle's default proto mode would generate `proto_library` rules and suppress `.pb.go` files from `go_library` srcs in any directory containing both `.proto` and `.pb.go` (e.g. `comp/forwarder/defaultforwarder/internal/retry/`, `pkg/security/proto/api/`). Currently this is masked by `gazelle:exclude` on those directories, but migration would silently break without the global disable. Proto source-only trees (`pkg/proto/datadog`, `pkg/proto/protodep`) still need `gazelle:exclude` because they contain no Go code — `# gazelle:proto disable` alone doesn't help there since there's nothing for Gazelle to generate. The fan-in problem (multiple `.proto` dirs sharing `option go_package = "pkg/proto/pbgo/core"`) is an additional reason those excludes must stay. ## `gazelle:ignore` vs `gazelle:exclude` - `gazelle:exclude <pattern>` — a directory match stops Gazelle from recursing into it, whereas a file match excludes it from managed rules, - `gazelle:ignore` — stops Gazelle from modifying its containing BUILD.bazel file. ## Known issue: `go_deps` external repo `@rules_go` visibility When `go_deps` creates external repos for local `go.work` modules that are still excluded, those repos can't resolve `@rules_go`. This surfaces when `//...` expansion hits an unmigrated intermediate package. Fix: `# gazelle:ignore` stubs at those directories, or ensure they remain excluded.
More agent context in DataDog/datadog-agent
42 other files this repository gives its agents.
CLAUDE.md
Cursor rule
Skill
- agent-supply-chain-newsletter.agents/skills/agent-supply-chain-newsletter/SKILL.md
- allium.agents/skills/allium/SKILL.md
- auto-jira.agents/skills/auto-jira/SKILL.md
- create-component.agents/skills/create-component/SKILL.md
- create-config-field.agents/skills/create-config-field/SKILL.md
- create-core-check.agents/skills/create-core-check/SKILL.md
- create-epic-recap.agents/skills/create-epic-recap/SKILL.md
- create-go-module.agents/skills/create-go-module/SKILL.md
- create-invoke-task.agents/skills/create-invoke-task/SKILL.md
- create-pr.agents/skills/create-pr/SKILL.md
- create-release-note.agents/skills/create-release-note/SKILL.md
- create-runtime-setting.agents/skills/create-runtime-setting/SKILL.md
- create-status-provider.agents/skills/create-status-provider/SKILL.md
- create-subcommand.agents/skills/create-subcommand/SKILL.md
- cws-btfhub-sync.agents/skills/cws-btfhub-sync/SKILL.md
- cws-iouring-coverage.agents/skills/cws-iouring-coverage/SKILL.md
- e2e-audit.agents/skills/e2e-audit/SKILL.md
- explain-lading-config.agents/skills/explain-lading-config/SKILL.md
- follow-pr.agents/skills/follow-pr/SKILL.md
- gpu-live-metric-validation.agents/skills/gpu-live-metric-validation/SKILL.md
- handle-pr-ci-failure.agents/skills/handle-pr-ci-failure/SKILL.md
- injector-dev.agents/skills/injector-dev/SKILL.md
- locate-config-setting.agents/skills/locate-config-setting/SKILL.md
- quality-gate-size-analysis.agents/skills/quality-gate-size-analysis/SKILL.md
- review-pr-comments.agents/skills/review-pr-comments/SKILL.md
- run-e2e.agents/skills/run-e2e/SKILL.md
- run-jira.agents/skills/run-jira/SKILL.md
- run-windows-e2e.agents/skills/run-windows-e2e/SKILL.md
- triage-ci-failure.agents/skills/triage-ci-failure/SKILL.md
- update-3rd-party-libs.agents/skills/update-3rd-party-libs/SKILL.md
- update-otel-deps.agents/skills/update-otel-deps/SKILL.md
- write-e2e.agents/skills/write-e2e/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
Reports can't be read right now.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

