tags:

views:

1388

answers:

5

I'd like to be able to determine if a directory such as a '.app' is considered to be a package or bundle from Finder's point of view on the command line. I don't think this would be difficult to do with a small shell program, but I'd rather not re-invent the wheel if I don't have to.

A: 

A bundle should always have a file `./contents/Info.plist'. You can check for the existance of this in a directory, if so then it's a package/bundle.

Joseph Daigle
Apps always have an contents/Info.plist, but it is not a requirement of a package/bundle. Most document bundles don't have this structure.
amrox
That is correct. My research so far has shown me that for things like a document bundle, Finder relies on the "extension" used in the directory name.
Joseph Daigle
This is untrue, not every bundle has a plist
Mecki
+2  A: 

While you can identify some bundles based on the existens of './contents/Info.plist", it isn't required for all bundle types (e.g. documents and legacy bundles). Finder also identifies a directory as a bundle based on file extension (.app, .bundle, etc) or if the bundle bit is set.

To check the bundle bit from the command line use:

getFileInfo -aB directory_name

In order to catch all cases I would check:

  • Is the bundle bit set?
  • If not, does it have a file extension that identifies it as a bundle? (see Mecki's answer)
  • If not, it probably isn't a bundle.
Hagelin
+2  A: 

You can get a list of all registered file type extensions, using this command:

/System/Library/Frameworks/ApplicationServices.framework/Frameworks\
/LaunchServices.framework/Support/lsregister -dump

or for Leopard

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks\
/LaunchServices.framework/Versions/A/Support/lsregister -dump"

Every file extension there has flags. If the package flag is set, this is a package.

E.g.

  claim   id:            806354944
            name:          Bundle
            role:          none
            flags:         apple-internal  relative-icon-path  package  
            icon:          Contents/Resources/KEXT.icns
            bindings:      .bundle
    --------------------------------------------------------
    claim   id:            1276116992
            name:          Plug-in
            role:          none
            flags:         apple-internal  relative-icon-path  package  
            icon:          Contents/Resources/KEXT.icns
            bindings:      .plugin

Compare this to a file that is no bundle

    claim   id:            2484731904
            name:          TEXT
            role:          viewer
            flags:         apple-internal  
            icon:          
            bindings:      .txt, .text, 'TEXT'

The only way to really get all bundles is by looking up in the LaunchService database (the one we dumped above). If you just go by whether it has a plist or not or whether the bundle bit is set or not, you might catch some or even many bundles, but you can't catch all of them. This is the database Finder uses to determine

  • Is this directory a bundle or not?
  • Is this a known file extension or not?
  • Which applications should be listed under "Open With" for this file type?
  • Which icon should I use for displaying this file type?

and some more stuff.

[EDIT: Added path for Leopard, thanks to Hagelin for the update]

Mecki
In Leopard the command is "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump"
Hagelin
A: 

There ought to be a way to do it easily from the command line, because as an AppleScript user, I can do it using System Events. So if all else fails, you can execute the necessary AppleScript from the command line as follows:

$ FILE=/Users/myuser/Desktop/foo.rtfd
$ osascript -e "tell application \"System Events\" to get package folder of alias POSIX file \"${FILE}\""

result is

true
A: 

<plug>

My launch tool has a feature for this. For example:

% launch -f Guards.oo3 
Guards.oo3: non-application package 
    type: '' creator: ''
    kind: OmniOutliner 3
    content type ID: com.omnigroup.omnioutliner.oo3-package
    contents: 1 item
    created: 3/6/09 3:36:50 PM
    modified: 3/6/09 4:06:13 PM
    accessed: 4/12/09 1:10:36 PM [only updated by Mac OS X]
    backed up: 12/31/03 6:00:00 PM

% launch -f /Applications/Safari.app
/Applications/Safari.app: scriptable Mac OS X application package 
    type: 'APPL' creator: 'sfri'
    architecture: PowerPC 7400, Intel 80x86
    bundle ID: com.apple.Safari
    version: 4 Public Beta
    kind: Application
    content type ID: com.apple.application-bundle
    contents: 1 item
    created: 8/21/07 5:11:33 PM
    modified: 2/24/09 7:29:51 PM
    accessed: 4/12/09 1:10:51 PM [only updated by Mac OS X]
    backed up: 12/31/03 6:00:00 PM

You should be able to get what you want by checking to see if the first line of output ends in 'package'.

launch is in Fink and MacPorts too.

</plug>

Nicholas Riley