Skip to content

fix(template): clarify file collision handling#1150

Merged
chhoumann merged 8 commits intomasterfrom
1139-bug-leading-zeros-are-stripped-from-template-filename-when-starting-with-tt0xxxx
Mar 14, 2026
Merged

fix(template): clarify file collision handling#1150
chhoumann merged 8 commits intomasterfrom
1139-bug-leading-zeros-are-stripped-from-template-filename-when-starting-with-tt0xxxx

Conversation

@chhoumann
Copy link
Owner

@chhoumann chhoumann commented Mar 12, 2026

Fix template choice file-collision handling and make the settings easier to understand.

This PR fixes the runtime bug where QuickAdd could eagerly increment the target path even when the setting implied it should prompt first. It keeps the existing trailing-number behavior for compatibility, adds an identifier-safe Append duplicate suffix mode, and preserves zero padding when incrementing existing numeric suffixes.

On the settings side, I reworked the existing-file UI so it reflects the actual outcomes instead of mixing file updates, new-file creation, and no-op behavior in one flat list. The top-level choice now separates Ask every time, Update existing file, Create another file, and Keep existing file, and only shows the follow-up action picker when that category needs more configuration.

I considered keeping the earlier combined toggle/dropdown row, but it overloaded one setting with too many concepts and made the action meanings hard to scan. The current version is a little more explicit, but it better matches what the runtime actually does.

Reviewer notes:

  • stored values remain backward-compatible; the increment mode still persists as Increment the file name
  • prompt labels are now decoupled from stored values so the UI can use clearer wording
  • docs were updated only in docs/docs/..., not versioned snapshots
  • verified with bun run test, bun run build-with-lint, and Obsidian dev-vault reload/runtime checks

Fixes #1139


Open with Devin

Summary by CodeRabbit

  • New Features

    • Enhanced template file conflict handling with four behaviors: Ask every time, Update existing file, Create another file, Keep existing file.
    • New naming strategies when creating files: Increment trailing number and Append duplicate suffix.
    • Updated template settings UI with category-driven selection for file-exists behavior.
  • Documentation

    • Template docs and examples updated to reflect the new behaviors and naming strategies.

@vercel
Copy link

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
quickadd Ready Ready Preview Mar 13, 2026 9:31pm

@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Refactors template file-existence conflict handling into a centralized policy model. Adds src/template/fileExistsPolicy.ts, replaces legacy constants and per-choice flags with fileExistsBehavior, updates engines, UI, migrations, and tests to use category/mode-driven collision resolution (prompt, update, create, keep).

Changes

