Skip to content

refactor: Move config from method parameters to InteractiveRunner struct field #30

Description

@exileum

Problem

The InteractiveRunner currently passes config as a parameter through multiple method calls, creating unnecessary coupling and inconsistent patterns compared to other structs in the codebase.

Current issues:

  • Config parameter passed through 9+ method calls in InteractiveRunner
  • Inconsistent with other structs (Runner, Migrator, PreflightChecker) which store config as fields
  • Makes method signatures verbose and error-prone
  • Harder to maintain and extend

Current pattern:

runner := migration.NewInteractiveRunner(*nonInteractive)
if err := runner.Run(cfg); err != nil { // Config passed as parameter

Proposed Solution

Refactor InteractiveRunner to store config as a struct field, consistent with existing architecture patterns.

Desired pattern:

runner := migration.NewInteractiveRunner(*nonInteractive, cfg)
if err := runner.Run(); err != nil { // No config parameter needed

Implementation Details

Files to modify:

1. internal/migration/interactive.go:

  • Add config *config.Config field to InteractiveRunner struct
  • Update constructor: NewInteractiveRunner(nonInteractive bool, cfg *config.Config) *InteractiveRunner
  • Remove cfg *config.Config parameter from all methods:
    • Run(cfg *config.Config)Run()
    • setProgressFile(cfg *config.Config, ...)setProgressFile(...)
    • handlePreMigrationSteps(cfg *config.Config, ...)handlePreMigrationSteps(...)
    • runMigration(cfg *config.Config, ...)runMigration(...)
    • handlePostMigrationSteps(cfg *config.Config, ...)handlePostMigrationSteps(...)
    • handleMigrationError(cfg *config.Config, ...)handleMigrationError(...)
    • getLastProcessedID(cfg *config.Config, ...)getLastProcessedID(...)
    • selectNewCategories(cfg *config.Config, ...)selectNewCategories(...)
    • runDryRun(cfg *config.Config, ...)runDryRun(...)
  • Replace all cfg references with r.config in method bodies

2. cmd/xenforo-to-gh-discussions/main.go:

// Before
runner := migration.NewInteractiveRunner(*nonInteractive)
if err := runner.Run(cfg); err != nil {

// After  
runner := migration.NewInteractiveRunner(*nonInteractive, cfg)
if err := runner.Run(); err != nil {

3. Update any existing tests that use InteractiveRunner

Benefits

Consistency: Aligns with existing patterns used by Runner, Migrator, PreflightChecker
Cleaner interfaces: Methods focus on their logic, not parameter passing
Maintainability: New methods automatically have config access
Less error-prone: No risk of forgetting to pass config or passing wrong instance
Single source of truth: Config stored once, accessible everywhere

Scope

  • Small, focused refactoring affecting only InteractiveRunner
  • No breaking changes to public APIs outside the migration package
  • No changes needed to other structs (they already follow desired pattern)

Acceptance Criteria

  • Config stored as InteractiveRunner struct field
  • Constructor takes config parameter
  • All methods updated to use r.config instead of parameter
  • Method signatures cleaned up (no config parameters)
  • Main.go updated to pass config to constructor
  • All tests pass
  • Pattern consistent with other migration structs

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions