Saturday, 5 March 2011

Predictable path for single result in SpotlightFS

As part of a slightly bigger project, I'm putting together a simple system to look up select files or directories by a unique ID I've assigned them previously which I can use to reliably refer to them forever, without depending on their contents (which rules out checksums) or their paths (which rules out symlinks), and which survives (careful) moves across filesystems/disks (which rules out inode numbers), or even of changing my UNIX flavour (which rules out hard dependence on OS X). It'll be rather like URL shorteners (except some have disappeared!) or Carbon's Alias Manager.

I'm using Spotlight to index the UID and SpotlightFS to make access a simple matter of accessing a URL such as file:///byUID/o9e8 (making Spotlight an implementation detail that can change later). I can formulate a Spotlight query that'll return exactly one result — the one with the corresponding UID — but SpotlightFS will always give you a directory of symlinks whose names encode the true paths to results (link targets), meaning they vary based on the path. An example query (not using my UID stuff) with one result:


me$ ls -la /Volumes/SpotlightFS/SmarterFolder/exec_separate_vm/
.
..
:Users:me:JavaSnoop.properties -> /Users/me/JavaSnoop.properties


What I want is a predictable symlink that works when there's exactly one result, linking to that single result. The only way I can see to do this and keep file:///byUID/ URLs working is to patch SpotlightFS. The resulting patch (to version 2.0.3,2, ready to be dropped into /opt/local/var/macports/sources/rsync.macports.org/release/ports/fuse/spotlightfs/files/) allows me to do this:


me$ ls -la /Volumes/SpotlightFS/SmarterFolder/exec_separate_vm/the-only-result
/Volumes/SpotlightFS/SmarterFolder/exec_separate_vm/the-only-result
->
/Users/me/JavaSnoop.properties


It doesn't show up in the directory listing of a SmarterFolder query — if you don't stat() it, you'll never know it's there (which could be considered a feature). If there are zero results or multiple results, it'll provide the same symlink with an explanatory message as the target:


me$ ls -la /Volumes/SpotlightFS/SmarterFolder/arloegu098pgm/the-only-result
/Volumes/SpotlightFS/SmarterFolder/arloegu098pgm/the-only-result
->
error-there-must-be-exactly-one-result