Cohort / File(s) Summary
Policy Module
src/template/fileExistsPolicy.ts, src/template/fileExistsPolicy.test.ts
New centralized policy defining mode/category IDs, resolution kinds, mode lookups, legacy mappings, and collision resolvers (increment, duplicate suffix); extensive unit tests for modes and name-resolution behavior.
Engine Logic
src/engine/TemplateChoiceEngine.ts, src/engine/TemplateEngine.ts, src/engine/TemplateChoiceEngine.collision.test.ts
TemplateChoiceEngine now queries fileExistsPolicy for selected mode and delegates to applyFileExistsMode/resolvers; removed legacy incrementFileName from TemplateEngine; added collision tests covering prompt/auto flows and create/modify/reuse outcomes.
UI / Types / Builder
src/gui/ChoiceBuilder/templateChoiceBuilder.ts, src/types/choices/ITemplateChoice.ts, src/types/choices/TemplateChoice.ts
Replaced boolean+constant-driven UI with category-driven dropdowns and dynamic mode options; ITemplateChoice/TemplateChoice now use fileExistsBehavior: TemplateFileExistsBehavior.
Migrations & Normalization
src/migrations/consolidateFileExistsBehavior.ts, src/migrations/helpers/normalizeTemplateFileExistsBehavior.ts, src/migrations/incrementFileNameSettingMoveToDefaultBehavior.ts, src/migrations/*.test.ts
Added migration to normalize legacy fileExistsMode/setFileExistsBehavior into new fileExistsBehavior, plus helper to map legacy settings and tests validating migrated structures.
Settings / Preflight
src/settings.ts, src/preflight/runOnePagePreflight.selection.test.ts
Introduced consolidateFileExistsBehavior migration flag in default settings; updated preflight/test expectations to use fileExistsBehavior: { kind: "prompt" }.
Constants Removal & Docs
src/constants.ts, docs/docs/Choices/TemplateChoice.md, docs/docs/Examples/Template_CreateMOCNoteWithLinkDashboard.md
Removed legacy public file-exists constants/choices; updated docs/examples to describe new behavior categories and naming strategies (e.g., "Create another file" / "Increment trailing number").
Tests Removed/Updated
src/engine/templateEngine-increment-canvas.test.ts, src/engine/TemplateChoiceEngine.notice.test.ts
Deleted legacy incrementFileName tests and updated notice tests to use fileExistsBehavior object.
Misc Test Defaults
src/engine/*.test.ts
Updated various test mocks to include new consolidateFileExistsBehavior migration flag and adjusted choice defaults.

Sequence Diagram

sequenceDiagram
    actor User
    participant TemplateChoiceEngine
    participant fileExistsPolicy
    participant GenericSuggester
    participant Vault

    User->>TemplateChoiceEngine: Request create with targetFilePath
    TemplateChoiceEngine->>Vault: exists(targetFilePath)?
    alt File exists
        TemplateChoiceEngine->>fileExistsPolicy: getBehaviorCategory / getSelectedFileExistsMode
        alt Behavior == prompt
            TemplateChoiceEngine->>GenericSuggester: show collision options
            GenericSuggester->>User: present modes
            User-->>GenericSuggester: select mode
            GenericSuggester-->>TemplateChoiceEngine: modeId
        end
        TemplateChoiceEngine->>fileExistsPolicy: applyFileExistsMode(modeId)
        alt ResolutionKind == createNew
            TemplateChoiceEngine->>fileExistsPolicy: resolveCreateNewCollisionFilePath(targetFilePath)
            fileExistsPolicy->>Vault: exists(candidatePath)?
            loop until free
                fileExistsPolicy->>fileExistsPolicy: compute next candidate
                fileExistsPolicy->>Vault: exists(nextCandidate)?
            end
            fileExistsPolicy-->>TemplateChoiceEngine: collisionFreePath
            TemplateChoiceEngine->>Vault: create file at collisionFreePath
        else ResolutionKind == modifyExisting
            TemplateChoiceEngine->>Vault: update existing file (append/overwrite)
        else ResolutionKind == reuseExisting
            TemplateChoiceEngine->>Vault: open existing file
        end
    else File does not exist
        TemplateChoiceEngine->>Vault: create file at targetFilePath
    end
    TemplateChoiceEngine-->>User: return created/opened file
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

released

🐰
I hopped through names both old and new,
Added rules to know just what to do,
Increment, suffix, prompt, or keep—
Now files find beds without a peep!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(template): clarify file collision handling' directly summarizes the main change, which is reworking template file collision handling with a new policy-driven approach and clearer UI categories.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #1139 by: (1) preserving zero padding in incremented filenames via resolveIncrementedCollisionPath logic, (2) adding 'Append duplicate suffix' mode for identifier-safe collision handling (like tt0780504), and (3) fixing the bug where collision logic ran prematurely by implementing a policy-driven two-step flow that respects configured behavior (prompt vs. auto).
Out of Scope Changes check ✅ Passed All changes are scoped to template file collision handling: removed legacy constants/methods, introduced fileExistsPolicy module, updated TemplateChoiceEngine and UI builder, added comprehensive migrations and tests. No unrelated refactoring or feature creep detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 1139-bug-leading-zeros-are-stripped-from-template-filename-when-starting-with-tt0xxxx
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chhoumann chhoumann marked this pull request as ready for review March 12, 2026 21:09
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 12, 2026

Deploying quickadd with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0f8fa2e
Status: ✅  Deploy successful!
Preview URL: https://b6e25eeb.quickadd.pages.dev
Branch Preview URL: https://1139-bug-leading-zeros-are-s.quickadd.pages.dev

View logs

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

chatgpt-codex-connector[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@chhoumann chhoumann merged commit 5ea1db0 into master Mar 14, 2026
5 checks passed
@chhoumann chhoumann deleted the 1139-bug-leading-zeros-are-stripped-from-template-filename-when-starting-with-tt0xxxx branch March 14, 2026 11:12
@chhoumann chhoumann restored the 1139-bug-leading-zeros-are-stripped-from-template-filename-when-starting-with-tt0xxxx branch March 14, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Leading zeros are stripped from template filename when starting with tt0xxxx

1 participant