Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$PATH is very hard to set on MacOS Yosemite #68

Closed
dmcg opened this issue Dec 1, 2014 · 12 comments
Closed

$PATH is very hard to set on MacOS Yosemite #68

dmcg opened this issue Dec 1, 2014 · 12 comments

Comments

@dmcg
Copy link

dmcg commented Dec 1, 2014

Commands that I invoke through Watchman on Yosemite have a PATH set to /usr/bin:/bin:/usr/sbin:/sbin

Needless to say, very little of my toolchain is in that path.

I think that it has to do with launchd defaulting to a very restricted path http://apple.stackexchange.com/questions/106355/

The only solution I've come up with is to source ~/.bash_profile in scripts invoked from Watchman, but this means that if I invoke them normally they have an enormous path set.

@wez
Copy link
Contributor

wez commented Dec 1, 2014

this a regression from switching to launchd (watchman is supposed to capture your PATH at the time you launch it).

A workaround would be to edit ~/Library/LaunchAgents/com.github.facebook.watchman.plist and add something like:

<key>EnvironmentVariables</key>
<dict>
    <key>PATH</key>
    <string>INSERT YOUR PATH HERE</string>
</dict>

(see man launchd.plist for more on this file)

then:

launchctl unload -w ~/Library/LaunchAgents/com.github.facebook.watchman.plist
launchctl load -w ~/Library/LaunchAgents/com.github.facebook.watchman.plist

I'll work up a fix sometime in the coming week.

@dmcg
Copy link
Author

dmcg commented Dec 1, 2014

That's a little less palatable than my solution TBH, because it doesn't update as I update .profile, and as I've just updated to Yosemite and am having to reinstall my toolchain $PATH is a bit of a moving target ;-)

Thanks for the attention, I'll look forward to a pukka fix.

@jschaf
Copy link

jschaf commented Dec 31, 2014

I just ran into this issue. All of the homebrew tools are unavailable by default. @wez's solution works. I did the following for PATH

<key>EnvironmentVariables</key>
<dict>
  <key>PATH</key>
  <string>$PATH:/usr/local/sbin:/usr/local/bin</string>
</dict>

@jimtla
Copy link

jimtla commented Mar 31, 2015

Any updates on this? As a hack I've added a script to freeze my current env into the plist:

#Freeze the current env to the watchman config. This is a hack to get around
# https://github.com/facebook/watchman/issues/68
ENVIRONMENT=$(env | sed 's/=/<\/key><string>/' | sed -e 's/^/<key>/' | sed -e 's/$/<\/string>/')
echo $ENVIRONMENT

PLIST=~/Library/LaunchAgents/com.github.facebook.watchman.plist

# Remove the last two lines.
sed -i '' -e '$ d' $PLIST
sed -i '' -e '$ d' $PLIST

# replace the second to last line (previously "</dict>") with our environment +
# "</dict>"
echo "<key>EnvironmentVariables</key><dict>"$ENVIRONMENT"</dict></dict>" >> $PLIST

# Replace the last line
echo "</plist>" >> $PLIST

# Reload the watchman config
launchctl unload -w ~/Library/LaunchAgents/com.github.facebook.watchman.plist
launchctl load -w ~/Library/LaunchAgents/com.github.facebook.watchman.plist

but it's annoying to manually run that after any update to my env.

@wez
Copy link
Contributor

wez commented Mar 31, 2015

We have a diff that we'll land real soon now: https://reviews.facebook.net/D36045

wez added a commit that referenced this issue Apr 1, 2015
Summary:
Prior to switching to launchd, the daemonization would capture your
PATH at the time that we spawned the service.  Launchd will start our service
with a default environment, so this diff captures the PATH in a similar
fashion.

There may be other important env vars that we should do this for; I'm hoping
that PATH is good enough.

We use CDATA to avoid having to pull in "proper" XML escaping just for
the plist file.

Addresses #68

Test Plan:
manually:

```
./configure --enable-statedir=/tmp
make
./watchman version
less ~/Library/LaunchAgents/com.github.facebook.watchman.plist
```

Reviewers: sid0

Reviewed By: sid0

Differential Revision: https://reviews.facebook.net/D36045
@wez
Copy link
Contributor

wez commented Apr 1, 2015

This has landed; we're going to cut 3.1 with this fix in it soon and submit a PR to homebrew.
Meanwhile, you can do brew install --HEAD watchman to pick up this fix.

@wez wez closed this as completed Apr 1, 2015
@sunny-mittal
Copy link

I am still having an issue related to this (I think) using 3.3.0. I ran the following in my project root:

$ watchman watch `pwd`
$ watchman -- trigger `pwd` js '*.js' -- "browserify -o bundle.js"

But when I check the logs, I see a "No such file or directory" error. If I change the command to cat or something, I see the output in the log as expected. The plist confirms that my path is getting picked up, but it doesn't seem to be able to find browserify.

@wez
Copy link
Contributor

wez commented Jul 6, 2015

I think you want this:

watchman -- triggerpwdjs '*.js' -- browserify -o bundle.js

otherwise watchman will try to find the file named "browserify -o bundle.js" in your path and execute it

@sunny-mittal
Copy link

I tried that as well...no luck. I also tried it with various node-related commands and they all fail with the same error. Any other ideas? In the log file, I can see that the path is correct but it just doesn't seem to want to execute any command related to node.

@wez
Copy link
Contributor

wez commented Jul 6, 2015

I can't see your log file so I don't have any more context than you have shared on this closed issue.
I'd recommend just making a wrapper script that sets the appropriate things in the environment:

#!/bin/sh
PATH="$PATH:/some/where"
NODE_PATH="whatever is appropriate"
export PATH NODE_PATH
exec browserify -o bundle.js "$@"

@sunny-mittal
Copy link

I'll give that a shot. Thanks for your help!

@jimtla
Copy link

jimtla commented Jul 13, 2015

For anybody looking - my hack to freeze the environment into the plist doesn't work so well anymore, but I wrote a new script to bake the current environment into a shell script:

#!/bin/bash -e -x

# Takes a bash script as the only argument, and prints the location of a new
# shell script that executes the given script with the current environment.

SCRIPT=`mktemp $TMPDIR"bake_env".XXXXXXXX`
ENVIRONMENT=$(env | sed "s/=\(.*\)\$/='\1'/g" | sed 's/^/;export /')
echo "#!/bin/bash -e" >> $SCRIPT
echo "true"$ENVIRONMENT >> $SCRIPT
ABS_PATH=`python -c "import os; print os.path.realpath('$1')"`
echo "exec $ABS_PATH \$@" >> $SCRIPT
chmod a+x $SCRIPT
echo $SCRIPT

When I want to run something with watchman I pass the target to run to that script, and then pass the output to watchman.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants