-
Notifications
You must be signed in to change notification settings - Fork 445
refactor(workflow): extract helpers to fix function-length lint violations #44008
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
base: main
Are you sure you want to change the base?
Changes from all commits
cdf3323
b47f4b2
fa98c82
9fba746
745e461
0034e92
b299c85
3f8b0ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # ADR-44008: Extract Package-Private Helpers to Comply with the `largefunc` Lint Limit | ||
|
|
||
| **Date**: 2026-07-07 | ||
| **Status**: Draft | ||
| **Deciders**: Unknown | ||
|
|
||
| --- | ||
|
|
||
| ### Context | ||
|
|
||
| The repository enforces a `largefunc` lint rule capping function bodies at 60 lines. Four functions in `pkg/workflow` exceeded this limit after organic growth: `ResolveSHA` (67 lines), `computeAntigravityToolsCore` (65 lines), `buildInputSchema` (69 lines), and `getShellEnvironmentPolicyVars` (61 lines). All four contained self-contained logical sub-problems—semver pin lookup, bash tool expansion, JSON Schema property construction, and MCP env-var mapping—that were implemented as inline blocks. Leaving these violations unaddressed blocks the lint gate and defers the structural clarity cost indefinitely. | ||
|
|
||
| ### Decision | ||
|
|
||
| We will extract each over-limit inline block into a dedicated, package-private helper function co-located in the same source file, with no changes to observable behavior. The helpers (`lookupEmbeddedActionPin`, `appendBashTools`, `buildChoiceInputProperty`, `buildInputProperty`, `addMCPToolEnvVars`) own exactly one sub-problem each and are named after their responsibility rather than their caller. This satisfies the `largefunc` lint limit without raising the threshold or suppressing the check. | ||
|
|
||
| ### Alternatives Considered | ||
|
|
||
| #### Alternative 1: Raise or Suppress the `largefunc` Threshold | ||
|
|
||
| The lint threshold could be increased (e.g., from 60 to 80 lines) or suppressed with a per-file `//nolint` comment for the four affected files. This avoids any code restructuring and is trivially fast to apply. | ||
|
|
||
| Rejected because it signals that the lint rule is optional and sets a precedent for future exemptions. The four functions each contained a genuinely separable concern; the lint violation was a signal worth acting on rather than silencing. | ||
|
|
||
| #### Alternative 2: Promote Helpers to a New Sub-Package | ||
|
|
||
| The extracted logic (semver pin matching, bash tool expansion, MCP env-var mapping) could be placed in separate sub-packages (e.g., `pkg/workflow/actionpin`, `pkg/workflow/bashtools`) to give them stronger encapsulation and independent test files. | ||
|
|
||
| Rejected because the helpers are not reused outside `pkg/workflow` and the sub-package boundary would add import indirection with no practical benefit. Package-private functions in the same file achieve the same readability improvement with less structural overhead. | ||
|
|
||
| ### Consequences | ||
|
|
||
| #### Positive | ||
| - All four functions now comply with the 60-line `largefunc` lint rule, unblocking the lint gate. | ||
| - Each extracted helper is independently unit-testable without constructing the full parent receiver. | ||
| - Callers of the parent functions are shorter and read at a higher level of abstraction. | ||
|
|
||
| #### Negative | ||
| - The package now has five additional unexported functions, slightly increasing its exported-symbol footprint as seen by IDEs and documentation tools. | ||
| - Readers who want to understand a full call path must navigate one extra indirection for each extracted helper. | ||
|
|
||
| #### Neutral | ||
| - All helpers are package-private (`lowercase` names) and co-located with their caller; no public API surface changes. | ||
| - The refactoring carries zero behavior change risk, but reviewers still need to verify the extraction did not alter edge-case handling (e.g., the early-`continue` logic in `buildInputSchema`'s choice branch). | ||
|
|
||
| --- | ||
|
|
||
| *ADR created by [adr-writer agent]. Review and finalize before changing status from Draft to Accepted.* |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,38 +56,7 @@ func computeAntigravityToolsCore(tools map[string]any) []string { | |
|
|
||
| // Map bash neutral tool to run_shell_command | ||
| if bashConfig, hasBash := tools["bash"]; hasBash { | ||
| bashCommands, ok := bashConfig.([]any) | ||
| if !ok || len(bashCommands) == 0 { | ||
| // bash with no specific commands - allow all shell commands | ||
| antigravityToolsLog.Print("bash (no specific commands) → run_shell_command") | ||
| toolsCore = append(toolsCore, "run_shell_command") | ||
| } else { | ||
| // Check for wildcard (* or :*) | ||
| hasWildcard := false | ||
| for _, cmd := range bashCommands { | ||
| if cmdStr, ok := cmd.(string); ok && (cmdStr == "*" || cmdStr == ":*") { | ||
| hasWildcard = true | ||
| break | ||
| } | ||
| } | ||
| if hasWildcard { | ||
| antigravityToolsLog.Print("bash wildcard → run_shell_command") | ||
| toolsCore = append(toolsCore, "run_shell_command") | ||
| } else { | ||
| // Add an entry for each specific command: run_shell_command(cmd) | ||
| for _, cmd := range bashCommands { | ||
| if cmdStr, ok := cmd.(string); ok { | ||
| // Normalize trailing " *" wildcard (e.g. "jq *" → "jq") so that | ||
| // all engines emit the canonical prefix form (run_shell_command(jq)) | ||
| // regardless of whether the command was written with or without the wildcard. | ||
| normalized, _ := normalizeBashCommand(cmdStr) | ||
| entry := fmt.Sprintf("run_shell_command(%s)", normalized) | ||
| antigravityToolsLog.Printf("bash %q → %s", cmdStr, entry) | ||
| toolsCore = append(toolsCore, entry) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| toolsCore = appendBashTools(toolsCore, bashConfig) | ||
| } | ||
|
|
||
| // Map edit neutral tool to write_file and replace (Antigravity's file write tools) | ||
|
|
@@ -108,6 +77,43 @@ func computeAntigravityToolsCore(tools map[string]any) []string { | |
| return toolsCore | ||
| } | ||
|
|
||
| // appendBashTools maps the bash neutral tool configuration to run_shell_command | ||
| // entries and appends them to toolsCore. | ||
| func appendBashTools(toolsCore []string, bashConfig any) []string { | ||
| bashCommands, ok := bashConfig.([]any) | ||
| if !ok || len(bashCommands) == 0 { | ||
| // bash with no specific commands - allow all shell commands | ||
| antigravityToolsLog.Print("bash (no specific commands) → run_shell_command") | ||
| return append(toolsCore, "run_shell_command") | ||
| } | ||
|
|
||
| // Single pass over bashCommands. A separate accumulator (specific) collects | ||
| // per-command entries so that if a wildcard ("*" or ":*") is found anywhere | ||
| // in the list — even after specific commands — only "run_shell_command" is | ||
| // appended and the pre-wildcard entries are discarded. This preserves the | ||
| // semantics of "any wildcard means allow all shell commands" regardless of | ||
| // command ordering. | ||
| var specific []string | ||
| for _, cmd := range bashCommands { | ||
| cmdStr, ok := cmd.(string) | ||
| if !ok { | ||
| continue | ||
| } | ||
| if cmdStr == "*" || cmdStr == ":*" { | ||
| antigravityToolsLog.Print("bash wildcard → run_shell_command") | ||
| return append(toolsCore, "run_shell_command") | ||
| } | ||
| // Normalize trailing " *" wildcard (e.g. "jq *" → "jq") so that | ||
| // all engines emit the canonical prefix form (run_shell_command(jq)) | ||
| // regardless of whether the command was written with or without the wildcard. | ||
| normalized, _ := normalizeBashCommand(cmdStr) | ||
| entry := fmt.Sprintf("run_shell_command(%s)", normalized) | ||
| antigravityToolsLog.Printf("bash %q → %s", cmdStr, entry) | ||
| specific = append(specific, entry) | ||
| } | ||
| return append(toolsCore, specific...) | ||
| } | ||
|
|
||
| // generateAntigravitySettingsStep creates a GitHub Actions step that writes the | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [/codebase-design] 💡 Consider single-pass alternativeThe current implementation iterates for _, cmd := range bashCommands {
cmdStr, ok := cmd.(string)
if !ok {
continue
}
if cmdStr == "*" || cmdStr == ":*" {
antigravityToolsLog.Print("bash wildcard → run_shell_command")
return append(toolsCore, "run_shell_command")
}
normalized, _ := normalizeBashCommand(cmdStr)
entry := fmt.Sprintf("run_shell_command(%s)", normalized)
antigravityToolsLog.Printf("bash %q → %s", cmdStr, entry)
toolsCore = append(toolsCore, entry)
}
return toolsCoreThis is a nit — the current version is correct and the tests cover both paths. @copilot please address this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in commit |
||
| // Antigravity CLI project settings file (.antigravity/settings.json) before execution. | ||
| // | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/tdd]
lookupEmbeddedActionPincontains non-trivial semver matching logic (precise vs. range version comparison) but has no direct test — existingResolveSHAtests only cover cache-hit and network-error paths; the embedded-pin branch is untested.💡 Suggested test
lookupEmbeddedActionPinis package-private and can be unit-tested directly:This locks down the semver-matching logic independently of the cache layer.
@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in commit
b299c85. AddedTestLookupEmbeddedActionPintoaction_resolver_test.gocovering four paths: precise-version match, semver-range match, unknown-repo not-found, and known-repo incompatible-version not-found.