Skip to content

Scan, DryRun, Deduplicate and Stats each copy the path prompt and the scan→hash→group pipeline, so every fix to that path must be made four times #157

Description

@matt-edmondson

What's wrong

The four verbs in FileDeduplicator/Verbs/ duplicate two blocks almost word for word.

  • The path prompt. ValidateArgs() in Scan.cs:14-30, DryRun.cs:14-30, Deduplicate.cs:14-30 and Stats.cs:15-31 is the same method: PathString is "." or "" → prompt → Console.ReadLine()?.Trim() → abort when the input is empty.
  • The pipeline. Steps 1-3 of each Run (Scan.cs:37-61, DryRun.cs:37-61, Deduplicate.cs:37-61, Stats.cs:38-56) are the same sequence: FileScanner.ScanForFiles → print the count → return on zero → FileHasher.HashFiles → Deduplicator.GroupByHash → Deduplicator.FindDuplicates. For Scan and DryRun, lines 14-61 differ only in the verb type and one banner line.

On top of that, Scan.cs:64-83 renders its own KEEP/DELETE listing and wasted-space total instead of using DuplicateReport.PlanDeletions. DuplicateReport's own remarks say all verbs should build this listing in one place so they cannot drift apart.

Why it matters

Several open issues change exactly this duplicated code. Each fix has to land four times, identically, or the verbs start to behave differently:

If a fix reaches three verbs and misses the fourth, one verb reports a different set of duplicates, or accepts different input, than the others. The codebase already treats that kind of divergence as its worst defect: DryRunEquivalenceTests exists because DryRun has to predict Deduplicate exactly.

Suggested fix

  • Move the prompt into BaseVerb<T>, and have each verb supply only its prompt text (for example, through an abstract PromptText property).
  • Add one method, for example DuplicateFinder.Find(AbsoluteDirectoryPath) -> ScanResult, that returns the scanned files, the hashes and the duplicate groups. Each verb calls it once and keeps only its own reporting.
  • Make Scan render from DuplicateReport.PlanDeletions, like DryRun and Deduplicate do. It can keep its [KEEP]/[DELETE] suffix format.

Acceptance criteria

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions