Scripting a package archive/compression

I’ve been using StefanK’s excellent ZipIt utility script to programmatically make archives for a while now, and its been fantastic. However, I am now running into a problem: I can’t handle packages properly.

The problem is not in his script so much, but in ‘ditto’. Everyone online compares ditto to Apple’s Archive Utility, but I’ve found this one difference. If I right-click on a package and compress it via Archive Utility, I get a zip that decompresses into the package. However, if I compress the same package using ditto (e.g. ditto -c -k -rsrc ./, I get a zip that decompresses into a folder of the name (myArchive/) that contains the contents of the package.

I feel like I’m not being clear, so I’ll try to use an illustration. Consider the following package:

An archive created with Archive Utility decompresses into exactly the structure above, regardless of the name of the archive. However, an archive created with ditto decompresses into:


So the files are all there, but the containing directory is considered a folder, who’s name came from the name of the archive, not a package that was initially compressed. I hope this is clear, and I am interested in any feasible solution. Using Automator’s “Create Archive” action doesn’t maintain the resource fork of the files when decompressed (I surmise it is a simple ‘zip’ call). Archive Utility itself isn’t scriptable. I can’t use a tarball first, as I need to be able to decompress it with ditto (ditto -x -k).

Any ideas?

You should include the --keepParent argument.


There is a trick to invoke archieve utility from the commandline, and a hidden preference pane, which you can use to archieve zip files with. It seemed to me that it archieved bundles correctly, as I archieved and unarchieved an app, and it’s contents bundle, and each worked perfectly

There is an alternative way to do it. here:MacScripter / Renaming part of file using enclosing folder name in post 16 you will have to tell archieve utility to quit afterwards, and you have to play a little with the properties of the hidden preference pane, and check what it does manually.

You’ll have to tell it to quit afterwards as well.

This is more of a demonstration, than a script:

set cmd to quoted form of POSIX path of ((path to application id "" as text) & "Contents:MacOS:Archive Utility")

set subj to quoted form of POSIX path of ((path to desktop as text) & "")

do shell script cmd & " " & subj

tell application id "" to quit

To open the preference pane, execute this from a terminal window:

open /System/Library/CoreServices/Archive\


Be careful when you play with it, if you set it to delete files after archieving, and delete archieve, I guess all of your files will be gone!

It is not so smart as to when to apply the options, (If it is during an archieve or unarchieve process, at least it seemed like that to me.)

Thanks for the replies! I appreciate the information for how to script Archive Utility, but Shane Stanley’s response was exactly the right one.

It turns out that the original Zipit script from StefanK contained the --keepParent flag. I had to take it out of my version, as it caused problems when just putting a file in there, the parent folder information was maintained. But, it does exactly what I want for packages. So, I’ve made its inclusion dependent on whether or not it is a package, and everything is working great.

Thanks again; this is a fantastic community.