asdf: bug: VS Code fails to initialize workspace with Cargo (Rust Alanyzer)
Describe the Bug
I am using the rust-analyzer extension for Visual Studio Code and when I open a Cargo project I see:
rust-analyzer failed to load workspace: "cargo" "--version" failed: No such file or directory (os error 2)
I have had nothing but problems trying to get other similar tools to find the shims from asdf. There has to be a method, as it is everything that I try to use with asdf-managed tools is simply inoperable.
I cannot find a setting in Code that allows me to change the path to the toolchain.
Steps to Reproduce
asdf plugin add rust
asdf install rust latest
asdf global rust latest
- Test VS Code, see it can’t find Cargo.
asdf reshim
- Test again, error again.
rm -rf ~/.asdf/shims
asdf reshim
- Test again, error again.
- ???
Expected Behaviour
The IDEs and other tools should be able to find software managed by asdf. I have tried adding the initialization script to both .zshrc
and .profile
(ZSH is my login shell).
# Source the asdf version manager
[ -f '/opt/asdf-vm/asdf.sh' ] &&
source '/opt/asdf-vm/asdf.sh'
Everything works fine from the command line.
Actual Behaviour
No tooling I try (specifically VS code in this case) can ever find binaries from ~/.asdf
.
Environment
OS:
Linux jacob-thinkpad 5.17.0-2-MANJARO #1 SMP PREEMPT Fri Feb 25 11:28:23 UTC 2022 x86_64 GNU/Linux
SHELL:
zsh 5.8.1 (x86_64-pc-linux-gnu)
ASDF VERSION:
v0.9.0
ASDF ENVIRONMENT VARIABLES:
ASDF_DIR=/opt/asdf-vm
ASDF INSTALLED PLUGINS:
flutter https://github.com/oae/asdf-flutter.git master 1f5b9e2
java https://github.com/halcyon/asdf-java.git master b0341fd
nodejs https://github.com/asdf-vm/asdf-nodejs.git master 364c078
python https://github.com/danhper/asdf-python.git master 57a4d72
ruby https://github.com/asdf-vm/asdf-ruby.git master de49662
rust https://github.com/code-lever/asdf-rust.git master 0c88f99
asdf plugins affected (if relevant)
rust
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 9
- Comments: 25 (7 by maintainers)
@jthegedus
There are two questions to be answered in my mind: Question “A” why does the
~/.bash_profile
make vscode work while~/.bashrc
doesn’t (analogous to zshell’s rc files). Question “B” what environment do the graphical applications run with (ones that don’t go near shell when being executed)A) Actually vscode tends to launch it’s children through a login shell, here is
strace
output (my initial findings were not quite correct):What you can see here is vscode starting a
login
shell. Excerpt from bash manpage:So here is the reason, I had my
. $HOME/.asdf/asdf.sh
in.bashrc
and the.bash_profile
was separate from it (i.e. it was empty) so vscode couldn’t get the right path since it starts the login shell.When I changed my user’s shell (
chsh -s /bin/sh myuser
) tosh
then the vscode would exec/bin/sh -ilc
instead (which would in turn source its own login files (/etc/profile
and.profile
if they exist).B) It’s difficult to tell on linux because there are so many different ways you can set up your graphical environment. There are many desktop managers (login things that make you enter password and they spin up your gnome/kde/fluxbox/etc. for you) that can be set up in a different way. I’m using ubuntu 20.04 with
lightdm
and what it does once it authenticates you and runs your session is it runs a wrapper script (located in/usr/sbin/lightdm-session
) that sources~/.profile
and~/.xprofile
, GDM seems to be following suit with its/etc/gdm3/Xsession
. You end up with variables from/etc/profile
and$HOME/.{profile,xsession}
A note on PAM we shouldn’t forget that on linux the authentication is done by PAM which is going to provide its own variables from
/etc/environment
and~/.pam_environment
by default but it depends on PAM’s configuration.Having said all that what I did in the end was:
. $HOME/.asdf/asdf.sh
into the~/.bashrc
.bashrc
in the~/.profile
(courtesy of ubuntu’s defaults):~/.bash_profile
since the~/.profile
seems to be the common denominator here (both for graphical and shell sessions).I hope that helps.
edit: typo and minor semantic mistake
path
only works with zsh, if you are using bash do it like this:export PATH=$HOME/.asdf/shims:$PATH
Hey, @spikespaz. I found a quick fix for this problem. Add the shims folder to the env vars of your
.bash_profile
(or.zprofile
, if you are using Zsh):I want to mention my gratitude to @baliestri, who helped me solve this problem.
This issue happens to me with some tools and not others. I have experienced this with Rust Analyzer myself, but didn’t stick with Rust long enough to resolve or investigate in any meaningful way.
Given the unpredictable nature of this, I expect that this depends on how the plugin itself tries to find tools and what it does in the background to resolve missing tools. For instance, I use the
shellcheck
VSCode plugin, but it can’t find myasdf
installed Shellcheck version (I am unsure how it searches for it) and then proceeds to download and install a version to somewhere on my machine. Again, since this happens with some plugins and not others I expect it is because of the way the tool is located by the plugin. Happy to be corrected, because if this is an easy fix for us, then great.The
asdf.sh
script which is sourced in your shell (as part of step 3 of the setup guide) should source.asdf/shims
, so it should already be in your PATH and not needed to be added manually.Is sourcing it in the
"profile"
file different to VSCode? Why would this be?Perhaps I got lucky. I had the below behaviour:
~/somedir
. Correctly resolves Deno version~/somedir
& runcode ~
~
and correctly errors trying to resolve Deno version. The Output tab shows the asdf error when the Extension tried to start the Deno Language Server:So it is correctly trying to resolve the tool from the directory it was opened in and not from. At least for me, and with this particular Extension. The Deno extension might just be super resilient. As for my setup while testing this:
nushell
was output in strace, it seemed to resolve/usr/bin/sh
, and the default Ubuntu~/.profile
does source~/.bashrc
however I do not haveasdf
configured with in any config other than Nushell.Extension variance is definitely a factor in this, but not a predictable one and certainly not solvable by us.
User shell setup is also a nightmare, hence why we didn’t want to get into the game of automatically modifying configs.
Additionally, I just got VSCode@1.69 which has unrelated, but further Shell integrations
So VSCode are actively working in this area and can potentially introduce changes which would affect our advice. We must remain aware.
I would like to not get stuck in the weeds of comparing each others Shell setups if we agree on the “what we need to do” items I outlined above.
Not quite, if you look up the
INVOCATION
section of the bash 5 manual you can find that for a login shell (login shell can be interactive but doesn’t have to be) following files are being sourced:/etc/profile
,~/.bash_profile
,~/.bash_login
, and~/.profile
(in that order). For an interactive bash session that is not a login shell/etc/bash.bashrc
and~/.bashrc
, are being read.Conclusion is that
~/.bash_profile
and~/.bashrc
are independent of each other and being read at different times. A lot of people will source their~/.bashrc
inside~/.bash_profile
or~/.profile
and that’s why it looks like~/.bashrc
is being always read (but it doesn’t have to be true).This feels relevant: https://github.com/microsoft/vscode/issues/130493
But, I don’t really know how
asdf
works. I need to do some reading, But, feels like if the node extension host (which runs per-workspace) were launched with the right environment and/or ran theasdf
hook (?) first then everything would be happy.Is this captured in VSCode documentation anywhere? Before we recommend to all users in the docs I want to understand the issue completely. Is VSCode strictly tied to your Shell? A specific Shell, or the default Shell? If I use Fish will VSCode run that Shell’s equivalent of profile?
Lots of questions to understand what is actually happening before we can recommend any solution. You have done some great digging, thanks @Rotwang If you have more time to further investigate that would be appreciated.
I am not sure what we can do about it though.
Copying shims to
/usr/bin
or/usr/sbin
type locations might work, but we can’t guess which location each VSCode plugin would decide to use, so we would have to copy to ALL of the possible locations, which does not feel like the right thing to do.@jthegedus it’s such a fundamental issue for users of asdf, like it’s one of the first things I stumbled on. Right now the best solution for me is to run
code
from the terminal session. It would be good if there was at least some kind of infrormation/doc pointing to the solution.edit: I know it’s not asdf issue per se but people think it is, for example look here: https://elixirforum.com/t/failed-to-run-elixir-command-error-in-vs-code/31047/6
edit2: so in my case when I have been sourcing
$HOME/.asdf/asdf.sh
in~/.bashrc
then it broke but when I added that source to~/.bash_profile
then it worked. So my conclusion is that vscode will abide by the~/.bash_profile
or.zprofile
(confirming what @bitterteriyaki have said already)edit3: I’ve straced vscode and it doesn’t look to me like it’s directly sourcing the files, my assumption is that something launching it has already done that.
@spikespaz As you say in the initial issue:
They can if they look in the right place.
Standardized locations for tools installed at the system level, non-version managed.
Yes, it is not Nix. Our comments on that are here https://asdf-vm.com/guide/introduction.html
Can someone speak as to why @bitterteriyaki method supposedly works?
I am inclined to mark this as unfixable by
asdf
core and close the Issue.Only if you want you can write to the
.zshrc
file.I use it as follows: