Add "Rescan directory" import prompt choice - #6945
Conversation
When beets can't confidently match an album, the interactive import prompt now offers a "Rescan directory" option alongside Skip/Use as-is/etc. It re-reads the task's directories from disk and re-runs the match, so files can be cleaned up (duplicates, junk) mid-import without restarting the whole `beet import` run. - New Action.RESCAN enum member (actions.py) and set_choice wiring (tasks.py). - New "r" PromptChoice, shown for album tasks with a toppath, added to both the "no candidates" and "pick a candidate" prompt variants since they share the same choice list (session.py). - New rescan_tasks() generator and a RESCAN branch in the user_query pipeline stage that re-extends the pipeline with freshly-discovered tasks, mirroring the existing TRACKS/ALBUMS branches (stages.py). - Tests covering added/removed/all files between the initial scan and the rescan (test_importer.py). - Documents the new choice in the auto-tagger guide (docs/guides/tagger.rst). - Changelog entry. Also syncs uv.lock's recorded package version (2.13.0 -> 2.13.1) to match pyproject.toml; it was drifting and getting silently regenerated by every uv/poe invocation, which was tripping up pre-commit's file-modification detection.
- rescan_tasks(): assert task.toppath is not None before passing to ImportTaskFactory (it's only reachable when the "r" choice was offered, which already requires a truthy toppath), and use distinct variable names for the singleton/album branches so mypy doesn't unify them into an incompatible union type. - test_plugins.py: the new built-in "r" (Rescan directory) choice collided with a test plugin's example "r" choice, which the short-letter conflict resolution silently drops in favor of built-ins. Moved the test plugin's choice to "z" and added "Rescan directory" to the expected option tuples across the four TestPromptChoices cases that exercise the album prompt.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #6945 +/- ##
==========================================
- Coverage 76.29% 76.17% -0.13%
==========================================
Files 164 164
Lines 21542 21559 +17
Branches 3334 3340 +6
==========================================
- Hits 16436 16422 -14
- Misses 4316 4353 +37
+ Partials 790 784 -6
🚀 New features to boost your workflow:
|
- rescan_tasks(): remove the singleton-mode branch. It was dead code -- the "Rescan directory" choice is only ever offered on album tasks, and album tasks only exist when the session isn't in singleton mode, so the branch could never actually run. - test_importer.py: the existing rescan tests mutated the album directory *before* calling importer.run(), so the initial scan (not just the rescan) already saw the mutated state -- the tests passed, but didn't actually exercise re-reading a directory that changed mid-import. Added ImportRescanTest._run_with_cleanup_before_first_prompt(), which performs the filesystem edit exactly when the first prompt is answered (via a choose_match side_effect), and switched all existing rescan tests to use it. - Added two more tests: rescanning a directory left with only an unreadable file (covers factory.album() returning None), and rescanning after the user splits one messy directory into two proper album subdirectories.
|
Hi! Thanks for the PR! Is there an active issue / feature request this is related to? |
Hey @henry-oberholtzer! I didn't find one at first, but I looked again and found what looks like an old issue: #166 (google-code-export/beets#384). I updated the PR description to reflect this. This may be a niche situation, but it's been plaguing me lately. It's been super helpful for me, and hopefully others will find it helpful as well. I also added an example in the PR description to show it in use. |
|
Possibly #6527 could be related |
|
@henry-oberholtzer is there anything else needed for this PR or is it good to be merged? |
Description
Fixes #166
When beets can't confidently match an album, the interactive import prompt now offers a "Rescan directory" option alongside Skip/Use as-is/etc. It re-reads the task's directories from disk and re-runs the match, so files can be cleaned up (duplicates, junk) mid-import without restarting the whole
beet importrun.Also syncs uv.lock's recorded package version (2.13.0 -> 2.13.1) to match pyproject.toml; it was drifting and getting silently regenerated by every uv/poe invocation, which was tripping up pre-commit's file-modification detection.
To Do
Example
Don McLean has multiple albums named "The Best of Don McLean". In this case 2 of them were smashed together in the same directory.