Log a message when changing filenames to avoid conflicts
- Dominant language
- Python
- Stars
- 15.7k
- Forks
- 2.1k
- Avg merge
- 4d 21h
- Merged PRs (30d)
- 31
Description
### Summary ###
When moving an item with the `move` command, if a file that's not registered with beets exists in the destination directory, beets gives the file a unique filename, but neglects to tell the user that the move didn't go as planned (even if in verbose mode), and continues to claim that the file was moved if the command is run again, even if the file isn't moved. If the command is run with the `-p` flag in order to cause a dry run, beets claims that it is moving the file to the original file name, not the unique-ified name.
### Setup ###
* OS: Linux 4.16.5-1-ARCH
* Python version: Python 3.6.5
* beets version: 1.4.6 [no plugins; default options]
### Reproduction ###
1. With an empty library, import an item.
2. Change the library directory in the config to point to a new, empty directory.
3. Create a dummy file in the new directory mirroring the actual music file. For example, if the real file is in `library/DummyArtist/DummyAlbum/DummySong.mp3`, and your dummy library is `newlibrary`, create the file in `newlibrary/DummyArtist/DummyAlbum/DummySong.mp3`. The content is irrelevant. It can be identical, empty, or corrupt.
4. Issue `beet -vv move -p`. Notice that beets declares that it is moving the song to the same location as the dummy file, and doesn't mention any problem with this
5. Issue `beet -vv move`. Beets moves the item to `newlibrary/DummyArtist/DummyAlbum/DummySong.1.mp3`, and doesn't mention it, even with verbose mode enabled.
5. Issue `beet -vv move -p` and `beet -vv move` again. In both cases, beets claims that it is moving the file, despite not moving the file at all.
### Expected / Suggested Behavior ###
I understand why beets is doing what it is doing, but I believe that leaving the user in the dark about it can only cause confusion. I would suggest that beets do one of the following instead:
* On a move conflict, provide a dialog to the user, allowing them to choose, to skip the file, overwrite it, or use a unique name. This would essentially force the user to make a decision and enable them to deal with it easily, from withing the beets interface. It might get a little annoying if the user wants the behavior in the third bullet, or without options to assume an answer (e.g. overwrite all)
* On a move conflict, print a warning to console specifying where the error occurred. This is the closest to what beets currently does, and seems like a simple solution that gives the most control to the user without being too silent or interrupting an otherwise one-click action. If the user wants to deal with the problem themselves, however, they need to manually remove the conflicting item, which might be annoying if there are hundreds of conflicts
* If the file is already in the location it would be moved to (but not where it should be), don't list the file as being moved by the `move` command. This would allow users who don't care what goes on in their beets directory as long as it works to go on with life without knowing that there was a problem, as opposed to having potentially hundreds of false move messages when consolidating their libraries
### Notes ###
I encountered this problem while attempting to deal with #2747. I accidentally ran `beet import -A $mylibrary` without the flag to import as singletons, and because of the way my paths were set up, and some commands attempting to fix this issued with a poor understanding of how Beets works, ended up with my entire library duplicated in this way. My specific situation might be uncommon, but I imagine that the ability to deal with conflicts in general might be useful.
Contributor guide
Research direction
Start by reproducing the conflict with `beet -vv move -p` and then `beet -vv move`, using the dummy destination file described in the issue. Trace the `move` command's reporting for dry runs, renamed destinations, and repeated moves; done means the user is accurately told what destination is used and whether a move actually occurs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100