Galooshi / sublime-import-js

Sublime Text plugin for ImportJS
MIT License
24 stars 2 forks source link

Improve compatibility with nvm #2

Closed lencioni closed 8 years ago

lencioni commented 8 years ago

Some folks might not have a system node installed but are using nvm. I thought it would work to configure the executable to point to the importjs binary installed in the .nvm directory (e.g. /Users/foo/.nvm/versions/node/v4.4.3/bin/importjs), but that gives us the "couldn't find executable" error message.

We could probably make this work by having Python use a login shell when executing the importjs command, but I'd like to avoid that if possible for performance reasons.

I think all of the plugins besides atom-import-js will likely need similar attention.

This is related to https://github.com/Galooshi/import-js/issues/233

lencioni commented 8 years ago

It turns out that I was erroneously seeing the couldn't find executable error message, which I improved in 32a2019fa8c792875f23ff037c993dcb6717500a. This is still an issue, but now the message is much more helpful:

env: node: No such file or directory

janpaul123 commented 8 years ago

@lencioni Can you try setting the executable path to:

/usr/bin/env PATH=/path/to/directory/that/contains/node /path/to/importjs

trotzig commented 8 years ago

I've started using nodenv, so I'm likely to hit this issue too. I found sublime-3-shell-exec while googling, and it looks like we could use the same technique they do here:

https://github.com/gbaptista/sublime-3-shell-exec/blob/master/ShellExec.py#L169

lencioni commented 8 years ago

@janpaul123 good thought, but I still get the couldn't find executable error with that.

@trotzig good digging, but the only real difference I see there is they are using shell=True which doesn't seem to help here.

lencioni commented 8 years ago

Unfortunately, your fix does not work for me.

In a regular shell, running echo $PATH gives me:

/Users/joe/.nvm/versions/node/v4.4.3/bin:/Users/joe/bin:/Users/joe/.shells/bin:/usr/local/bin:/Users/joe/.rbenv/shims:/Users/joe/.rbenv/shims:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/joe/bin:/Users/joe/.shells/bin:/Users/joe/.rbenv/shims:/Users/joe/.rbenv/bin:/usr/local/share/python:/Users/joe/.rbenv/bin:/Users/joe/.rbenv/shims:/usr/local/share/python

But when I look in the Sublime console, I can see that PATH is set to '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin', which doesn't have the necessary path for nvm.

If I have no executable configuration, I get the nice custom error message we have. If I set my configuration to this:

{
    "executable": "/Users/joe/.nvm/versions/node/v4.4.3/bin/importjs"
}

I get

Error when executing importjs: env: node: No such file or directory

This is what I see logged in the console:

['/Users/joe/.nvm/versions/node/v4.4.3/bin/importjs', 'fix', '/Users/joe/import-js-simple-project/js/index.js']
error: Error when executing importjs:

env: node: No such file or directory

I believe that this is due to the PATH not including "/Users/joe/.nvm/versions/node/v4.4.3/bin" which is added by my .zshrc file.

I think we might be able to try to execute ~/.nvm/nvm.sh before grabbing the PATH and then we'll be all set.

trotzig commented 8 years ago

Isn't your .zshrc sourced when you run /bin/zsh? Can you help me debug this for nvm? :)

lencioni commented 8 years ago

Hmm, it is sourced when I run /bin/zsh. I tried running /bin/zsh -l -c 'echo $PATH' in my terminal just now, which should give a login shell, which should source my .zshrc file, and it gives me what looks like a good PATH with the nvm stuff in it so that seems to be correct. But for some reason it isn't when run in the plugin...

lencioni commented 8 years ago

the value of out specifically here is __SUBL_PATH__/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin__SUBL_PATH__ which is missing a bunch of stuff.

lencioni commented 8 years ago

I've checked the value of os.environ['SHELL'] and it is /usr/local/bin/zsh which is good.

lencioni commented 8 years ago

I tried putting this in a test.py file:

import os
import subprocess

out = subprocess.Popen(
    [os.environ['SHELL'], '-l', '-c',
        'echo "__SUBL_PATH__${PATH}__SUBL_PATH__"'],
    env=os.environ,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
).communicate()[0].decode()
path = out.split('__SUBL_PATH__', 2)

print(path)

and I ran it with python test.py and it prints a good PATH. The plot thickens.

lencioni commented 8 years ago

print(os.environ['PATH']) in the sublime plugin gives me the short path without the stuff I need, and in my test.py it gives me the good path.

janpaul123 commented 8 years ago

I think it matters if you launch Sublime from the shell or not. See also https://github.com/int3h/SublimeFixMacPath

lencioni commented 8 years ago

Interesting. Unfortunately, installing SublimeFixMacPath doesn't seem to help me. I'm also having a hard time trying to figure out how to launch Sublime from the shell (where is subl located?)

lencioni commented 8 years ago

It might be worth looking at what SublimeLinter does for this. Links:

trotzig commented 8 years ago

I used code directly taken from SublimeLinter in a6e27c50efd. I probably missed some essential part though.

lencioni commented 8 years ago

Oh that's right. It is possible that this just won't work with how my environment is set up too. Actually, according to http://www.sublimelinter.com/en/latest/troubleshooting.html#adjusting-shell-startup-files that method will not source .zshrc. I moved my nvm PATH stuff into .zprofile and it seems to work.

trotzig commented 8 years ago

I just found this in the SublimeLinter docs:

When SublimeLinter starts up, it runs your shell as a login shell to get the PATH. This forces the shell to read the “profile/env” file, but for most shells the “rc” file is not read. There is a very good reason for this: performing initialization that only relates to interactive shells is not only wasteful, it will in many cases fail if there is no terminal attached to the process. By the same token, you should avoid putting code in the “profile/env” file that has any output (such as motd or fortune), since that only works with interactive shells attached to a terminal.

trotzig commented 8 years ago

Just noticed that you found the same thing. 👍