This also assumes that the shell is bourne-compatible and thus does not work with fish 2.0, which is getting increasingly more popular among the hacker community. (Fish considers $PATH an array, not a colon-delimited string. And it thus prints it using spaces as delimiters by default. One can probably cook up an easy fix, like running for i in $PATH; echo "PATH=$i"; end and then only taking the lines that start with PATH=. Filtering is a good idea on any case, because profile scripts often print something on their own.)
This also assumes that the shell is bourne-compatible and thus does not work with fish 2.0, which is getting increasingly more popular among the hacker community.
This also assumes that the shell is bourne-compatible and thus does not work with fish 2.0, which is getting increasingly more popular among the hacker community. (Fish considers $PATH an array, not a colon-delimited string. And it thus prints it using spaces as delimiters by default. One can probably cook up an easy fix, like running for i in $PATH; echo "PATH=$i"; end and then only taking the lines that start with PATH=. Filtering is a good idea on any case, because profile scripts often print something on their own.)
For those wishing to use something like system Git from a sandboxed app, note that while you don't have access to read files and enumerate directories, you do have access to stat — [[NSFileManager defaultManager] fileExistsAtPath:path]. You can use this to probe a hard-coded list of typical folders looking for your binary, and when you find the locations (like /usr/local or /opt/local or whatever), ask the user to give you access via NSOpenPanel. This won't catch every case, but will handle 90% of use cases and is the best thing you can do for your users out of the box.
For those wishing to use something like system Git from a sandboxed app, note that while you don't have access to read files and enumerate directories, you do have access to stat — [[NSFileManager defaultManager] fileExistsAtPath:path]. You can use this to probe a hard-coded list of typical folders looking for your binary, and when you find the locations (like /usr/local or /opt/local or whatever), ask the user to give you access via NSOpenPanel. This won't catch every case, but will handle 90% of use cases and is the best thing you can do for your users out of the box.
P.S. The reason this works is because it catches environment changes made by the shell. E.g. RVM adds PATH=$PATH:$HOME/.rvm/bin to .bashrc on installation. Cocoa apps are launched from launchd, so they don't have these changes in their PATH.
I'm not 100% satisfied with this code, because it does not catch everything. My original intent was to handle RVM specifically, so I had to use a non-login shell here, but in practice, people randomly put PATH modification into .bashrc and .bash_profile, so it would be best to run both.
One of my users even had an interactive menu (!!!) in his shell profile, which naturally lead to this code hanging and me exporting a shell env flag just for him. :-) Adding a timeout is probably a good idea.
This also assumes that the shell is bourne-compatible and thus does not work with fish 2.0, which is getting increasingly more popular among the hacker community.
As a final note, this code has been an important part of a shipping app for over a year (top 10 paid developer tool on the Mac App Store for most of the year). However, I'm now implementing sandboxing and taking it out; naturally, you cannot do this trick from a sandboxed app. I'm replacing it with explicit support for RVM and friends, and reproducing their respective env changes manually.
P.S. The reason this works is because it catches environment changes made by the shell. E.g. RVM adds PATH=$PATH:$HOME/.rvm/bin to .bashrc on installation. Cocoa apps are launched from launchd, so they don't have these changes in their PATH.
I'm not 100% satisfied with this code, because it does not catch everything. My original intent was to handle RVM specifically, so I had to use a non-login shell here, but in practice, people randomly put PATH modification into .bashrc and .bash_profile, so it would be best to run both.
One of my users even had an interactive menu (!!!) in his shell profile, which naturally lead to this code hanging and me exporting a shell env flag just for him. :-) Adding a timeout is probably a good idea.
This also assumes that the shell is bourne-compatible and thus does not work with fish 2.0, which is getting increasingly more popular among the hacker community.
As a final note, this code has been an important part of a shipping app for over a year (top 10 paid developer tool on the Mac App Store for most of the year). However, I'm now implementing sandboxing and taking it out; naturally, you cannot do this trick from a sandboxed app. I'm replacing it with explicit support for RVM and friends, and reproducing their respective env changes manually.