7.2 KiB
Feature Specification: Replace Command with Multi-Pattern Support
Feature Branch: 002-add-replace-command
Created: 2025-10-29
Status: Draft
Input: User description: "添加 替换(replace)命令,用于替换指定的字符串,支持同时对多个字符串进行替换为一个 示例: renamer replace pattern1 pattern2 with space pattern3 "
Clarifications
Session 2025-10-29
- Q: What syntax separates patterns from the replacement value? → A: The final positional argument is the replacement; no delimiter keyword is used.
User Scenarios & Testing (mandatory)
User Story 1 - Normalize Naming with One Command (Priority: P1)
As a CLI user cleaning messy filenames, I want to run renamer replace with multiple source
patterns so I can normalize all variants to a single replacement in one pass.
Why this priority: Unlocks the main value proposition—batch consolidation of inconsistent substrings without writing custom scripts.
Independent Test: Execute renamer list to confirm scope, then renamer replace foo bar Baz
and verify preview shows every foo and bar occurrence replaced with Baz before confirming.
Acceptance Scenarios:
- Given files containing
draft,Draft, andDRAFT, When the user runsrenamer replace draft Draft DRAFT final, Then the preview lists every filename replaced withfinal, and execution applies the same mapping. - Given filenames where patterns appear multiple times, When the user runs
renamer replace beta gamma release, Then each occurrence within a single filename is substituted, and the summary highlights total replacements per file.
User Story 2 - Script-Friendly Replacement Workflows (Priority: P2)
As an operator embedding renamer in automation, I want deterministic exit codes and reusable profiles for replace operations so scripts can preview, apply, and undo safely.
Why this priority: Ensures pipelines can rely on the command without interactive ambiguity.
Independent Test: In a CI script, run renamer replace ... --dry-run (preview), assert exit code
0, then run with --yes and check ledger entry plus renamer undo restores originals.
Acceptance Scenarios:
- Given a non-interactive environment, When the user passes
--yesto apply replacements after a successful preview, Then the command exits 0 on success and writes a ledger entry capturing all mappings. - Given an invalid argument (e.g., only one token supplied), When the command executes, Then it exits with a non-zero code and explains that the final positional argument becomes the replacement value.
User Story 3 - Validate Complex Pattern Input (Priority: P3)
As a power user handling patterns with spaces or special characters, I want clear syntax guidance and validation feedback so I can craft replacements confidently.
Why this priority: Prevents user frustration when patterns require quoting or escaping.
Independent Test: Run renamer replace "Project X" "Project-X" ProjectX and confirm preview
resolves both variants, while invalid quoting produces actionable guidance.
Acceptance Scenarios:
- Given a pattern containing whitespace, When it is provided in quotes, Then the preview reflects the intended substring and documentation shows identical syntax describing the final argument as replacement.
- Given duplicate patterns in the same command, When the command runs, Then duplicates are deduplicated with a warning so replacements remain idempotent.
Edge Cases
- Replacement produces duplicate target filenames; command must surface conflicts before confirmation.
- Patterns overlap within the same filename (e.g.,
aaareplaced viaaa); order of application must be deterministic and documented. - Case-sensitivity opt-in: default literal matching is case-sensitive, but a future
--ignore-caseoption is deferred; command must warn that matches are case-sensitive. - Replacement string empty (aka deletion); preview must show empty substitution clearly and require explicit confirmation.
- No files match any pattern; command exits 0 with "No entries matched" messaging and no ledger entry.
Requirements (mandatory)
Functional Requirements
- FR-001: The CLI MUST expose
renamer replace <pattern...> <replacement>and treat all but the final token as literal patterns (quotes support whitespace). - FR-002: Replace operations MUST integrate with the existing preview → confirm workflow; previews list old and new names with highlighted substrings.
- FR-003: Executions MUST append detailed entries to
.renamerincluding original names, replacements performed, patterns supplied, and timestamps so undo remains possible. - FR-004: Users MUST be able to undo the most recent replace batch via existing undo mechanics without orphaned files.
- FR-005: Command MUST respect global scope flags (
--recursive,--include-dirs,--hidden,--extensions,--path) identical tolist/previewbehavior. - FR-006: Command MUST accept two or more patterns and collapse them into a single replacement string applied to every filename in scope.
- FR-007: Command MUST preserve idempotence by deduplicating patterns and reporting the number of substitutions per pattern in summary output.
- FR-008: Invalid invocations (fewer than two arguments, empty pattern list after deduplication, missing replacement) MUST fail with exit code ≠0 and actionable usage guidance.
- FR-009: CLI help MUST document quoting rules for patterns containing spaces or shell special characters.
Key Entities (include if feature involves data)
- ReplaceRequest: Captures working directory, scope flags, ordered pattern list, replacement string, and preview/apply options.
- ReplaceSummary: Aggregates per-pattern match counts, per-file changes, and conflict warnings for preview and ledger output.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: Users complete a multi-pattern replacement across 100 files with preview + apply in under 2 minutes end-to-end.
- SC-002: 95% of usability test participants interpret the final positional replacement argument correctly after reading
renamer replace --help. - SC-003: Automated regression tests confirm replace + undo leave the filesystem unchanged in 100% of scripted scenarios.
- SC-004: Support tickets related to manual string normalization drop by 40% within the first release cycle after launch.
Assumptions
- Patterns are treated as literal substrings; regex support is out of scope for this increment.
- Case-sensitive matching aligns with current rename semantics; advanced matching can be added later.
- Replacement applies to filenames (and directories when
-d/--include-dirsis set), not file contents. - Existing infrastructure for preview, ledger, and undo can be extended without architectural changes.
Dependencies & Risks
- Requires updates to shared traversal/filter utilities so replace respects global scope flags.
- Help/quickstart documentation must be updated alongside the command to prevent misuse.
- Potential filename conflicts must be detected pre-apply to avoid data loss; conflict handling relies on existing validation pipeline.