Skip to content

[duplicate-code] Duplicate Code: YAML block-walking state machine duplicated across codemod files #69116

Open

Description

@github-actions

🔍 Duplicate Code Detected: Codemod YAML Block-Walking State Machine

Analysis of commit 5bf0b44 (github/gh-aw)

Assignee: @copilot

Summary

The pkg/cli/codemod_*.go family re-implements the same line-by-line YAML block-walking state machine. Each codemod iterates over lines, tracks inTools / nested-block booleans, detects block entry via strings.HasPrefix(trimmed, "...:"), captures indentation with the shared getIndentation, and resets state via the shared hasExitedBlock. The helpers are already factored into pkg/cli/yaml_frontmatter_utils.go, but the ~40-50 line control-flow scaffold around them is copy-pasted.

Duplication Details

Pattern: line-walk + block-state scaffold

  • Severity: High
  • Occurrences: 9+ files use the inTools-style walk; 30 references to hasExitedBlock across codemods
  • Representative Locations:
    • pkg/cli/codemod_github_repos.go (lines 62-110, renameGitHubReposToAllowedRepos)
    • pkg/cli/codemod_toolset_singular.go (lines ~63-110)
    • pkg/cli/codemod_allowed_repos_current.go (lines ~68-115)
    • pkg/cli/codemod_github_app.go (lines ~99-139)
    • pkg/cli/codemod_checkout_persist_credentials_false.go / codemod_steps_run_secrets_env.go (~25-line blocks repeated)
    • pkg/cli/codemod_mcp_network.go / codemod_playwright_domains.go
  • Code Sample:
    for i, line := range lines {
        trimmed := strings.TrimSpace(line)
        if trimmed == "" { result = append(result, line); continue }
        if !strings.HasPrefix(trimmed, "#") {
            if inToolsGithub && hasExitedBlock(line, toolsGithubIndent) { inToolsGithub = false }
            if inTools && hasExitedBlock(line, toolsIndent) { inTools = false; inToolsGithub = false }
        }
        if strings.HasPrefix(trimmed, "tools:") { inTools = true; toolsIndent = getIndentation(line); ... }
    }

Impact Analysis

  • Maintainability: A fix to block-exit/indentation edge cases must be applied in ~9 places.
  • Bug Risk: High risk of inconsistent handling of comments/blank lines between codemods.
  • Code Bloat: Hundreds of near-identical lines in pkg/cli.

Refactoring Recommendations

  1. Extract a reusable block walker into pkg/cli/yaml_frontmatter_utils.go, e.g. walkYAMLBlock(lines []string, path []string, onLine func(ctx blockCtx, line string) (string, bool)) ([]string, bool) that drives the enter/exit state machine and lets each codemod supply only the per-line transform.
    • Estimated effort: medium (4-8h)
    • Benefits: single source of truth for indentation/exit semantics; each codemod shrinks to its unique rewrite logic.
  2. Add table-driven tests for the extracted walker covering comments, blank lines, and nested exits.

Implementation Checklist

  • Review duplication findings
  • Design shared walker signature
  • Migrate codemods incrementally
  • Update/centralize tests
  • Verify make recompile + unit tests pass
Analysis Metadata
  • Analyzed Files: pkg/cli/codemod_*.go (72 files)
  • Detection Method: Serena activation + normalized sliding-window block hashing
  • Commit: 5bf0b44

Generated by 🔍 Duplicate Code Detector · pi · opus48 · 139.4 AIC · ⌖ 42.8 AIC · ⊞ 1.6K · ◷

  • expires on Oct 17, 2026, 1:56 PM UTC-08:00

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions