C.W.K.
Stream
Lesson 02 of 04 · published

Batch Rename Is a Plan Builder

~12 min · batch-rename, plan-builder, preview

Level 0Lost in Finder
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Renaming three hundred files at once is not a special power. It's three hundred ordinary plans with one preview."

Power Is Not a License to Bypass

Batch Rename feels like it should be a fast lane — you're renaming hundreds of files, surely it needs its own optimized path straight to FileManager? That instinct is exactly the one Waygate refuses. Batch Rename is a plan builder: it composes the rename rule into a set of proposed changes and submits normal, immutable operation plans through the same engine as a single rename. The power is in the batching UI, never in bypassing the safety machinery.

The Preview Is a Frozen Contract

Before anything changes, Batch Rename shows a complete preview: for every file, the current name and the proposed new name, plus the expected identity of each target. That preview is frozen intent. If the world changes between preview and apply — a file gets renamed by another app, a collision appears — the apply doesn't silently push through; it forces a fresh preview against current reality. What you approved is what runs, or you approve again.

Case and Collision Are Checked Up Front

Batch renames have their own traps, and the preview catches them: two files that would collapse to the same new name, a case-only change on a case-insensitive volume, a target that already exists. The preview surfaces these as problems to resolve before submission, not surprises discovered halfway through. Then each rename goes through the engine as an immutable plan with per-item journal evidence — so even the batch is recoverable item by item.

Batch Rename is a plan builder, not a privileged shortcut. It freezes a full preview of old/new names and expected identities, forces a new preview if apply-time conditions changed, and submits normal immutable plans through the one engine. Renaming many files at once never means escaping journaling, validation, or per-item evidence.
Order matters in a batch, and the preview makes it visible. Renaming file A to B while another file is already named B, in the same batch, is a collision the preview must show before anything runs — the safe resolution might be a two-step rename through a temporary name. A batch tool that hides ordering hazards until apply time is how 'rename all my photos' quietly loses one.

Code

Rule -> preview -> ordinary plans (no bypass)·swift
struct RenamePreviewRow {
    let target: LocationReference
    let currentName: String
    let proposedName: String
    let expectedIdentity: ResourceID
    var problem: RenameProblem?   // collision, case-only, duplicate-target...
}

func buildBatch(_ rule: RenameRule, over items: [LocationReference]) -> [RenamePreviewRow] {
    let rows = items.map { rule.preview(for: $0) }
    return validateForCollisionsAndCase(rows)   // surface problems BEFORE apply
}

func applyBatch(_ rows: [RenamePreviewRow]) async {
    for row in rows where row.problem == nil {
        let plan = OperationPlan(kind: .rename, sources: [row.target],
                                 destination: row.target.renamed(row.proposedName),
                                 expected: [row.expectedIdentity])
        await engine.submit(plan)   // <- the SAME engine as a single rename
    }
}

External links

Exercise

Design a batch rename that adds a sequence number: photo.jpg -> photo-001.jpg, photo-002.jpg, and so on. Now find the hidden collision: what if one of the source files is already named photo-001.jpg? Describe what the preview must show and what ordering the engine needs so the batch never overwrites a file it's about to rename.
Hint
If photo-001.jpg already exists among the sources, naively renaming another file to photo-001.jpg would collide with — or overwrite — a file the batch itself is going to rename later. The preview has to flag it, and the safe execution renames through temporary names first (everything to a temp, then to final), so no in-batch target is ever occupied by an about-to-move file. Ordering is the whole game.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.