Skip to content
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

Add option to always extract to output_dir named after the archive even on single/one file #766

Open
uwidev opened this issue Feb 12, 2025 · 10 comments
Labels
enhancement New feature or request

Comments

@uwidev
Copy link

uwidev commented Feb 12, 2025

I wasn't initially aware of this behavior, but when extracting an archive that only has one element, the extracted file gets placed in the root directory (where the extract occurred) rather than a created directory named after archive. This actually resulted in problems for me when having multiple archives that just so happen to have a single file with the same name. This resulted in the filenames colliding and overwriting each other.

Would you consider having a option to always create a folder even if there is only one file?

@uwidev uwidev added the enhancement New feature or request label Feb 12, 2025
@uwidev uwidev changed the title Add option to always extract to output_dir named after the archive Add option to always extract to output_dir named after the archive even on single/one file Feb 12, 2025
@marcospb19
Copy link
Member

marcospb19 commented Feb 12, 2025

I feel you.

I've had people complain both ways in the past, cause ouch used to create unnecessary folders, or it didn't create a folder and that caused problems (your scenario).

So we ended up with this mixed behavior to try to make everyone happy but it's completely unpredictable, and I can't expect people to remember to pass a flag every time they run Ouch, with that in mind, I still think the correct answer is to change the default and not just add an option 🤔.

(For reference, in issues and in the code we refer to this as "smart_unpack".)

I'm starting to lean towards making your suggestion the default behavior, and in the future, maybe delegating smart_unpack behavior (current default) to an entry in ~/.config/ouch/config.toml (this doesn't exist rn), so people can pick what behavior they want.

I'd appreciate some help making these decisions 😆, considering all of this, do you think we should prioritize the safer defaults that cause less conflicts but might be slightly more annoying?

@killercup you've been helping recently, can I ask for your opinion about this too?

@uwidev
Copy link
Author

uwidev commented Feb 12, 2025

From my experience in using software, for general every-day use, I would prefer software to be smart by default as it automates a lot of processes that the user usually would do. However, it's when those automated processes aren't needed, or get in the way of what needs to be done.

In cases like this, I find it desirable to be able to temporarily turn off the smart features and go back to the basics so that it becomes part of the process, not the entire process. This lets people use scripts (or manual work) to trivially extend the behavior for various applications and integrations.

In my use case, I have a plugin for Yazi (a terminal file explorer) that allows me to decompress multiple archives. It will automatically say "Yes" to everything, including overwrites. I selected multiple archives and decompressed them, and a lot of files were lost because they were overwritten (because single file).

While ouch is supposed to ask the user if they want to overwrite the file, this plugin behavior is potentially destructive as it could overwrite irrelevant but important files (e.g. my_resume.pdf). The blame could be the integration of ouch into Yazi for not allowing questions on overwrite, but I think ouch could improve to prevent such destructive behaviors from occurring.

The argument could also be applied in the scenario where an archive extracts to a directory named after itself, but an existing directory already exists. I'm not too sure how ouch handles this, but to be non-destructive, I would assume it renames it with a number (i.e. ./my_resume_1/).

In short, I think prioritizing safer defaults that cause less conflicts but might be slightly less annoying is a good approach. The default should not be to overwrite, as it's destructive, and to instead append the new file/folder with a number (i.e. ./decompressed_file_1.png). If users really want to overwrite, give them an option to, but don't make it the default, as again, it's destructive; ensure the user explicitly said they want to do something potentially destructive.

@killercup
Copy link
Contributor

Not sure I have a strong opinion here. The range of options I see

  1. Never overwrite unless explicitly enabled with flag
  2. Prompt user on collision, user accepts consequences if using -y
  3. Add a new option to rename,so the prompt would be overwrite? (y/n/rename) and there would be a flag for "always overwrite"
    • also add "apply for all" option in prompt

@marcospb19
Copy link
Member

marcospb19 commented Feb 12, 2025

OH, you're using this in a script, and with --yes.

I completely misinterpreted that.

All interface decisions were made with user interaction in mind, scripting was never a priority and there is a lot of room for improving in this direction.


@uwidev I believe what you want is --dir + #322 solved.

Closing this in favor of that, let me know if you think we should re-open.

(currently --dir is working in addition to smart unpack so you get double nesting.)

Thanks you both for the input, I opened #767 to not lose track of the renaming suggestion.

@uwidev
Copy link
Author

uwidev commented Feb 13, 2025

