diff --git a/crates/http_client/src/github.rs b/crates/http_client/src/github.rs index 70587fa3ce..649daa9e31 100644 --- a/crates/http_client/src/github.rs +++ b/crates/http_client/src/github.rs @@ -121,6 +121,7 @@ pub async fn get_release_by_tag_name( #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum AssetKind { TarGz, + Gz, Zip, } @@ -134,6 +135,7 @@ pub fn build_asset_url(repo_name_with_owner: &str, tag: &str, kind: AssetKind) - "{tag}.{extension}", extension = match kind { AssetKind::TarGz => "tar.gz", + AssetKind::Gz => "gz", AssetKind::Zip => "zip", } ); diff --git a/crates/languages/src/rust.rs b/crates/languages/src/rust.rs index d074a74f7a..c5e1fab9d3 100644 --- a/crates/languages/src/rust.rs +++ b/crates/languages/src/rust.rs @@ -26,13 +26,13 @@ pub struct RustLspAdapter; #[cfg(target_os = "macos")] impl RustLspAdapter { - const GITHUB_ASSET_KIND: AssetKind = AssetKind::TarGz; + const GITHUB_ASSET_KIND: AssetKind = AssetKind::Gz; const ARCH_SERVER_NAME: &str = "apple-darwin"; } #[cfg(target_os = "linux")] impl RustLspAdapter { - const GITHUB_ASSET_KIND: AssetKind = AssetKind::TarGz; + const GITHUB_ASSET_KIND: AssetKind = AssetKind::Gz; const ARCH_SERVER_NAME: &str = "unknown-linux-gnu"; } @@ -47,7 +47,8 @@ impl RustLspAdapter { fn build_asset_name() -> String { let extension = match Self::GITHUB_ASSET_KIND { - AssetKind::TarGz => "gz", // Nb: rust-analyzer releases use .gz not .tar.gz + AssetKind::TarGz => "tar.gz", + AssetKind::Gz => "gz", AssetKind::Zip => "zip", }; @@ -134,7 +135,7 @@ impl LspAdapter for RustLspAdapter { let version = version.downcast::().unwrap(); let destination_path = container_dir.join(format!("rust-analyzer-{}", version.name)); let server_path = match Self::GITHUB_ASSET_KIND { - AssetKind::TarGz => destination_path.clone(), // Tar extracts in place. + AssetKind::TarGz | AssetKind::Gz => destination_path.clone(), // Tar and gzip extract in place. AssetKind::Zip => destination_path.clone().join("rust-analyzer.exe"), // zip contains a .exe }; @@ -145,19 +146,40 @@ impl LspAdapter for RustLspAdapter { .http_client() .get(&version.url, Default::default(), true) .await - .map_err(|err| anyhow!("error downloading release: {}", err))?; + .with_context(|| format!("downloading release from {}", version.url))?; match Self::GITHUB_ASSET_KIND { AssetKind::TarGz => { let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut())); let archive = async_tar::Archive::new(decompressed_bytes); - archive.unpack(&destination_path).await?; + archive.unpack(&destination_path).await.with_context(|| { + format!("extracting {} to {:?}", version.url, destination_path) + })?; + } + AssetKind::Gz => { + let mut decompressed_bytes = + GzipDecoder::new(BufReader::new(response.body_mut())); + let mut file = + fs::File::create(&destination_path).await.with_context(|| { + format!( + "creating a file {:?} for a download from {}", + destination_path, version.url, + ) + })?; + futures::io::copy(&mut decompressed_bytes, &mut file) + .await + .with_context(|| { + format!("extracting {} to {:?}", version.url, destination_path) + })?; } AssetKind::Zip => { node_runtime::extract_zip( &destination_path, BufReader::new(response.body_mut()), ) - .await?; + .await + .with_context(|| { + format!("unzipping {} to {:?}", version.url, destination_path) + })?; } }; diff --git a/crates/languages/src/typescript.rs b/crates/languages/src/typescript.rs index ffce5f8274..c580575a1e 100644 --- a/crates/languages/src/typescript.rs +++ b/crates/languages/src/typescript.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context as _, Result}; use async_compression::futures::bufread::GzipDecoder; use async_tar::Archive; use async_trait::async_trait; @@ -445,14 +445,35 @@ impl LspAdapter for EsLintLspAdapter { AssetKind::TarGz => { let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut())); let archive = Archive::new(decompressed_bytes); - archive.unpack(&destination_path).await?; + archive.unpack(&destination_path).await.with_context(|| { + format!("extracting {} to {:?}", version.url, destination_path) + })?; + } + AssetKind::Gz => { + let mut decompressed_bytes = + GzipDecoder::new(BufReader::new(response.body_mut())); + let mut file = + fs::File::create(&destination_path).await.with_context(|| { + format!( + "creating a file {:?} for a download from {}", + destination_path, version.url, + ) + })?; + futures::io::copy(&mut decompressed_bytes, &mut file) + .await + .with_context(|| { + format!("extracting {} to {:?}", version.url, destination_path) + })?; } AssetKind::Zip => { node_runtime::extract_zip( &destination_path, BufReader::new(response.body_mut()), ) - .await?; + .await + .with_context(|| { + format!("unzipping {} to {:?}", version.url, destination_path) + })?; } }