Fix Linux rust-analyzer downloads in Preview (#20718)

Follow-up of https://github.com/zed-industries/zed/pull/20408

Release Notes:

- (Preview) Fixed broken rust-analyzer downloads
This commit is contained in:
Kirill Bulatov 2024-11-15 11:57:54 +02:00 committed by GitHub
parent f619a872b5
commit 1e14697bb6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 55 additions and 10 deletions

View file

@ -121,6 +121,7 @@ pub async fn get_release_by_tag_name(
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum AssetKind { pub enum AssetKind {
TarGz, TarGz,
Gz,
Zip, Zip,
} }
@ -134,6 +135,7 @@ pub fn build_asset_url(repo_name_with_owner: &str, tag: &str, kind: AssetKind) -
"{tag}.{extension}", "{tag}.{extension}",
extension = match kind { extension = match kind {
AssetKind::TarGz => "tar.gz", AssetKind::TarGz => "tar.gz",
AssetKind::Gz => "gz",
AssetKind::Zip => "zip", AssetKind::Zip => "zip",
} }
); );

View file

@ -26,13 +26,13 @@ pub struct RustLspAdapter;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
impl RustLspAdapter { impl RustLspAdapter {
const GITHUB_ASSET_KIND: AssetKind = AssetKind::TarGz; const GITHUB_ASSET_KIND: AssetKind = AssetKind::Gz;
const ARCH_SERVER_NAME: &str = "apple-darwin"; const ARCH_SERVER_NAME: &str = "apple-darwin";
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
impl RustLspAdapter { impl RustLspAdapter {
const GITHUB_ASSET_KIND: AssetKind = AssetKind::TarGz; const GITHUB_ASSET_KIND: AssetKind = AssetKind::Gz;
const ARCH_SERVER_NAME: &str = "unknown-linux-gnu"; const ARCH_SERVER_NAME: &str = "unknown-linux-gnu";
} }
@ -47,7 +47,8 @@ impl RustLspAdapter {
fn build_asset_name() -> String { fn build_asset_name() -> String {
let extension = match Self::GITHUB_ASSET_KIND { 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", AssetKind::Zip => "zip",
}; };
@ -134,7 +135,7 @@ impl LspAdapter for RustLspAdapter {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap(); let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let destination_path = container_dir.join(format!("rust-analyzer-{}", version.name)); let destination_path = container_dir.join(format!("rust-analyzer-{}", version.name));
let server_path = match Self::GITHUB_ASSET_KIND { 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 AssetKind::Zip => destination_path.clone().join("rust-analyzer.exe"), // zip contains a .exe
}; };
@ -145,19 +146,40 @@ impl LspAdapter for RustLspAdapter {
.http_client() .http_client()
.get(&version.url, Default::default(), true) .get(&version.url, Default::default(), true)
.await .await
.map_err(|err| anyhow!("error downloading release: {}", err))?; .with_context(|| format!("downloading release from {}", version.url))?;
match Self::GITHUB_ASSET_KIND { match Self::GITHUB_ASSET_KIND {
AssetKind::TarGz => { AssetKind::TarGz => {
let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut())); let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
let archive = async_tar::Archive::new(decompressed_bytes); 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 => { AssetKind::Zip => {
node_runtime::extract_zip( node_runtime::extract_zip(
&destination_path, &destination_path,
BufReader::new(response.body_mut()), BufReader::new(response.body_mut()),
) )
.await?; .await
.with_context(|| {
format!("unzipping {} to {:?}", version.url, destination_path)
})?;
} }
}; };

View file

@ -1,4 +1,4 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Context as _, Result};
use async_compression::futures::bufread::GzipDecoder; use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive; use async_tar::Archive;
use async_trait::async_trait; use async_trait::async_trait;
@ -445,14 +445,35 @@ impl LspAdapter for EsLintLspAdapter {
AssetKind::TarGz => { AssetKind::TarGz => {
let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut())); let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
let archive = Archive::new(decompressed_bytes); 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 => { AssetKind::Zip => {
node_runtime::extract_zip( node_runtime::extract_zip(
&destination_path, &destination_path,
BufReader::new(response.body_mut()), BufReader::new(response.body_mut()),
) )
.await?; .await
.with_context(|| {
format!("unzipping {} to {:?}", version.url, destination_path)
})?;
} }
} }