-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move files to trash instead of deleting via new config option #3796
Conversation
FYI:
|
I saw that notice before and selected the project (Trash) as an example nonetheless. Reasons include:
|
Yo! This is a good idea. Can I make these suggestions, however?
|
Hey Adrian!
Certainly. They were related enough that it seemed sensible to submit them together, but I'm happy to separate them.
Sure, I can see the benefit in that. I'll have another pass at it. |
On some (most?) Linux systems, the If not, we could mention in the docs that creating a script like this can enable the feature on Linux:
|
Nice; great point. All the more reason we should probably make the command configurable—so one could just configure it directly to do |
293415c
to
1946241
Compare
70e124d
to
146a587
Compare
Hey @sampsyo. Based on your feedback, I addressed the points you raised:
I removed the documentation changes relating to backups, which I will submit in a separate pull request.
The executable is now configurable via the Anything left to do here before merging? ✨ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a few remarks, I think the most important one would be the handling of invalid config values. I haven't been part of the discussion on trashing and the backup recommendation so far, so if this has been discussed before feel free to dismiss my comments.
It might be useful to grep the codebase for uses of util.remove
; I could imagine it being used on temporary files that should not go to trash.
146a587
to
26f1d31
Compare
Hey @wisp3rwind. Thanks for the comments. I did grep through the code, and I didn't see any areas in which |
I've just been doing the same, but I do think that there are a few cases in |
26f1d31
to
c21d822
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left one more comment about a slight simplification that can be made; I'll have a look at callers which need to opt-out of trash handling later today.
Otherwise, this is looking good 👍
Enhance the util.remove() function to move the specific file to trash by default *if* there is a `trash` executable on $PATH. Otherwise, the file is deleted. This provides a safer user experience without adding yet another Python dependency to the project. The executable used for file removal operations (default: `trash`) can be configured via the new `remove_command` configuration option.
c21d822
to
191526c
Compare
Hi, folks! Thanks for making so much progress on this; it looks fantastic so far. Just to check, however: it looks like the current implementation will attempt to use It also occurs to me that the current structure of the Line 793 in 84f6d37
|
Hey Adrian! Thanks for the kind words.
Yes — the idea is that this is a safer default for end users, eliminating potential foot-guns caused by unexpected and/or aberrant behavior, which can often result in catastrophic data loss. (See related linked issue in the description.)
I think you might be reading it wrong? There shouldn't be any errors in that situation. If
I believe that (1) the safest default is the best default and (2) this safety outweighs preserving the less-safe current behavior. Plus, it only changes the behavior for current users who have gone out of their way to install a |
Personally, I agree with @nathdwek in #149
and TBH, I don't care what the default is, which is why I didn't press the point here. For my own workflow, I'm rarely in a situation where beets is deleting files anyway. This feature request (and the alleged footguns when using beets) seems to be brought up persistently (by a small number of people, however), so if trashing by default helps calming the waves, I'll just add
I think @justinmayer is right in that this is currently already a silent fallback. I was suprised about that, too, see #3796 (comment), but as outlined above, I won't be investing energy into discussing this point. Ideally of course, that would be polled on the forum.
I'm not sure that is useful: In the example you made, there is still a In any case, this needs to go with #3876, lest we litter the trash with unexpected temporary files. I'd appreciate if someone (...) could have a brief look whether the additional commit in that PR looks sensible. |
Awesome; thanks. Glad that I totally misread the fallback thing! Sorry about that. As for the other two issues:
|
Unless we're sure that beets' trash-related code is 100% bug-free, it strikes me as arrogant to not make recycle bin / trash the default. #2499 Add in an unbounded number of plugins that may also want to delete files, and it's a big source of errors for no benefit. If your OS is that good, just automate the trash removal. I think mine does that already so there's no overhead to me as an end user, just more safety. I skimmed the above conversation, so maybe I missed it: what is gained by not having trash functionality? If it just tries to call an outside program |
My argument for having this off by default boils down to the principle of least astonishment: is that beets is a Unix CLI tool, and the "normal" thing for a Unix CLI tool to do is to delete files when you type the So I'm very enthusiastic about the functionality being available, but I still think it should be off by default. |
Having thought about it again, I probably care more than I realised, and I think I'm seeing a clear path now on how this should be approached:
The basic idea behind this would be that we can always change the defaults to a "safer" value, but should really avoid doing the reverse (e.g. because we found some regression). The latter would break expectations of anyone who comes to rely on trashing over direct deletion. I'm also under the impression that we're not going to agree on the default here, and I'd like to avoid blocking to merge this PR. There's of course the risk that when reviewing that new issue we will not be able to resolve the disagreement.
I didn't even think about those safeguards, sounds like a good reason 👍
I'm not sure how large the actual risk is that there's indeed another program named
Yes, I now agree that trash should be opt-in, for the reasons scattered throughout this comment.
I believe that having it in
That seems like a contradiction. I'm quite confident about the current "trash-related" PR. I'm by no means 100% sure that there's not a problem with an edge case we didn't think about (where, say, beets crashes and leaves you with some half-imported items in the database). There is a value to introducing it somewhat conservatively.
There is a very significant benefit: We should not ever move temporary files that we created ourselves to the trash. Such files with semi-random names popping up in the recycle bin are absolutely a cause for confusion, and exactly that will happen when implementing
In addition to @sampsyo's answer, I think there simply is no solution here that will suit everyone's workflow out of the box. Why should "absolutely everything needs to go to the trash" be the only viable way forward? FWIW, if we don't go by the steps outlined above, I think this PR needs one more change: I did account for direct calls to |
Windows doesn't have that "rm = instant delete" paradigm to my knowledge, even in the CLI. Admittedly, Windows is half-supported right now (who on the dev team is enthusiastically using beets on Windows?). IIRC, there has been some discussion of just moving to the Windows Subsystem for Linux. For temp files, Windows has the temporary files folder. This is all much lower level than I'm familiar with, but for temp files wouldn't the program be doing this anyway? https://en.wikipedia.org/wiki/Temporary_file#Creation
Fair enough. I guess what I mean is, what does this look like 1-3 years from now? For me, trash-by-default is the most user-friendly and indeed "least astonishing" behavior. rm == delete on unix, but for someone not used to the unix command line (ex. Windows user), it could just as easily be remove. Even for me, knowing the rm command on Linux, I wouldn't have guessed that it deletes files irreversibly. That's not something I'm used to non-system programs doing (with limited Linux command line experience). Like, nothing I can do in Firefox Ubuntu will end with me deleting files without stopping in the trash first. It's splitting hairs though, if the config supports trashing, I can't complain much. In my 4 years of using beets, I've had bugs cause beets to remove files that shouldn't have been removed, but I've never thought "I need these music files off my PC now, no backsies". |
Thanks, @wisp3rwind; that plan sounds great!
That's a good reason! I too am not exactly sure what to do about that
Also a very good point (and a reason to keep
Unfortunately, @RollingStar, I think there's a chance that these frustrating accidental deletions would not have been solved by a "trash" precaution. It's just as easy for a bug in beets to lose data by overwriting a file via a move, for instance, that would have slipped by this specific change to the |
Now you could argue that file moves should do backups first :) I don't have an overview over the situations we do moves in, so that might actually be worth discussing in a future issue/PR. In any case, let's get the uncontroversial part of the current PR merged. @justinmayer, how does the plan above sound to you? Do you have the time and energy to modify the defaults accordingly? |
@wisp3rwind: Assuming we're talking about the first two bullets points in your previous comments, then yes — I should be able to make time to update this PR with those changes. I'm traveling at the moment but will do my best to get that done by the end of June. |
Yep, exactly, that'd be great! Don't hurry, enjoy the travelling! |
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward? This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
@sampsyo: Can you re-open this? I'll work on it this week. |
Certainly! |
Description
While it doesn't happen often, some folks have had experiences in which Beets unexpectedly deletes a song. All software has bugs, and data loss sometimes happens. But as someone who once lost an entire music collection due to data loss (not Beets-related), I think we should do everything we can to prevent unexpected file deletion, regardless of whether that happens via bugs or user mistakes.
This pull request enhances the
util.remove()
function to move the specified file to the trash by default if there is atrash
executable on$PATH
. Otherwise, the file is deleted. This approach provides the option for a safer user experience without adding yet another Python dependency to the project.The executable to be used for these safer file removal operations (default:
trash
) is configurable via a newremove_command
configuration option.Fixes #149 #2499