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

Avoid fs::canonicalize for project model paths #65

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

the-mikedavis
Copy link
Contributor

@the-mikedavis the-mikedavis commented Nov 18, 2024

I'm looking at using ELP on my system and am running into some issues with the way symlinks are handled.

For some background: I use impermanence so directories like ~/src on my system are actually symlinks to /nix/persist/home/michael/src. It should be possible to reproduce everything I see with a simpler setup though, for example cloning a rebar3 project to ~/source/proj on your machine, creating a symlink at ~/dest/proj that points to it, and opening an editor in ~/dest/proj. For a practical example, you might symlink a local dependency under _checkouts in a rebar project and go through the symlink to edit the dependency.

The problem is canonicalization: fs::canonicalize/Path::canonicalize resolve symlinks. Usually what you're actually looking for is normalization - resolving . and .. and maybe stripping trailing /s - and making relative directories absolute to a given root. The VFS having canonicalized paths is a problem since the LSP client can send non-canonicalized paths which would appear to the VFS to be different files. You might think that canonicalizing incoming paths from the client is the solution here but it's a false trail: the effect would be that the response to textDocument/definition for example would include canonicalized paths and the client would consider them to be different buffers than the non-canonicalized paths in the request. Instead we should avoid canonicalization entirely.

So this PR removes canonicalization from the project_model crate and another instance of it in the build-info CLI.

This will also need a change in rebar3 to update how it retrieves the CWD. Like std::env::current_dir, file:get_cwd() uses getcwd(3) under the hood so rebar_dir:get_cwd/0 will need an adaptation of the new current_dir function in the last commit. I have some changes locally that I will send and link here. (Edit: erlang/rebar3#2925)

Canonicalizing paths resolves symlinks which can cause mismatches
between what the VFS thinks of a project's paths and what an LSP client
sends or expects to receive. Instead we want to join relative paths to
absolute roots and normalize them (resolving `.`/`..`, stripping
trailing slashes, etc.).
@facebook-github-bot
Copy link
Contributor

@alanz has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@alanz
Copy link
Member

alanz commented Nov 22, 2024

This one is going to take a bit longer to land, we had some issues with canonicalization and symlinks in our internal setup in the past, we will need to confirm this does not return us to those problems.

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

Successfully merging this pull request may close these issues.

3 participants