-
Notifications
You must be signed in to change notification settings - Fork 46
Description
Overview
The file pkg/cli/add_interactive.go has grown to 1025 lines, making it difficult to maintain and test. This task involves refactoring it into smaller, focused files with improved test coverage.
Current State
- File:
pkg/cli/add_interactive.go - Size: 1025 lines
- Test Coverage: No test file found
- Complexity: Multiple distinct functional domains with 23 functions handling Git operations, GitHub API interactions, user prompts, and workflow orchestration
Full File Analysis
Detailed Breakdown
The file contains 23 functions organized into these functional areas:
1. Repository & Authentication Checks (5 functions, ~170 lines)
checkGHAuthStatus()- Verify GitHub CLI authenticationcheckGitRepository()- Verify git repo and get org/repo infocheckRepoVisibility()- Check if repo is public/privatecheckActionsEnabled()- Verify GitHub Actions enabledcheckUserPermissions()- Check user has write access
2. Secret Management (2 functions, ~80 lines)
checkExistingSecrets()- Fetch existing repository secretsaddRepositorySecret()- Add a new repository secret
3. AI Engine Selection & API Key Collection (4 functions, ~240 lines)
selectAIEngineAndKey()- Prompt user to select engine and provide key (110 lines)collectAPIKey()- Collect API key for selected enginecollectCopilotPAT()- Special handling for Copilot PAT creation (60 lines)collectGenericAPIKey()- Generic API key collection (60 lines)
4. Workflow Resolution & Display (3 functions, ~50 lines)
resolveWorkflows()- Resolve workflow specifications earlyshowWorkflowDescriptions()- Display workflow descriptionsdetermineFilesToAdd()- Determine which files will be added
5. Change Application & Git Operations (4 functions, ~120 lines)
getSecretInfo()- Get secret name and value for engineconfirmChanges()- Ask user to confirm changesapplyChanges()- Create PR, merge it, and add secret (70 lines)updateLocalBranch()- Update local branch after merge (40 lines)
6. Workflow Execution & Status (4 functions, ~160 lines)
checkStatusAndOfferRun()- Check workflow status and offer to run (135 lines)getWorkflowStatuses()- Helper to get workflow statuses (45 lines)mergePullRequest()- Merge a pull request (10 lines)showFinalInstructions()- Display final instructions (20 lines)
7. Main Orchestration (1 function, ~95 lines)
RunAddInteractive()- Main entry point that coordinates all steps
Complexity Hotspots
selectAIEngineAndKey()(lines 372-478): 110 lines handling engine selection logic with multiple priority checks (workflow frontmatter, existing secrets, environment variables)checkStatusAndOfferRun()(lines 825-956): 135 lines managing workflow status polling, spinner UI, and conditional run triggeringcollectCopilotPAT()(lines 499-557): 60 lines with extensive GitHub PAT creation instructionsapplyChanges()(lines 701-769): 70 lines coordinating workflow addition, PR creation, and merging
Code Patterns
- Heavy use of console formatting for user-facing output
- Interactive prompts using
charmbracelet/huhlibrary - GitHub CLI (
gh) command execution viaworkflow.RunGH() - State stored in
AddInteractiveConfigstruct passed through methods - No test coverage for any interactive flows
Refactoring Strategy
Proposed File Splits
Based on semantic analysis, split the file into the following modules:
-
add_interactive_orchestrator.go- Functions:
RunAddInteractive(),resolveWorkflows(),showWorkflowDescriptions(),determineFilesToAdd(),confirmChanges(),showFinalInstructions() - Responsibility: Main orchestration and workflow coordination
- Estimated LOC: ~250 lines
- Functions:
-
add_interactive_auth.go- Functions:
checkGHAuthStatus(),checkGitRepository(),checkRepoVisibility(),checkActionsEnabled(),checkUserPermissions() - Responsibility: Authentication and repository validation
- Estimated LOC: ~200 lines
- Functions:
-
add_interactive_secrets.go- Functions:
checkExistingSecrets(),addRepositorySecret(),getSecretInfo() - Responsibility: Secret management and GitHub Secrets API interaction
- Estimated LOC: ~120 lines
- Functions:
-
add_interactive_engine.go- Functions:
selectAIEngineAndKey(),collectAPIKey(),collectCopilotPAT(),collectGenericAPIKey() - Responsibility: AI engine selection and API key collection
- Estimated LOC: ~240 lines
- Functions:
-
add_interactive_git.go- Functions:
applyChanges(),updateLocalBranch(),mergePullRequest() - Responsibility: Git operations, PR creation, and merging
- Estimated LOC: ~120 lines
- Functions:
-
add_interactive_workflow.go- Functions:
checkStatusAndOfferRun(),getWorkflowStatuses() - Responsibility: Workflow status polling and execution
- Estimated LOC: ~160 lines
- Functions:
Shared Configuration
Keep AddInteractiveConfig struct in add_interactive_orchestrator.go since it's the central state container used by all modules.
Test Coverage Plan
Add comprehensive tests for each new file:
-
add_interactive_orchestrator_test.go- Test orchestration logic with mocked dependencies
- Test workflow resolution and file determination
- Target coverage: >80%
-
add_interactive_auth_test.go- Test auth status checks with mock
ghcommands - Test repository validation logic
- Test public/private repo detection
- Target coverage: >80%
- Test auth status checks with mock
-
add_interactive_secrets_test.go- Test secret existence checking
- Test secret name/value extraction
- Mock GitHub Secrets API responses
- Target coverage: >80%
-
add_interactive_engine_test.go- Test engine selection priority logic (frontmatter > secrets > env)
- Test API key validation
- Test Copilot PAT instructions
- Target coverage: >80%
-
add_interactive_git_test.go- Test PR creation and merging logic
- Test local branch update logic
- Mock git and gh CLI commands
- Target coverage: >80%
-
add_interactive_workflow_test.go- Test workflow status polling with retries
- Test workflow dispatch triggering
- Mock workflow status API responses
- Target coverage: >80%
Testing Strategy
Since this code is heavily interactive (uses charmbracelet/huh forms), tests should:
- Mock external dependencies (
ghCLI, git commands) - Test business logic separately from UI interactions
- Use table-driven tests for validation logic
- Consider extracting testable functions from interactive prompts
Implementation Guidelines
- Preserve Behavior: Ensure all existing functionality works identically
- Maintain Exports: Keep public API unchanged (only
RunAddInteractive()is exported) - Add Tests First: Write tests for extracted logic before refactoring
- Incremental Changes: Split one module at a time
- Run Tests Frequently: Verify
make test-unitpasses after each split - Update Imports: Ensure all import paths are correct
- Document Changes: Add comments explaining module boundaries
- Console Formatting: Maintain existing console.Format* patterns
Acceptance Criteria
- Original file is split into 6 focused files
- Each new file is under 300 lines
- All existing functionality preserved (no behavior changes)
- Test coverage ≥80% for testable logic (excluding interactive UI)
- No breaking changes to public API (
RunAddInteractivesignature unchanged) - Code passes linting (
make lint) - Build succeeds (
make build) -
AddInteractiveConfigstruct remains in orchestrator file
Additional Context
- Repository Guidelines: Follow patterns in
AGENTS.md - Code Organization: Prefer many small files grouped by functionality
- Testing: Match existing test patterns in
pkg/cli/*_test.go - Console Output: Use
fmt.Fprintln(os.Stderr, console.Format*Message(...))for all user output - Debug Logging: Use
addInteractiveLog.Printf()for debug output - Interactive Forms: Use
charmbracelet/huhlibrary consistently
Priority: Medium
Effort: Large (due to size and lack of existing tests)
Expected Impact: Improved maintainability, easier testing, reduced complexity, better separation of concerns
AI generated by Daily File Diet