Invoke npm from downloaded Node

This commit is contained in:
Julia 2023-03-23 18:31:46 -04:00
parent edd6c85af7
commit ed442cfc8c
7 changed files with 45 additions and 25 deletions

View File

@ -13,9 +13,7 @@ use client::{
use collections::{HashMap, HashSet};
use fs::FakeFs;
use futures::{channel::oneshot, StreamExt as _};
use gpui::{
executor::Deterministic, test::EmptyView, ModelHandle, Task, TestAppContext, ViewHandle,
};
use gpui::{executor::Deterministic, test::EmptyView, ModelHandle, TestAppContext, ViewHandle};
use language::LanguageRegistry;
use parking_lot::Mutex;
use project::{Project, WorktreeId};

View File

@ -32,15 +32,18 @@ impl LspAdapter for HtmlLspAdapter {
async fn fetch_latest_server_version(
&self,
_: Arc<dyn HttpClient>,
http: Arc<dyn HttpClient>,
) -> Result<Box<dyn 'static + Any + Send>> {
Ok(Box::new(npm_package_latest_version("vscode-langservers-extracted").await?) as Box<_>)
Ok(
Box::new(npm_package_latest_version(http, "vscode-langservers-extracted").await?)
as Box<_>,
)
}
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
_: Arc<dyn HttpClient>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
let version = version.downcast::<String>().unwrap();
@ -52,6 +55,7 @@ impl LspAdapter for HtmlLspAdapter {
if fs::metadata(&binary_path).await.is_err() {
npm_install_packages(
http,
[("vscode-langservers-extracted", version.as_str())],
&version_dir,
)

View File

@ -2,9 +2,9 @@ use anyhow::{anyhow, Context, Result};
use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive;
use client::http::HttpClient;
use futures::{io::BufReader, StreamExt};
use futures::io::BufReader;
use serde::Deserialize;
use smol::fs::{self, File};
use smol::fs::{self};
use smol::io::AsyncReadExt;
use std::{
path::{Path, PathBuf},
@ -75,10 +75,16 @@ pub async fn ensure_node_installation_dir(http: Arc<dyn HttpClient>) -> Result<P
Ok(dbg!(node_dir))
}
pub async fn npm_package_latest_version(name: &str) -> Result<String> {
let output = smol::process::Command::new("npm")
pub async fn npm_package_latest_version(http: Arc<dyn HttpClient>, name: &str) -> Result<String> {
let node_dir = ensure_node_installation_dir(http).await?;
let node_binary = node_dir.join("bin/npm");
let npm_file = node_dir.join("bin/npm");
let output = smol::process::Command::new(node_binary)
.arg(npm_file)
.args(["-fetch-retry-mintimeout", "2000"])
.args(["-fetch-retry-maxtimeout", "5000"])
.args(["-fetch-timeout", "5000"])
.args(["info", name, "--json"])
.output()
.await
@ -98,12 +104,19 @@ pub async fn npm_package_latest_version(name: &str) -> Result<String> {
}
pub async fn npm_install_packages(
http: Arc<dyn HttpClient>,
packages: impl IntoIterator<Item = (&str, &str)>,
directory: &Path,
) -> Result<()> {
let output = smol::process::Command::new("npm")
let node_dir = ensure_node_installation_dir(http).await?;
let node_binary = node_dir.join("bin/npm");
let npm_file = node_dir.join("bin/npm");
let output = smol::process::Command::new(node_binary)
.arg(npm_file)
.args(["-fetch-retry-mintimeout", "2000"])
.args(["-fetch-retry-maxtimeout", "5000"])
.args(["-fetch-timeout", "5000"])
.arg("install")
.arg("--prefix")
.arg(directory)

View File

@ -30,15 +30,15 @@ impl LspAdapter for PythonLspAdapter {
async fn fetch_latest_server_version(
&self,
_: Arc<dyn HttpClient>,
http: Arc<dyn HttpClient>,
) -> Result<Box<dyn 'static + Any + Send>> {
Ok(Box::new(npm_package_latest_version("pyright").await?) as Box<_>)
Ok(Box::new(npm_package_latest_version(http, "pyright").await?) as Box<_>)
}
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
_: Arc<dyn HttpClient>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
let version = version.downcast::<String>().unwrap();
@ -49,7 +49,7 @@ impl LspAdapter for PythonLspAdapter {
let binary_path = version_dir.join(Self::BIN_PATH);
if fs::metadata(&binary_path).await.is_err() {
npm_install_packages([("pyright", version.as_str())], &version_dir).await?;
npm_install_packages(http, [("pyright", version.as_str())], &version_dir).await?;
if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() {
while let Some(entry) = entries.next().await {

View File

@ -40,18 +40,18 @@ impl LspAdapter for TypeScriptLspAdapter {
async fn fetch_latest_server_version(
&self,
_: Arc<dyn HttpClient>,
http: Arc<dyn HttpClient>,
) -> Result<Box<dyn 'static + Send + Any>> {
Ok(Box::new(Versions {
typescript_version: npm_package_latest_version("typescript").await?,
server_version: npm_package_latest_version("typescript-language-server").await?,
typescript_version: npm_package_latest_version(http.clone(), "typescript").await?,
server_version: npm_package_latest_version(http, "typescript-language-server").await?,
}) as Box<_>)
}
async fn fetch_server_binary(
&self,
versions: Box<dyn 'static + Send + Any>,
_: Arc<dyn HttpClient>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
let versions = versions.downcast::<Versions>().unwrap();
@ -66,6 +66,7 @@ impl LspAdapter for TypeScriptLspAdapter {
if fs::metadata(&binary_path).await.is_err() {
npm_install_packages(
http,
[
("typescript", versions.typescript_version.as_str()),
(

View File

@ -34,15 +34,15 @@ impl LspAdapter for YamlLspAdapter {
async fn fetch_latest_server_version(
&self,
_: Arc<dyn HttpClient>,
http: Arc<dyn HttpClient>,
) -> Result<Box<dyn 'static + Any + Send>> {
Ok(Box::new(npm_package_latest_version("yaml-language-server").await?) as Box<_>)
Ok(Box::new(npm_package_latest_version(http, "yaml-language-server").await?) as Box<_>)
}
async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
_: Arc<dyn HttpClient>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
let version = version.downcast::<String>().unwrap();
@ -53,8 +53,12 @@ impl LspAdapter for YamlLspAdapter {
let binary_path = version_dir.join(Self::BIN_PATH);
if fs::metadata(&binary_path).await.is_err() {
npm_install_packages([("yaml-language-server", version.as_str())], &version_dir)
.await?;
npm_install_packages(
http,
[("yaml-language-server", version.as_str())],
&version_dir,
)
.await?;
if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() {
while let Some(entry) = entries.next().await {

View File

@ -654,7 +654,7 @@ mod tests {
use assets::Assets;
use editor::{scroll::autoscroll::Autoscroll, DisplayPoint, Editor};
use gpui::{
executor::Deterministic, AssetSource, MutableAppContext, Task, TestAppContext, ViewHandle,
executor::Deterministic, AssetSource, MutableAppContext, TestAppContext, ViewHandle,
};
use language::LanguageRegistry;
use project::{Project, ProjectPath};