mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 08:02:22 +03:00
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:
parent
cb16003133
commit
276139f792
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -6091,6 +6091,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"futures 0.3.28",
|
||||
"log",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smol",
|
||||
|
@ -336,12 +336,12 @@ pub trait LspAdapter: 'static + Send + Sync {
|
||||
name.clone(),
|
||||
LanguageServerBinaryStatus::CheckingForUpdate,
|
||||
);
|
||||
let version_info = self.fetch_latest_server_version(delegate.as_ref()).await?;
|
||||
let latest_version = self.fetch_latest_server_version(delegate.as_ref()).await?;
|
||||
|
||||
log::info!("downloading language server {:?}", name.0);
|
||||
delegate.update_status(self.name(), LanguageServerBinaryStatus::Downloading);
|
||||
let mut binary = self
|
||||
.fetch_server_binary(version_info, container_dir.to_path_buf(), delegate.as_ref())
|
||||
.fetch_server_binary(latest_version, container_dir.to_path_buf(), delegate.as_ref())
|
||||
.await;
|
||||
|
||||
delegate.update_status(name.clone(), LanguageServerBinaryStatus::Downloaded);
|
||||
@ -408,7 +408,7 @@ pub trait LspAdapter: 'static + Send + Sync {
|
||||
|
||||
async fn fetch_server_binary(
|
||||
&self,
|
||||
version: Box<dyn 'static + Send + Any>,
|
||||
latest_version: Box<dyn 'static + Send + Any>,
|
||||
container_dir: PathBuf,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
) -> Result<LanguageServerBinary>;
|
||||
|
@ -49,19 +49,22 @@ impl LspAdapter for AstroLspAdapter {
|
||||
|
||||
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 = "@astrojs/language-server";
|
||||
|
||||
if fs::metadata(&server_path).await.is_err() {
|
||||
let should_install_npm_package = self
|
||||
.node
|
||||
.should_install_npm_package(package_name, &server_path, &container_dir, &latest_version)
|
||||
.await;
|
||||
|
||||
if should_install_npm_package {
|
||||
self.node
|
||||
.npm_install_packages(
|
||||
&container_dir,
|
||||
&[("@astrojs/language-server", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -50,19 +50,22 @@ impl LspAdapter for CssLspAdapter {
|
||||
|
||||
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 = "vscode-langservers-extracted";
|
||||
|
||||
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,
|
||||
&[("vscode-langservers-extracted", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -48,19 +48,22 @@ impl LspAdapter for DockerfileLspAdapter {
|
||||
|
||||
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 = "dockerfile-language-server-nodejs";
|
||||
|
||||
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,
|
||||
&[("dockerfile-language-server-nodejs", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -53,19 +53,22 @@ impl LspAdapter for ElmLspAdapter {
|
||||
|
||||
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 = "@elm-tooling/elm-language-server";
|
||||
|
||||
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,
|
||||
&[("@elm-tooling/elm-language-server", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -50,19 +50,22 @@ impl LspAdapter for HtmlLspAdapter {
|
||||
|
||||
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 = "vscode-langservers-extracted";
|
||||
|
||||
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,
|
||||
&[("vscode-langservers-extracted", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -102,19 +102,22 @@ impl LspAdapter for JsonLspAdapter {
|
||||
|
||||
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 = "vscode-json-languageserver";
|
||||
|
||||
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,
|
||||
&[("vscode-json-languageserver", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -51,18 +51,30 @@ impl LspAdapter for IntelephenseLspAdapter {
|
||||
|
||||
async fn fetch_server_binary(
|
||||
&self,
|
||||
version: Box<dyn 'static + Send + Any>,
|
||||
latest_version: Box<dyn 'static + Send + Any>,
|
||||
container_dir: PathBuf,
|
||||
_delegate: &dyn LspAdapterDelegate,
|
||||
) -> Result<LanguageServerBinary> {
|
||||
let version = version.downcast::<IntelephenseVersion>().unwrap();
|
||||
let latest_version = latest_version.downcast::<IntelephenseVersion>().unwrap();
|
||||
let server_path = container_dir.join(Self::SERVER_PATH);
|
||||
let package_name = "intelephense";
|
||||
|
||||
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.0.as_str(),
|
||||
)
|
||||
.await;
|
||||
|
||||
if should_install_language_server {
|
||||
self.node
|
||||
.npm_install_packages(&container_dir, &[("intelephense", version.0.as_str())])
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.0.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(LanguageServerBinary {
|
||||
path: self.node.binary_path().await?,
|
||||
env: None,
|
||||
|
@ -48,19 +48,22 @@ impl LspAdapter for PrismaLspAdapter {
|
||||
|
||||
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 = "@prisma/language-server";
|
||||
|
||||
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,
|
||||
&[("@prisma/language-server", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -52,19 +52,22 @@ impl LspAdapter for PurescriptLspAdapter {
|
||||
|
||||
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 = "purescript-language-server";
|
||||
|
||||
if fs::metadata(&server_path).await.is_err() {
|
||||
let should_install_npm_package = self
|
||||
.node
|
||||
.should_install_npm_package(package_name, &server_path, &container_dir, &latest_version)
|
||||
.await;
|
||||
|
||||
if should_install_npm_package {
|
||||
self.node
|
||||
.npm_install_packages(
|
||||
&container_dir,
|
||||
&[("purescript-language-server", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -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?;
|
||||
}
|
||||
|
||||
|
@ -49,19 +49,22 @@ impl LspAdapter for SvelteLspAdapter {
|
||||
|
||||
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 = "svelte-language-server";
|
||||
|
||||
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,
|
||||
&[("svelte-language-server", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -51,19 +51,22 @@ impl LspAdapter for TailwindLspAdapter {
|
||||
|
||||
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 = "@tailwindcss/language-server";
|
||||
|
||||
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,
|
||||
&[("@tailwindcss/language-server", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -71,22 +71,33 @@ impl LspAdapter for TypeScriptLspAdapter {
|
||||
|
||||
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::<TypeScriptVersions>().unwrap();
|
||||
let latest_version = latest_version.downcast::<TypeScriptVersions>().unwrap();
|
||||
let server_path = container_dir.join(Self::NEW_SERVER_PATH);
|
||||
let package_name = "typescript";
|
||||
|
||||
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.typescript_version.as_str(),
|
||||
)
|
||||
.await;
|
||||
|
||||
if should_install_language_server {
|
||||
self.node
|
||||
.npm_install_packages(
|
||||
&container_dir,
|
||||
&[
|
||||
("typescript", version.typescript_version.as_str()),
|
||||
(package_name, latest_version.typescript_version.as_str()),
|
||||
(
|
||||
"typescript-language-server",
|
||||
version.server_version.as_str(),
|
||||
latest_version.server_version.as_str(),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
@ -86,6 +86,7 @@ impl super::LspAdapter for VueLspAdapter {
|
||||
let version = version.downcast::<VueLspVersion>().unwrap();
|
||||
let server_path = container_dir.join(Self::SERVER_PATH);
|
||||
let ts_path = container_dir.join(Self::TYPESCRIPT_PATH);
|
||||
|
||||
if fs::metadata(&server_path).await.is_err() {
|
||||
self.node
|
||||
.npm_install_packages(
|
||||
|
@ -52,19 +52,22 @@ impl LspAdapter for YamlLspAdapter {
|
||||
|
||||
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 = "yaml-language-server";
|
||||
|
||||
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,
|
||||
&[("yaml-language-server", version.as_str())],
|
||||
)
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ async-tar.workspace = true
|
||||
async-trait.workspace = true
|
||||
futures.workspace = true
|
||||
log.workspace = true
|
||||
semver.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
smol.workspace = true
|
||||
|
@ -1,7 +1,10 @@
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use async_compression::futures::bufread::GzipDecoder;
|
||||
use async_tar::Archive;
|
||||
use futures::AsyncReadExt;
|
||||
use semver::Version;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
use smol::{fs, io::BufReader, lock::Mutex, process::Command};
|
||||
use std::process::{Output, Stdio};
|
||||
use std::{
|
||||
@ -10,6 +13,7 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
use util::http::HttpClient;
|
||||
use util::ResultExt;
|
||||
|
||||
const VERSION: &str = "v18.15.0";
|
||||
|
||||
@ -41,6 +45,56 @@ pub trait NodeRuntime: Send + Sync {
|
||||
|
||||
async fn npm_install_packages(&self, directory: &Path, packages: &[(&str, &str)])
|
||||
-> Result<()>;
|
||||
|
||||
async fn should_install_npm_package(
|
||||
&self,
|
||||
package_name: &str,
|
||||
local_executable_path: &Path,
|
||||
local_package_directory: &PathBuf,
|
||||
latest_version: &str,
|
||||
) -> bool {
|
||||
// In the case of the local system not having the package installed,
|
||||
// or in the instances where we fail to parse package.json data,
|
||||
// we attempt to install the package.
|
||||
if fs::metadata(local_executable_path).await.is_err() {
|
||||
return true;
|
||||
}
|
||||
|
||||
let package_json_path = local_package_directory.join("package.json");
|
||||
|
||||
let mut contents = String::new();
|
||||
|
||||
let Some(mut file) = fs::File::open(package_json_path).await.log_err() else {
|
||||
return true;
|
||||
};
|
||||
|
||||
file.read_to_string(&mut contents).await.log_err();
|
||||
|
||||
let Some(package_json): Option<Value> = serde_json::from_str(&contents).log_err() else {
|
||||
return true;
|
||||
};
|
||||
|
||||
let installed_version = package_json
|
||||
.get("dependencies")
|
||||
.and_then(|deps| deps.get(package_name))
|
||||
.and_then(|server_name| server_name.as_str());
|
||||
|
||||
let Some(installed_version) = installed_version else {
|
||||
return true;
|
||||
};
|
||||
|
||||
let Some(latest_version) = Version::parse(latest_version).log_err() else {
|
||||
return true;
|
||||
};
|
||||
|
||||
let installed_version = installed_version.trim_start_matches(|c: char| !c.is_ascii_digit());
|
||||
|
||||
let Some(installed_version) = Version::parse(installed_version).log_err() else {
|
||||
return true;
|
||||
};
|
||||
|
||||
installed_version < latest_version
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RealNodeRuntime {
|
||||
@ -239,6 +293,7 @@ impl NodeRuntime for RealNodeRuntime {
|
||||
|
||||
let mut arguments: Vec<_> = packages.iter().map(|p| p.as_str()).collect();
|
||||
arguments.extend_from_slice(&[
|
||||
"--save-exact",
|
||||
"--fetch-retry-mintimeout",
|
||||
"2000",
|
||||
"--fetch-retry-maxtimeout",
|
||||
|
Loading…
Reference in New Issue
Block a user