Skip to content

Refactor Command::Base (700 lines): extract option factories and step/retry runner #384

Description

@justin808

Summary

lib/command/base.rb is 700 lines (largest file in the gem) mixing at least three responsibilities: Thor option factories (org_option, app_option, ... — a large block of near-identical class methods), step/progress/retry orchestration (step, step_finish, with_retry, progress IO), and shared command behaviors (validations, image/app helpers, args_join). Every command inherits all of it, and the size is masked by rubocop disables rather than addressed — lib/ carries 87 rubocop:disable comments overall (verified count), concentrated in the biggest files.

Why it matters

  • High blast radius: nearly every PR touches or inherits from this file, so unrelated changes conflict here.
  • The option factories are pure boilerplate that could be declarative.
  • Step/retry logic is exactly the kind of thing that should be unit-tested in isolation (it wraps every long-running operation) but can't be, cleanly, while embedded in Base.

Proposed approach (slice per PR, no behavior change)

  1. Extract Command::Options — move the option factory class methods into a module/registry; Base keeps thin delegation so command classes don't change.
  2. Extract a StepRunner (step/step_finish/progress/retry) with its own unit spec; Base delegates.
  3. Re-evaluate what remains in Base; remove any rubocop:disable Metrics/* that are no longer needed rather than carrying them forward.

Top-10 largest files for context (health review, 7c96df9): base.rb 700, run.rb 601, core/controlplane.rb 575, github_flow_readiness_service.rb 477, core/config.rb 405, cpflow.rb 393 — this issue covers base.rb only; controlplane.rb has its own issue (see tracking epic).

Acceptance criteria

  • base.rb under ~400 lines with option-building and step-running in dedicated, unit-tested files
  • No command class needed changes beyond requires (public interface preserved)
  • Net reduction in rubocop:disable Metrics/* count in touched files
  • Full fast suite green in CI (behavior-preserving refactor)

Priority / size / dependencies

P3 — valuable but only safe after the correctness work. Blocked by #380 (Shell.abort → exceptions rewrites Base error paths; do not refactor around code about to change) and #381 (args_join fix lands first so the refactor moves tested code). Benefits from #379 (shell.rb/Base-adjacent specs).


Origin: automated codebase health review, 2026-07-02, against 7c96df9.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low priority / cleanupenhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions