Implement a more robust way of locating rust-analyzer

When bundled, we will retrieve it out of the `Resources` folder.
Locally, we're expected to run `script/download-rust-analyzer` and
put `vendor/bin` in our $PATH.
This commit is contained in:
Antonio Scandurra 2021-10-25 11:02:35 +02:00
parent 715faaaceb
commit 59ed535cdf
13 changed files with 97 additions and 52 deletions

View file

@ -13,3 +13,6 @@ parking_lot = "0.11"
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["raw_value"] }
smol = "1.2"
[dev-dependencies]
gpui = { path = "../gpui", features = ["test-support"] }

View file

@ -1,36 +1,10 @@
use std::{
env,
fs::{self, Permissions},
os::unix::prelude::PermissionsExt,
process::Command,
};
use std::env;
fn main() {
let target = env::var("TARGET").unwrap();
let rust_analyzer_filename = format!("rust-analyzer-{}", target);
let rust_analyzer_url = format!(
"https://github.com/rust-analyzer/rust-analyzer/releases/download/2021-10-18/{}.gz",
rust_analyzer_filename
);
println!(
"cargo:rustc-env=RUST_ANALYZER_FILENAME={}",
rust_analyzer_filename
);
println!("cargo:rustc-env=TARGET={}", target);
let target_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let rust_analyzer_target_path = format!("{}/{}", target_dir, rust_analyzer_filename);
assert!(
Command::new("/bin/sh")
.arg("-c")
.arg(format!(
"curl -L {} | gunzip > {}",
rust_analyzer_url, rust_analyzer_target_path
))
.status()
.unwrap()
.success(),
"failed to download rust-analyzer"
);
fs::set_permissions(rust_analyzer_target_path, Permissions::from_mode(0x755))
.expect("failed to make rust-analyzer executable");
if let Ok(bundled) = env::var("BUNDLE") {
println!("cargo:rustc-env=BUNDLE={}", bundled);
}
}

View file

@ -1,5 +1,5 @@
use anyhow::{anyhow, Context, Result};
use gpui::{executor, Task};
use gpui::{executor, AppContext, Task};
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue;
@ -71,6 +71,21 @@ struct Error {
}
impl LanguageServer {
pub fn rust(cx: &AppContext) -> Result<Arc<Self>> {
const BUNDLE: Option<&'static str> = option_env!("BUNDLE");
const TARGET: &'static str = env!("TARGET");
let rust_analyzer_name = format!("rust-analyzer-{}", TARGET);
if BUNDLE.map_or(Ok(false), |b| b.parse())? {
let rust_analyzer_path = cx
.platform()
.path_for_resource(Some(&rust_analyzer_name), None)?;
Self::new(&rust_analyzer_path, cx.background())
} else {
Self::new(Path::new(&rust_analyzer_name), cx.background())
}
}
pub fn new(path: &Path, background: &executor::Background) -> Result<Arc<Self>> {
let mut server = Command::new(path)
.stdin(Stdio::piped())
@ -143,12 +158,7 @@ impl LanguageServer {
_input_task,
_output_task,
});
let init = this.clone().init();
background
.spawn(async move {
init.log_err().await;
})
.detach();
background.spawn(this.clone().init().log_err()).detach();
Ok(this)
}
@ -229,6 +239,6 @@ mod tests {
#[gpui::test]
async fn test_basic(cx: TestAppContext) {
let server = LanguageServer::new();
let server = cx.read(|cx| LanguageServer::rust(cx).unwrap());
}
}