Edit files in archives

Any wishes
Post Reply
warpkanal
Posts: 75
Joined: Mon Jan 30, 2017 5:24 pm

Edit files in archives

Post by warpkanal » Thu Feb 02, 2017 9:55 am

Is my impression correct that NC doesn't yet support editing files inside an archive?
(I often tweak some code archives by just editing some smaller config files inside them...)

JayB
Posts: 140
Joined: Sun Jan 08, 2017 4:38 pm

Re: Edit files in archives

Post by JayB » Thu Feb 02, 2017 10:36 am

Would be great, but is this even possible? To my knowledge this depends on the software with which you want to edit the file within the archive, e.g. a .config file. With TextEdit I can open a file within a zip archive, but edits are not saved. With BBEdit I cannot open or edit a file within a zip archive directly, but I can open the whole zip archive with BBEdit, then select the contained file in BBEdit's sidebar, and then edit and successfully save the whole updated zip again. The vim CLI software is also supposed to be able to edit files within zip archives. (Haven't tested with other archive formats like tbz, tgz, 7z, txz etc.)

So it seems to be dependent on what the editor software can do, and I assume they also do some secret temporary unzipping and rezipping, either themselves or by calling an equivalent of the zip -u comannd.

NC would surely need to unzip the file that is being accessed, put it in a temp location, and then update the zip archive after editing. Possible? Or is there a better way?

User avatar
mike
Posts: 775
Joined: Thu Jul 16, 2015 5:35 am
Location: Exeter, UK

Re: Edit files in archives

Post by mike » Thu Feb 02, 2017 10:48 am

warpkanal wrote:
Thu Feb 02, 2017 9:55 am
Is my impression correct that NC doesn't yet support editing files inside an archive?
(I often tweak some code archives by just editing some smaller config files inside them...)
Edition of existing archives is a very-very complex task, which contains many absolutely unobvious pitfalls and is capable of bringing myriads of unexpected side effects. It was my deliberate decision to avoid even trying to implement this stuff.
JayB wrote:
Thu Feb 02, 2017 10:36 am
So it seems to be dependent on what the editor software can do, and I assume they also do some secret temporary unzipping and rezipping, either themselves or by calling an equivalent of the zip -u comannd.
NC would surely need to unzip the file that is being accessed, put it in a temp location, and then update the zip archive after editing. Possible? Or is there a better way?
In fact, to open an archived file with some external editor, NC has to extract it from archives and place to a temporary location.

warpkanal
Posts: 75
Joined: Mon Jan 30, 2017 5:24 pm

Re: Edit files in archives

Post by warpkanal » Thu Feb 02, 2017 11:15 am

I can imagine that this brings tons of edge cases, would be fine for me if it would only work for the straight forward cases :)
Still it is (in my opinion) one of the important/useful features of a good filemanager (and in fact is implemented in the more advanced filemanagers like TC or Crax, and looks to me like Forklift3 will support this as well)

(@JayB: it's not editor dependent, as mike wrote, the respective file needs to be extracted anyway to a temp location, from there any editor can read/write that file)

JayB
Posts: 140
Joined: Sun Jan 08, 2017 4:38 pm

Re: Edit files in archives

Post by JayB » Thu Feb 02, 2017 11:57 am

That's not what I said. What I said was that independent of your file manager, if you have the right editor, you can edit files in archives, and save & update the archive. It goes without saying that any zipped file you want to edit needs to be extracted to a temp location first, whether by the 3rd party editor, by yourself, by the file manager. If you want the ability to edit zipped files with any editor, you need to have a file manager that does the unzipping, temporary location creation, archive updating. And yeah, that's probably quite complicated. (Finder can't do it… but hey, it's the Finder. ;) )

warpkanal
Posts: 75
Joined: Mon Jan 30, 2017 5:24 pm

Re: Edit files in archives

Post by warpkanal » Thu Feb 02, 2017 12:08 pm

@JayB: Ah, ok, misunderstood you, sorry :)
If I could vote, I'd vote for having a basic implementation of this feature, it's just sooo handy.

JayB
Posts: 140
Joined: Sun Jan 08, 2017 4:38 pm

Re: Edit files in archives

Post by JayB » Thu Feb 02, 2017 8:42 pm

