Skip to content

Module operations keep subprojects consistent with files on disk - #115

Merged
sdercolin merged 2 commits into
devfrom
feature/module-management-disk-consistency
Jul 14, 2026
Merged

sdercolin merged 2 commits into
devfrom
feature/module-management-disk-consistency

Conversation

@sdercolin

Copy link
Copy Markdown
Owner

Follow-up to #114, based on testing feedback: renaming a subproject did not rename the corresponding folder/files, leaving the project inconsistent with the disk.

Principle

Module management operations must keep subprojects consistent with the files/directories on disk, in the same way the project constructor builds them — import (name-based module matching), export, and label reloading all depend on that correspondence. Operations that change files on disk are dangerous and get a double confirmation.

Core changes

  • File.moveTo(target) added to the scripting File API (creates parent dirs, throws if target exists) + docs/file-api.md. Available to plugins too.
  • ModuleOperation.confirmation (localized message): when declared, the app shows a common confirmation dialog after the parameter dialog and before running the scripts (the "double confirm").
  • ModuleOperation.irreversible (boolean): when true, the undo history is cleared after the operation is applied, because undoing the project to a state inconsistent with renamed/deleted files is not safe (per discussion). Kept separate from confirmation so a labeler can define a confirmed-but-undoable operation (e.g. removing a TextGrid tier, which only affects the file on export). A failed or cancelled operation leaves both project and history untouched. No serialVersion bump — v3 is unreleased.
  • Auto-reload label watching follows automatically: the watcher re-registers on current-module change and resolves rawFilePath fresh, so it tracks the moved raw label file.

Bundled labelers (rename/remove are now confirmed + irreversible)

  • utau-singer (v27): rename moves the subproject folder (updates sampleDirectory/rawFilePath); remove deletes the folder recursively. Both are blocked for the root subproject (its folder is the root sample directory) and for folders that contain other subprojects' folders (per discussion: error-and-block rather than cascade). Rename/add now sort the module list by name, matching constructor ordering.
  • nnsvs (v15) / diffsinger (v4): rename moves the wav and lab files and updates every entry's sample reference; remove deletes the wav and lab files. Both validate that target file names are free on disk before touching anything.

All scripts validate fully before performing any disk operation, so a rejected operation never leaves partial changes.

Docs & tests

  • labeler-development.md: confirmation/irreversible fields, the disk-consistency principle, and the undo-history behavior.
  • Tests run the real scripts and assert the disk state: file/folder moves and deletions, stray-target and duplicate-name rejections, nested-subproject and root-subproject blocking (UTAU), and the undo-history behavior of irreversible vs reversible vs failed operations (AppStateModuleOperationTest).

A follow-up PR in vlabeler-textgrid will add a confirmation (not irreversible) to its remove operation and forbid changing the wav prefix on rename.

🤖 Generated with Claude Code

sdercolin and others added 2 commits July 14, 2026 18:28
As a principle, module (subproject) management operations should keep the
modules consistent with the files/directories on disk, in the same way the
project constructor builds them, because import/export and label reloading
depend on that correspondence. Dangerous operations are double-confirmed.

Core:
- Add `File.moveTo(target)` to the scripting File API
- Add `confirmation` to LabelerConf.ModuleOperation: when set, a common
  confirmation dialog is shown before the scripts run, and the undo
  history is cleared after the operation is applied (disk changes cannot
  be undone)

Bundled labelers (rename/remove now confirmed):
- utau-singer: rename moves the subproject folder; remove deletes it
  recursively; both are blocked for the root subproject and for folders
  containing other subprojects; rename/add now sort modules by name
- nnsvs/diffsinger: rename moves the wav and lab files and updates the
  entries' sample references; remove deletes the wav and lab files

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`confirmation` is now purely a double-confirm dialog; a separate
`irreversible` flag controls clearing the undo history after the
operation, so a labeler can define a confirmed-but-undoable operation
(e.g. removing a TextGrid tier, which only affects the file on export).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sdercolin
sdercolin merged commit 6369b65 into dev Jul 14, 2026
1 check passed
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.

1 participant