Towards a better archive extractor interface
I have waited years and years for someone to make a general purpose archive extracting tool the way I can picture it. The requirements are limited to:
- Extracts all common archive formats (
.tar.bz2
,.zip
, etc.)- This kind of goes without saying, but it doesn’t pedantically “extract” a
.tar.bz2
into a.tar
file (I’m looking at you 7-zip)
- This kind of goes without saying, but it doesn’t pedantically “extract” a
- Needs no flags or subcommands or other configuration for the common use case
- Never creates more than 1 top-level file or directory per archive file
- Doesn’t add an extra layer of directory nesting when the archive only contains a single top-level directory
It is those last 2 requirements that makes me feel like some sort of UX normal-wit in a land full of half-wits. Nobody likes extracting an archive in their Downloads directory and have it barf all these generic README/Makefile/LICENSE project files everywhere. So what is the alternative today? Always get in the habit of extracting to a subdirectory, even though it adds unnecessary nesting 90% of the time? Or get in the habit of always inspecting the archive contents prior to extracting them, which is an easily automatable task?
I am sure some tool capable of this already exists in some form somewhere. But I can’t find it, so I’m writing a blog post to popularize the idea. Feel free to let me know.
Here is my attempt at the platonic ideal of archive extractor interfaces:
❯ xt
Usage: xt ARCHIVE… [DEST]
No flags needed. It does what you think it should do (or at least what I think it should do). A two letter command name is allocated for such a common task.
One point of ambiguity is where to extract the archive: the directory that ARCHIVE
is in? Or $PWD
? I am pretty sure the latter is the unix-y interpretation, so that is what I went with.
For convenience, it supports multiple archive files in one go (what else would the interface use positional params for?). Trying it out in practice, I also found it convenient to be able to say, “extract this archive over there”, hence the DEST
parameter. There is some ambiguity with the meaning of the DEST
parameter: does it mean ignore the 1-top-level file/directory rule and explicitly extract all the contents into the DEST
directory? Or does it mean extract like xt
normally does (at most 1 top-level file/directory per archive) but do it into the DEST
directory instead of $PWD
? I opted for the latter, but that may be a mistake.
An open question is what the behavior should be when piped. I didn’t have any ideas, so I left the behavior undefined for now.
I have the sketch of an implementation over here:
I must stress sketch of an idea. Use it at your own risk. It isn’t mean to be a real project (yet), but a test bed for trying the idea.