Skip to content

[file-diet] Refactor Large Go File: pkg/cli/compile_orchestrator.go (1200 lines) #8243

@agentic-workflows-dev

Description

@agentic-workflows-dev

Overview

The file pkg/cli/compile_orchestrator.go has grown to 1200 lines, making it difficult to maintain and test. The main CompileWorkflows function alone contains over 1000 lines with 195+ control structures, indicating high complexity and the need for refactoring into smaller, focused files with improved test coverage.

Current State

  • File: pkg/cli/compile_orchestrator.go
  • Size: 1200 lines
  • Test Coverage: 1200 lines across multiple test files (compile_command_test.go: 1060 lines, compile_orchestrator_stability_test.go: 140 lines)
  • Test-to-Source Ratio: 1:1 (adequate coverage exists)
  • Complexity: Very High
    • Only 4 functions, but CompileWorkflows is monolithic (1000+ lines)
    • 195+ control structures (if/for statements)
    • Handles 15+ distinct responsibilities in a single function

Campaign Status

Files Over 800-Line Threshold: 17 files currently exceed healthy limits

This refactor will reduce the count and improve overall codebase health.

Refactoring Strategy

The CompileWorkflows function is doing too much. Based on semantic analysis, split into focused modules:

Proposed File Splits

1. compile_config_validator.go

  • Functions:
    • validateCompileConfig() - Configuration validation
    • validateWorkflowDirectory() - Workflow directory setup
    • resolveWorkflowFile() - File resolution logic
  • Responsibility: Pre-compilation configuration validation
  • Estimated LOC: ~150 lines

2. compile_compiler_setup.go

  • Functions:
    • createCompiler() - Compiler initialization
    • configureCompilerFlags() - Set validation, strict mode, trial mode
    • setupActionMode() - Action mode detection and configuration
    • setupRepositoryContext() - Repository slug and git root setup
  • Responsibility: Compiler instance creation and configuration
  • Estimated LOC: ~200 lines

3. compile_workflow_processor.go

  • Functions:
    • processWorkflowFile() - Single workflow compilation logic
    • processCampaignSpec() - Campaign spec handling
    • collectLockFilesForLinting() - Lock file collection
  • Responsibility: Per-file processing logic
  • Estimated LOC: ~250 lines

4. compile_batch_operations.go

  • Functions:
    • runBatchActionlint() - Batch actionlint execution
    • runBatchZizmor() - Batch security linting
    • runBatchPoutine() - Batch supply chain analysis
    • purgeOrphanedFiles() - Clean up orphaned .lock.yml and .invalid.yml files
  • Responsibility: Batch operations on compiled workflows
  • Estimated LOC: ~200 lines

5. compile_output_formatter.go

  • Functions:
    • printCompilationSummary() - Already exists, move here
    • displayStatsTable() - Already exists, move here
    • displayActionlintSummary() - Already exists, move here
    • formatValidationResults() - JSON output formatting
    • sanitizeValidationResults() - Security sanitization
  • Responsibility: Output formatting and display
  • Estimated LOC: ~150 lines

6. compile_post_processing.go

  • Functions:
    • generateDependabotManifests() - Dependabot generation wrapper
    • generateMaintenanceWorkflow() - Maintenance workflow generation
    • validateCampaignSpecs() - Campaign validation wrapper
    • collectWorkflowStatistics() - Stats collection
  • Responsibility: Post-compilation generation and validation
  • Estimated LOC: ~150 lines

7. compile_orchestrator.go (Refactored)

  • Functions:
    • CompileWorkflows() - Main orchestrator (dramatically simplified)
    • getRepositoryRelativePath() - Keep helper
    • renderGeneratedCampaignOrchestratorMarkdown() - Keep campaign rendering
    • generateAndCompileCampaignOrchestrator() - Keep campaign generation
  • Responsibility: High-level orchestration and campaign support
  • Estimated LOC: ~250 lines (reduction from 1200 to 250)

Shared Utilities

Extract common functionality into existing files:

  • git_helpers.go: Git root finding, repository slug extraction (may already exist)
  • file_helpers.go: File path resolution, glob operations

Interface Abstractions

Consider introducing interfaces to reduce coupling:

  • WorkflowProcessor interface: For processing different file types (workflows vs campaigns)
  • LinterRunner interface: For running different linters (actionlint, zizmor, poutine)
  • OutputFormatter interface: For different output formats (text, JSON, stats)

