Properly extract package name out of cargo pkgid (#10929)

Fixes https://github.com/zed-industries/zed/issues/10925

Uses correct package name to generate Rust `cargo` tasks.
Also deduplicates lines in task modal item tooltips.

Release Notes:

- Fixed Rust tasks using incorrect package name
([10925](https://github.com/zed-industries/zed/issues/10925))
This commit is contained in:
Kirill Bulatov 2024-04-24 14:12:59 +03:00 committed by GitHub
parent 135a5f2114
commit 6108140a02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 53 additions and 21 deletions

View file

@ -421,13 +421,6 @@ impl ContextProvider for RustContextProvider {
}
fn human_readable_package_name(package_directory: &Path) -> Option<String> {
fn split_off_suffix(input: &str, suffix_start: char) -> &str {
match input.rsplit_once(suffix_start) {
Some((without_suffix, _)) => without_suffix,
None => input,
}
}
let pkgid = String::from_utf8(
std::process::Command::new("cargo")
.current_dir(package_directory)
@ -437,19 +430,40 @@ fn human_readable_package_name(package_directory: &Path) -> Option<String> {
.stdout,
)
.ok()?;
// For providing local `cargo check -p $pkgid` task, we do not need most of the information we have returned.
// Output example in the root of Zed project:
// ```bash
// cargo pkgid zed
// path+file:///absolute/path/to/project/zed/crates/zed#0.131.0
// ```
// Extrarct the package name from the output according to the spec:
// https://doc.rust-lang.org/cargo/reference/pkgid-spec.html#specification-grammar
let mut package_name = pkgid.trim();
package_name = split_off_suffix(package_name, '#');
package_name = split_off_suffix(package_name, '?');
let (_, package_name) = package_name.rsplit_once('/')?;
Some(package_name.to_string())
Some(package_name_from_pkgid(&pkgid)?.to_owned())
}
// For providing local `cargo check -p $pkgid` task, we do not need most of the information we have returned.
// Output example in the root of Zed project:
// ```bash
// cargo pkgid zed
// path+file:///absolute/path/to/project/zed/crates/zed#0.131.0
// ```
// Another variant, if a project has a custom package name or hyphen in the name:
// ```
// path+file:///absolute/path/to/project/custom-package#my-custom-package@0.1.0
// ```
//
// Extracts the package name from the output according to the spec:
// https://doc.rust-lang.org/cargo/reference/pkgid-spec.html#specification-grammar
fn package_name_from_pkgid(pkgid: &str) -> Option<&str> {
fn split_off_suffix(input: &str, suffix_start: char) -> &str {
match input.rsplit_once(suffix_start) {
Some((without_suffix, _)) => without_suffix,
None => input,
}
}
let (version_prefix, version_suffix) = pkgid.trim().rsplit_once('#')?;
let package_name = match version_suffix.rsplit_once('@') {
Some((custom_package_name, _version)) => custom_package_name,
None => {
let host_and_path = split_off_suffix(version_prefix, '?');
let (_, package_name) = host_and_path.rsplit_once('/')?;
package_name
}
};
Some(package_name)
}
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
@ -750,4 +764,20 @@ mod tests {
buffer
});
}
#[test]
fn test_package_name_from_pkgid() {
for (input, expected) in [
(
"path+file:///absolute/path/to/project/zed/crates/zed#0.131.0",
"zed",
),
(
"path+file:///absolute/path/to/project/custom-package#my-custom-package@0.1.0",
"my-custom-package",
),
] {
assert_eq!(package_name_from_pkgid(input), Some(expected));
}
}
}