I misinterpreted the implementation in Yazi. It turns out the integration into Yazi does not utilize ouch to extract archives (by default). during testing, the decompression functionality was exactly the same (smart unpack). Regardless, my issue still stands for ouch (I think it's very cool and want to use it more).

And the script was just an example. Maybe I want to do something like find . -type "*.zip" -exec ouch d {} \; to quickly extract all archives in my current directory, but again, we run in to the issue of overwriting files for archives that have a single file. Hence, these mixed feelings about not being able to at least toggle smart unpacking to prevent the overwriting issue.

But there raises another problem and perhaps the real problem: keeping track of which files belonged to which archive. The rename solution is a bandage fix, because now I have to deal with figuring out which file resume_1, resume _2, resume_3 originally belonged to which archive.

The --dir feature now requires me to write a script that gets the filename, make the folder, and extract to that folder. While it might solve this issue of overwriting files AND keeping track of what files belonged to which archive, I think it's a common enough workflow and desire for people to want to keep track of which file(s) belonged to which archive.

And honestly, I think that's the emerging, real issue here: not being able to keep track of which single file(s) belonged to which archive. Smart unpack will move a single file in a single-file-archive to the root directory, and if there are multiple single-file-archives, whether they overwrite or rename, you cannot reasonably tell at a glance which file belonged to which archive. Having smart unpack be a toggle to always extract to a newly created archive-folder name would solve this since you can now visually link that ./A/ belong to archive ./A.zip.

Addition:
All of these issues... they kind of feel all over the place. But as mentioned, the core issue is being able to understand that this extracted file(s) originally belonged to this archive. Extracting into a newly created folder that matches the archive name says "everything in this folder originally belonged to an archived whose filename matches this folder." Even if it's a single file, I actually would prefer a decompress to create a folder that matches the archive specifically for the fact that I can now visually link that "hey, those file(s) that you extracted just now? they are here!"

So giving that some thought, I'm actually a bit disoriented about smart unpacking. How is the user supposed to know what they're supposed to be expecting when they extract the file? They almost always don't, hence why the same-named folder method worked so well. With smart unpacking, if the archive contains a single file, there's now no way to link that file to the original archive, so good luck trying to find that extracted file in a messy directory (e.g. downloads).

@marcospb19
Copy link
Member

I highly appreciate the quality of your feedback.

If I had to summarize, I see two concerns:

  1. --dir requires a script to track the name of the archive, and that's inconvenient.
  2. Smart unpacking is disorienting if the user can't link the file to the origin archive.

Point 1

You convinced me :), we need a flag to disable smart unpack, I'll reopen this issue in a bit.

(Still think --dir should disable the smart unpack behavior, so will keep that one open.)

Point 2

I think we can solve this with communication, by improving the output.

...
[INFO] ".tmp-ouch-6Fwzdy/target/debug/deps/libparse_display_derive-1817008158c6cad1.so" extracted. (13.52 MiB)
[INFO] ".tmp-ouch-6Fwzdy/target/debug/deps/libbitflags-3bd726391f06c998.rlib" extracted. (44.99 kiB)
[INFO] ".tmp-ouch-6Fwzdy/target/debug/deps/libc-e5dcd51a2154bad7.d" extracted. (5.78 kiB)
[INFO] Successfully moved "/home/marcospb19/projets/ouch/testing/./.tmp-ouch-6Fwzdy/target" to "./target"
[INFO] Successfully decompressed archive in current directory
[INFO] Files unpacked: 4329

All of this looks... very messy.

But the important line here is:

[INFO] Successfully moved "/home/marcospb19/projets/ouch/testing/./.tmp-ouch-6Fwzdy/target" to "./target"

If instead we could have the last line say this:

[INFO] Find `archive.tar.gz` contents at "./target"

I think that would be clear enough! What do you think?

@uwidev
Copy link
Author

uwidev commented Feb 14, 2025

While I would say we could just knock two birds with one stone just by completely disabling smart unpacking, thus always moving files to a folder of the same archive name, I understand the usefulness it. I definitely think an adjustment to stdout would be appreciated.

I prefer simplicity in symbols over text.

[SUCCESS] archive.zip ➔ ./target
[FAILED] archive.zip ➔ ./target

Alternatively, use => or a similar variant. I'm also not too sure how you wish to handle logging levels.

Might I also suggest hiding the backend operations to [DEBUG], the backend operations including the temporary directory, moving, etc. At the end of the day, the user just needs to know if it succeeded and where to find the contents or if it failed. I'm aware --quiet exists, but it could be quieter?

@marcospb19 marcospb19 reopened this Mar 7, 2025
@Vonfry
Copy link

Vonfry commented Mar 9, 2025

Currently, ouch decompress -d will create a new dir with the given name always.
Could ouch keep this behaviour, and add a new option to change exec path like unzip -d so as to ignore nested dirs (no smart), which can make ouch working on some situation using unzip.

always moving files to a folder of the same archive name

This is also a great feature, and I'd like ouch can support them in seperate options, so that we can use them in different cases.

@marcospb19
Copy link
Member

@Vonfry do you want #322? Sorry I don't quite understand.

@Vonfry
Copy link

Vonfry commented Mar 10, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants