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

Find cargo toml up the fs #3309

Merged
merged 8 commits into from
Feb 29, 2020
Merged

Conversation

not-much-io
Copy link
Contributor

Currently rust-analyzer will look for Cargo.toml in the root of the project and if failing that then go down the filesystem until root.

This unfortunately wouldn't work automatically with (what I imagine is) a fairly common project structure. As an example with multiple languages like:

js/
  ..
rust/
  Cargo.toml
  ...

Added this small change so rust-analyzer would glance one level up if not found in root or down the filesystem.

Why not go deeper?

Could be problematic with large project vendored dependencies etc.

Why not add a Cargo.toml manual setting option?

Loosely related and a good idea, however the convenience of having this automated also is hard to pass up.

Testing?

Build a binary with various logs and checked it in a project with such a structure:

[ERROR ra_project_model] find_cargo_toml()
[ERROR ra_project_model] find_cargo_toml_up_the_fs()
[ERROR ra_project_model] entities: ReadDir("/workspaces/my-project")
[ERROR ra_project_model] candidate: "/workspaces/my-project/rust/Cargo.toml", exists: true

Edge Cases?

If you have multiple Cargo.toml files one level deeper AND not in the root, will get whatever comes first (order undefined), example:

crate1/
    Cargo.toml
crate2/
     Cargo.toml
... (no root Cargo.toml)

However this is quite unusual and wouldn't have worked before either. This is only resolvable via manually choosing.

@lnicola
Copy link
Member

lnicola commented Feb 26, 2020

Thanks. This seems like a reasonable idea, but I have a small nit: it doesn't match my usual idea of going up (towards the root) or down (into a subdirectory) the file system 😄.

@not-much-io
Copy link
Contributor Author

not-much-io commented Feb 26, 2020

You are right, I mixed up the terminology (thinking roots of a tree are down in the ground 😄 ). It is offically the reverse https://en.wikipedia.org/wiki/Cd_(command)

cd .. will move you up one directory not down. Will switch them around.

Also having slept on it I think I should inlude logic to collect all Cargo.toml-s in the sub dirs and if there are multiple options to abandon the process?

This will solve weird cases where otherwise users would experience that some stuff is working and other stuff isn't because one sub Cargo.toml is used.

To be throrough and pendantic an alternative error to the NotFound could also be included MultipleFound or similar.

@lnicola
Copy link
Member

lnicola commented Feb 26, 2020

Yeah, I think it's a good idea to error out instead of picking a random Cargo.toml.

if let Some(p) = find_cargo_toml_up_the_fs(path) {
return Ok(p)
}

Err(CargoTomlNotFoundError(path.to_path_buf()).into())
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the naming is confusing... Let's do find_in_parent_dir, find_in_child_dir mabye?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you might have meant this anyway but just mentioning that I prefixed with find_cargo_toml_... because these functions are in a fairly "large" file so a new reader might wonder - find what?


impl Error for CargoTomlNoneFoundError {}
impl Error for CargoTomlMultipleValidFoundError {}
impl Error for CargoTomlSearchFileSystemError {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope this method of grouping is acceptable? Group related structs and impls together.

I don't have a strong preference, I can more them around if that is preferred. :)

pub struct CargoTomlMultipleValidFoundError(pub Vec<PathBuf>);

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct CargoTomlSearchFileSystemError(pub PathBuf, pub String);
Copy link
Contributor Author

@not-much-io not-much-io Feb 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went this route to enumerate the possibilities, could also have been one error like:

pub enum CargoTomlFindErrorType {
    NoneFound
    MultipleValidFound
    FilesystemError
}

pub struct CargoTomlFindError(pub PathBuf, typ CargoTomlFindErrorType)

However I don't THINK this is "rusty" or a common practice in general nor in this codebase?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's stick with a single error type here

struct CargoTomlNotFoundError {
    searched_at: PathBuf,
    reason: String,
}

@not-much-io
Copy link
Contributor Author

Regarding last changes

I made the solution a bit more complicated to pass the details of what happened to the user, thinking it might be worth it.

Testing

Covered trying these cases by using the rust-analyzer codebase:

[x] Without changes -> all ~200 packages loaded

[x] Rename Cargo.toml in root to _Cargo.toml -> xtask Cargo.toml is found

[x] Rename in root & Add a fake one to crates -> duplicate error

duplicates

[x] Rename in root & simulate a fs error -> fs error

fs_error

@matklad
Copy link
Member

matklad commented Feb 29, 2020

bors r+

@bors
Copy link
Contributor

bors bot commented Feb 29, 2020

@bors bors bot merged commit 099a8f3 into rust-lang:master Feb 29, 2020
pastelmind added a commit to webtoon/psd that referenced this pull request Mar 14, 2023
The rust-analyzer plugin for VS Code cannot discover our Cargo.toml
because it is two levels below the root directory, and rust-analyzer
only searches one level deep by default.
(See rust-lang/rust-analyzer#3309)
To remedy this, let's add a per-project configuration file for VS Code
that specifies the path to Cargo.toml.
pastelmind added a commit to webtoon/psd that referenced this pull request Mar 15, 2023
The rust-analyzer plugin for VS Code cannot discover our Cargo.toml
because it is two levels below the root directory, and rust-analyzer
only searches one level deep by default.
(See rust-lang/rust-analyzer#3309)
To remedy this, let's add a per-project configuration file for VS Code
that specifies the path to Cargo.toml.
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

Successfully merging this pull request may close these issues.

3 participants