Test Coverage Plan

Add comprehensive tests for each new file:

1. compile_config_validator_test.go

  • Test cases:
    • Valid configuration passes
    • Invalid workflow directory rejected
    • File resolution with various input formats (ID, path, basename)
    • Error messages are user-friendly
  • Target coverage: >80%

2. compile_compiler_setup_test.go

  • Test cases:
    • Compiler created with correct flags
    • Action mode auto-detection works
    • Trial mode configuration
    • Repository context setup
  • Target coverage: >80%

3. compile_workflow_processor_test.go

  • Test cases:
    • Regular workflow processing
    • Campaign spec processing
    • Error handling for invalid files
    • Lock file collection
  • Target coverage: >80%

4. compile_batch_operations_test.go

  • Test cases:
    • Batch linting with multiple files
    • Purge removes orphaned files
    • Purge preserves expected files
    • Error handling in batch operations
  • Target coverage: >80%

5. compile_output_formatter_test.go

  • Test cases:
    • Summary formatting
    • JSON output validation
    • Stats table display
    • Security sanitization works correctly
  • Target coverage: >80%

6. compile_post_processing_test.go

  • Test cases:
    • Dependabot manifest generation
    • Maintenance workflow generation
    • Campaign validation
    • Statistics collection
  • Target coverage: >80%

7. compile_orchestrator_test.go (Updated)

  • Test cases:
    • End-to-end compilation flow
    • Integration between modules
    • Error propagation
    • Campaign orchestrator generation
  • Target coverage: >80%
  • Note: Existing compile_orchestrator_stability_test.go should continue to work

Implementation Guidelines

  1. Preserve Behavior: Ensure all existing functionality works identically
  2. Maintain Exports: Keep public API unchanged (CompileWorkflows signature stays the same)
  3. Add Tests First: Write tests for each new file before refactoring
  4. Incremental Changes: Split one module at a time, starting with easiest
  5. Run Tests Frequently: Verify make test-unit passes after each split
  6. Update Imports: Ensure all import paths are correct
  7. Document Changes: Add comments explaining module boundaries
  8. Keep Internal Functions Private: New helper functions should be unexported unless needed externally

Suggested Implementation Order

  1. Start with output formatting (compile_output_formatter.go) - Lowest coupling
  2. Config validation (compile_config_validator.go) - Clear boundaries
  3. Compiler setup (compile_compiler_setup.go) - Straightforward extraction
  4. Batch operations (compile_batch_operations.go) - Independent logic
  5. Post-processing (compile_post_processing.go) - Wrapper functions
  6. Workflow processor (compile_workflow_processor.go) - Core logic, most complex
  7. Refactor orchestrator (compile_orchestrator.go) - Final step, tie everything together

Acceptance Criteria

  • Original file is split into 7 focused files
  • Each new file is under 300 lines
  • compile_orchestrator.go reduced from 1200 to ~250 lines
  • All tests pass (make test-unit)
  • Test coverage is ≥80% for new files
  • No breaking changes to public API (CompileWorkflows signature unchanged)
  • Code passes linting (make lint)
  • Build succeeds (make build)
  • Existing integration tests continue to pass
  • compile_orchestrator_stability_test.go continues to work without changes

Additional Context

  • Repository Guidelines: Follow patterns in .github/instructions/developer.instructions.md
  • Code Organization: Prefer many small files grouped by functionality (see specs/code-organization.md)
  • Testing: Match existing test patterns in pkg/cli/*_test.go
  • Naming: Use clear, descriptive names following Go conventions
  • Logging: Use the logger package with namespace cli:filename pattern

Impact Assessment

Priority: High
Effort: Large (7-10 days for careful refactoring with tests)
Expected Impact:

  • ✅ Improved maintainability (easier to understand and modify)
  • ✅ Easier testing (focused unit tests for each module)
  • ✅ Reduced complexity (smaller functions with single responsibilities)
  • ✅ Better code organization (logical separation of concerns)
  • ✅ Reduced file size in campaign metrics (contributes to overall campaign goal)

Campaign: Go File Size Reduction
Metrics Date: 2025-12-31
Files Over Threshold: 17 (this refactor reduces count by 1)

AI generated by Daily File Diet

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions