Implement updating for node-based language servers (#9361)

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

This doesn't address `vue` as it has a slightly different install code,
but it should be fairly simple to add - I'll add it in in a follow-up.

This PR will allow all (except `vue`) node-based language servers to
update. It is mostly just throwing in a method into the `NodeRuntime`
trait that is used for checking if a package doesn't exist locally, or
is out of date, by checking the version against what's newest, and
installing. If any parsing of the `package.json` data fails along the
way, it assumes something has gone awry on the users system, logs the
error, and then proceeds with trying to install the package, so that
users don't get stuck on version if their package has some bad data.
Outside of adding this method, it just adds that check in all of the
language server's individual `fetch_server_binary` methods.

Release Notes:

- Added updating for node-based language servers
([#9234](https://github.com/zed-industries/zed/issues/9234)).
This commit is contained in:
Joseph T. Lyons authored and GitHub committed 2024-03-15 11:40:28 -04:00
1 parent 87e38fc702
commit 56f118ce03
19 files changed
+213 -94

No files matched your search

+10 -5
View File
@@ -3,7 +3,6 @@ use async_trait::async_trait;
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
use lsp::LanguageServerBinary;
use node_runtime::NodeRuntime;
use smol::fs;
use std::{
any::Any,
ffi::OsString,
@@ -43,16 +42,22 @@ impl LspAdapter for PythonLspAdapter {
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
latest_version: Box<dyn 'static + Send + Any>,
container_dir: PathBuf,
_: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<String>().unwrap();
let latest_version = latest_version.downcast::<String>().unwrap();
let server_path = container_dir.join(SERVER_PATH);
let package_name = "pyright";
if fs::metadata(&server_path).await.is_err() {
let should_install_language_server = self
.node
.should_install_npm_package(package_name, &server_path, &container_dir, &latest_version)
.await;
if should_install_language_server {
self.node
.npm_install_packages(&container_dir, &[("pyright", version.as_str())])
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
.await?;
}