Most of the stuff should be easy to do with a script: make a temp directory next to the archive (or in /tmp), unzip a specific file from the archive, calculate checksum, open that file (either in the default app or in an app of the user's choosing), monitor the app by pid (break monitor loop on quit), monitor file access (either lsof or iosnoop/dtrace etc.), monitor file save & close (break on positive grep), calculate new checksum, compare old and new checksum, if different, update archive with edited file; notify & end script.

The only downside is that lsof is a little strange on macOS, e.g. I can't trace documents opened in TextEdit (???), and iosnoop & Co. need to be run as root, which I don't mind, but lots of people do for "standard" operations like updating a zip archive.

So all that stuff should be easy to implement in C++ or similar languages. If it's easy in the shell, it's easy almost anywhere else.

The biggest problem, however, is the fact that Nimble Commander shows the archive contents as a VFS, and the path you get is just a relative path to the archive's "root" folder; you can't ascertain the path to the surrounding archive, i.e. /path/to/archive.zip … you only get /mysuper.config as a path, and you can't do anything with that. It would probably be easy for Nimble Commander to "know" the actual path to the archive, but for a shell script to detect the actual path is (probably?) impossible.

User avatar
mike
Posts: 775
Joined: Thu Jul 16, 2015 5:35 am
Location: Exeter, UK

Re: Edit files in archives

Post by mike » Mon Feb 06, 2017 7:07 am

JayB wrote:
Thu Feb 02, 2017 8:42 pm
Most of the stuff should be easy to do with a script: make a temp directory next to the archive (or in /tmp), unzip a specific file from the archive, calculate checksum, open that file (either in the default app or in an app of the user's choosing), monitor the app by pid (break monitor loop on quit), monitor file access (either lsof or iosnoop/dtrace etc.), monitor file save & close (break on positive grep), calculate new checksum, compare old and new checksum, if different, update archive with edited file; notify & end script.
The problem is about the complication of states (https://en.wikipedia.org/wiki/State_(computer_science)) in which the whole system can be at the moment. You surely can implement something as a bunch of shell scripts, but IMHO the whole point of using a single application is about integrity and coherence, and that's what is the most difficult to maintain.
That's without even mentioning different formats, their options, security/encryption, solid archives, archives on read-only media, handling of possible errors that might occur in the middle of archive updating, etc, their name is Legion.

I'm not trying to find an excuse here, just explaining why it's not the most wise decision to mix file management duties with a specific task from a separate area. If it's frequently required to change some files inside archives, I'd rather thought about the process itself in the first place - why is that required? After all, they are called "archives" for reason.

warpkanal
Posts: 75
Joined: Mon Jan 30, 2017 5:24 pm

Re: Edit files in archives

Post by warpkanal » Mon Feb 06, 2017 9:51 am

I'm not trying to find an excuse here, just explaining why it's not the most wise decision to mix file management duties with a specific task from a separate area. If it's frequently required to change some files inside archives, I'd rather thought about the process itself in the first place - why is that required? After all, they are called "archives" for reason.
My purpose: sometimes I deal a lot with java archives (jar and war files). As I know about the structure of these archives it's often way more simple to modify certain descriptors (for testing/debugging reasons) in such files instead of replicating the build process that would otherwise re-generate these files.
I would not agree that modifying archives is about mixing filemgmt duties with a specific task, I mean there's a reason why nearly all filemanagers including NC have archive handling (at least read-only navigation, compressing, ...) fully integrated, so I'd view archive handling as an integral part of a filemanager. Being able to not only browse/compress/uncompress but also modify archives is something I'd just consider as the next natural feature in a filemanagers archive handling capabilities.

However I fully understand your doubts in getting archive modification done right. Will see if I can live without it :)

JayB
Posts: 140
Joined: Sun Jan 08, 2017 4:38 pm

Re: Edit files in archives

Post by JayB » Mon Feb 06, 2017 10:59 am

Wouldn't it then be the easiest thing to just change the path that Nimble Commander gives the user when he has selected a file in a compressed archive (i.e. in a VFS)?

Example: I have a zip archive with the path /Users/JayB/Downloads/Safari/MyArchive.zip … I select it, hit return, and NC shows me the archive contents … in the archive there's a file at relative path /docs/ReadMe.txt … at the moment, when I copy the path of the txt file, NC will give me /docs/ReadMe.txt … but in a revision, it would give me the path of /Users/JayB/Downloads/Safari/MyArchive.zip/docs/ReadMe.txt

That way we would have a pseudo-path that we could pass on to a script, which we can split at the first instance of ".zip/" looking from left to right, giving us two paths as strings, i.e. the one to the archive, and the relative one within the archive. Then it would be easy to use the first part to access the archive, with zip, unzip, update etc., and to use the second one to select individual files in a zip archive for unzipping/editing/updating.

Not sure if that's easily possible. (?) Kinda like, when the user selects "Copy path", NC checks if VFS=true for currentSelection then path="$PathToVFS$relativeVFSPath" (?)

Post Reply