Skip to content

[refactor] Consolidate 6 identical hasStringKey copies into a shared generic set helperΒ #40531

Description

@github-actions

πŸ”§ Semantic Function Clustering Analysis

Analysis of repository: github/gh-aw β€” non-test .go files under pkg/

Overview

A semantic clustering + duplicate sweep over 940 non-test Go files (4,405 top-level funcs, 1,233 methods) found the codebase already well-factored: nearly every same-name cross-package match is either an intentional delegating shim or a legitimate build-tag variant. One genuine duplicate stands out and is worth consolidating.

Metric Value
Non-test Go files analyzed 940
Largest packages workflow (408), cli (322), linters (81), parser (44)
Genuine cross-package duplicate found 1 (hasStringKey)
False positives correctly excluded shims + *_wasm.go build variants

Key finding: hasStringKey duplicated across 6 packages

The exact same 4-line helper is defined in 6 separate seenmapbool_helpers.go files (function bodies byte-identical; only the package line differs):

func hasStringKey(set map[string]struct{}, key string) bool {
	_, ok := set[key]
	return ok
}
Package File
constants pkg/constants/seenmapbool_helpers.go
linters/ssljson pkg/linters/ssljson/seenmapbool_helpers.go
agentdrain pkg/agentdrain/seenmapbool_helpers.go
workflow pkg/workflow/seenmapbool_helpers.go
parser pkg/parser/seenmapbool_helpers.go
cli pkg/cli/seenmapbool_helpers.go

Scale: 196 call sites across these packages (workflow ~90, cli ~50, parser ~12, plus constants/agentdrain/ssljson). The filename and the identical body indicate these were emitted by the map[string]bool β†’ map[string]struct{} migration codemod rather than hand-written.

Recommendation

Introduce a tiny dependency-free leaf util (matching the existing pkg/sliceutil / pkg/typeutil / pkg/stringutil convention) with a generic signature, then delete the 6 copies:

// pkg/setutil/setutil.go  (or add to pkg/typeutil)
package setutil

// Contains reports whether key is present in a set built as map[K]struct{}.
func Contains[K comparable](set map[K]struct{}, key K) bool {
	_, ok := set[key]
	return ok
}

Then replace hasStringKey(set, k) β†’ setutil.Contains(set, k) across the 196 sites (mechanical, e.g. gofmt -r or codemod). pkg/constants is low-level, but a brand-new leaf package with zero imports introduces no cycle. The generic form also covers any future non-string sets for free.

Also fix the source: update the codemod that emits seenmapbool_helpers.go so it references the shared helper instead of generating a per-package copy β€” otherwise the duplicates regrow on the next migration run.

Why the other same-name matches are not duplicates (verified)
  • SanitizeName / SanitizeOptions β€” pkg/workflow/strings.go is already a type-alias + delegating shim to pkg/stringutil (func SanitizeName(...) { return stringutil.SanitizeName(...) }). βœ… Already centralized.
  • LevenshteinDistance β€” pkg/parser/schema_suggestions.go is a one-line wrapper returning stringutil.LevenshteinDistance(a, b). βœ… Already centralized.
  • findGitRoot, RunGH, RunGHContext, RunGHCombined, getDefaultGHHost, IsWorkflowSpec/isWorkflowSpec β€” these pair foo.go with foo_wasm.go; the second copy is a build-tag-gated WASM stub, not a duplicate. βœ… Excluded.
  • extractToolsFromFrontmatter β€” exists in workflow (returns map[string]any) and parser (returns (string, error)): same name, genuinely different purpose/signature in different packages. Package namespacing, not duplication. βœ… Acceptable.
  • run (31Γ—), init (13Γ—) β€” standard Cobra command + package-init patterns. βœ… Idiomatic.

Next actions

  • Add pkg/setutil (or typeutil) with generic Contains[K comparable]
  • Replace 196 hasStringKey call sites; delete the 6 seenmapbool_helpers.go copies
  • Patch the migration codemod to emit a shared call instead of per-package copies
  • go build ./... && go test ./... to confirm no behavior change

Detection method: top-level func-name clustering across all non-test .go files + body-identity (md5) verification + manual confirmation of each candidate. Analysis date: 2026-06-21.

References: Β§27887885991

Generated by πŸ”§ Semantic Function Refactoring Β· 163.9 AIC Β· βŒ– 14.9 AIC Β· ⊞ 9.1K Β· β—·

  • expires on Jun 22, 2026, 4:10 PM UTC-08:00

Activity

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

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions