rust-lang / vscode-rust

Rust extension for Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=rust-lang.rust
Other
1.39k stars 167 forks source link

Extension doesn't work with zsh / VSCode Mac OSX Catalina #850

Open crcdng opened 4 years ago

crcdng commented 4 years ago

Edit: I thought the problem was solved with the workaround in my comment below, but it affects all shell commands spawned form the extension:

for example CMD-SHIFT-byields

zsh:1: command not found: cargo The terminal process "/bin/zsh '-c', 'cargo build'" failed to launch (exit code: 127).

Original issue:

When I open a Rust source file, the extension asks

Some Rust components not installed. Install?

On confirmation it throws multiple errors such as:

zsh:1: command not found: rustup The terminal process "/bin/zsh '-c', 'rustup component add rust-analysis --toolchain stable'" failed to launch (exit code: 127).

Terminal will be reused by tasks, press any key to close it.

Executing task: rustup component add rust-src --toolchain stable <

zsh:1: command not found: rustup The terminal process "/bin/zsh '-c', 'rustup component add rust-src --toolchain stable'" failed to launch (exit code: 127).

Terminal will be reused by tasks, press any key to close it.

Executing task: rustup component add rls --toolchain stable <

zsh:1: command not found: rustup The terminal process "/bin/zsh '-c', 'rustup component add rls --toolchain stable'" failed to launch (exit code: 127).

Terminal will be reused by tasks, press any key to close it.

However rustup is installed and in the executable path. I can call it both from the Mac Terminal and from the VSCode terminal manually by typing rustup.

For some reason the extension does not find it.

crcdng commented 4 years ago

As a workaround, I ran these commands manually in the console:

~ % /bin/zsh '-c' 'rustup component add rust-analysis --toolchain stable' 
info: component 'rust-analysis' for target 'x86_64-apple-darwin' is up to date
~ % /bin/zsh '-c' 'rustup component add rust-src --toolchain stable' 
info: component 'rust-src' is up to date
~ % /bin/zsh '-c' 'rustup component add rls --toolchain stable' 
info: downloading component 'rls'
info: installing component 'rls'
info: Defaulting to 500.0 MiB unpack ram

Now rls is installed and the extension seems to work as intended.

lnicola commented 4 years ago

This happens because your shell's PATH doesn't apply to Code if you don't start it from a shell (e.g. terminal).

crcdng commented 4 years ago

This happens because your shell's PATH doesn't apply to Code if you don't start it from a shell (e.g. terminal).

The built-in VSCode terminal does recognize the PATH (calling rustup works from there), so there should be a way the plugin does register the path as well.

lnicola commented 4 years ago

That's because the Code terminal spawns a shell, which reads ~/.profile or whatever and gets the correct PATH. In Linux you can set environment variables in /etc/environment or ~/.pam_environment, and see https://stackoverflow.com/a/588442 for MacOS.

The extension could spawn every Rust-related command using a shell, but then it would have to figure out the user's shell, be careful about escaping the arguments and pay for the execution time of whatever is in .profile and maybe .zshrc, which might be non-trivial if you're using plugins.

It could also try to parse .profile or guess that it should look under ~/.cargo/bin, but this is pretty tricky -- both platform and user-specific.

crcdng commented 4 years ago

The extension could spawn every Rust-related command using a shell

I believe that it must do that because it's functionality relies on calling shell commands. Without the context of the current user's shell this cannot work. I agree with the other points: approaches which are based on guessing the path don't work well either. But currently, it does not work at all.

Epikem commented 3 years ago

I added "terminal.integrated.inheritEnv": true, option to settings.json as a workaround and it worked. I suggest adding fallback inputBox to get rustup path from user.

(rustup.ts)


  if (clicked) {
    try {
      await installComponents(config, components);
      window.showInformationMessage('Rust components successfully installed!');
    } catch (error) {

      const options: InputBoxOptions = {
        value: "$HOME/.cargo/bin/rustup",
        prompt: "Could not find rustup. Please specify rustup path",
        validateInput: async (x: string) => {
          if (x == null) return 'null';
          return null;
        }
      };
      const rustupPath = await window.showInputBox(options);
      if (!rustupPath) return;

      config.path = rustupPath;
      await installComponents(config, components);
      window.showInformationMessage('Rust components successfully installed!');
    }
  } else {
    throw new Error();
  }
cicorias commented 3 years ago

This post seems to have a potential permanent solution: https://zgljl2012.com/executing-task-cargo-test-nocapture-test1-zsh-1-command-not-found-cargo/

function createShellExecution(execution) {
     const { binary, command, args, cwd, env } = execution;
     // const cmdLine = `${command || binary} ${args.join(' ')}`;
     const cmdLine = `source $HOME/.cargo/env; ${command || binary} ${args.join(' ')}`;
     return new vscode_1.ShellExecution(cmdLine, { cwd, env });
}

image