For an excellent example of what it takes to do a great port of UNIX software to OS X, look no further than Glen Low's port of graphviz for OS X. For good reasons to take a look at graphviz, check out John Schull's Weblog, especially entries such as Outline to graphviz.
This port and GUI front-end adds features such as rendering via the native OS X APIs (finally, good fast PDFs!), and it can actually use kqueue on OS X 10.3 to automatically re-render when a file changes!
Not only does at add a slew of cool new features (most of which I didn't mention), but all of the CLI tools are wrapped up in a nice little application bundle; making installation and removal painless, and relocation no longer becomes a problem.
If all OS X with significant UNIX heritage were distributed this way, one might think it would become difficult to add them all to your PATH. Fortunately, that's just not true . Here's a nice little snippet of LaunchServices code that will return the full path of an application by name regardless of where it happens to be or if it has moved :
from LaunchServices.Launch import LSFindApplicationForInfo
from Carbon.CoreFoundation import kCFURLPOSIXPathStyle
kLSUnknownCreator = '\x00\x00\x00\x00'
def pathForName(appName):
"""
Returns the file system path for an application by name.
NOTE: You should include the suffix, as in "Python.app".
"""
fsRef, cfURL = LSFindApplicationForInfo(kLSUnknownCreator, None, appName)
return cfURL.CFURLCopyFileSystemPath(kCFURLPOSIXPathStyle).toPython()
if __name__ == '__main__':
import sys
if len(sys.argv) == 1:
import os
raise SystemExit, "Usage: %s SomeApplication.app" % (
os.path.basename(sys.argv[0])
)
for appName in sys.argv[1:]:
print pathForName(appName.decode('utf8')).encode('utf8') Usage looks like this (note: I use tcsh not bash):
[crack:~/bin] bob% setenv PATH ${PATH}:`./findapp.py GraphViz.app`/Contents/MacOS
[crack:~/bin] bob% rehash
[crack:~/bin] bob% which dot
/Applications/GraphViz/Graphviz.app/Contents/MacOS/dot
[crack:~/bin] bob% dot --help
dot: option -- unrecognized
Usage: dot [-Vv?] [-(GNE)name=val] [-(Tlso)<val>] <dot files>
-V - Print version and exit
-v - Enable verbose mode
-Gname=val - Set graph attribute 'name' to 'val'
-Nname=val - Set node attribute 'name' to 'val'
-Ename=val - Set edge attribute 'name' to 'val'
-Tv - Set output format to 'v'
-lv - Use external library 'v'
-ofile - Write output to 'file'
-q[l] - Set level of message suppression (=1)
-s[v] - Scale input by 'v' (=72)
-y - Invert y coordinate in output
|