fourier / ztree

Directory tree comparison mode for Emacs
http://www.emacswiki.org/emacs/ZtreeDiff
GNU General Public License v3.0
239 stars 21 forks source link

[feature request] Support diffing embedded archives, perhaps using `jka-compr` #83

Closed ncalexan closed 2 years ago

ncalexan commented 2 years ago

Hello! First, thanks for ztree, and especially ztree-diff: I use it regularly and appreciate it.

I happen to do a good deal of build system work for Firefox, and that means comparing a lot of Firefox packages. Such packages include a few embedded archives, notably omni.ja files which are slightly optimized ZIP files. I would like to teach ztree-diff to recursively diff these embedded archives. Has anybody asked for this before? Can you suggest how this might be structured in the code? I haven't taken a kick at this myself, so I've no idea how difficult it will be, but I imagine some scheme using the built-in jka-compr is possible, or it may be possible to extract the archives "in place" (perhaps into a uniquely-named subdirectory) and refresh the ztree-diff buffer, or...

Thanks again!

fourier commented 2 years ago

Hi, It would be a bit tricky. ztree-diff is relying on diff to be available, however any similar command line tool would help. Comparing manually in elisp would be costly. Ztree-diff also relies on filesystem APIs of Emacs to get other information, i.e. attributes, remove-path, copy-file, directory-file-name etc.

So the easiest solution I would recommend is to create a command in dired (or what do you use to browse file system) to extract files in place, and then run ztree-diff on the extracted files.

However as always anything could be possible given the amount of resources put in place :) Last year I did some refactoring which could make requests like this a bit easier to implement.

The general idea is that the ztree-view doesn't know what exactly it is showing. There is a defined protocol - see ztree-protocol.el - the generic functions which particular type (file, or comparison node) would implement. The implementation of this protocol for ztree-diff is in the file ztree-diff.el starting from the line 549: (cl-defmethod ztree-node-visible-p ((node ztree-diff-node)). You could theoretically extract similar protocol for file-system operations like mentioned above, and create a new struct derived from ztree-diff-node implementing these and some other operations, and then use it when the target 'things' are archives and not directories. Might be worse if you want to compare directory to archive though...

Saying all of that it might be not really worth the effort - better to just implement quick extract function (or temporarily-extract-archive-and-then-ztree-diff function), in the filesystem browser you use (dired is a great candidate for this :) )

ncalexan commented 2 years ago

Thanks for the prompt and informative response: it would have taken me a decent amount of code spelunking to have figured out your high-level vision.

Given the situation with the filesystem APIs, I'm not eager to make ztree transparently handle archives. I think a little unarchive-in-place helper, sibling to ztree-diff-delete-file, which:

would handle my use case. I'll see what I can work up.

Thanks!