Fixes https://github.com/zed-industries/zed/issues/7534 by not requiring assets for gopls and vscode-eslint langservers — those two are the only ones in Zed that do not use assets directly when determining langserver version and retrieving those. All other servers deal with assets, hence require those to be present. The problem with https://github.com/tamasfe/taplo/releases is that they host multiple binary releases in the same release list, so for now the code works because only the langserver has assets — but as soon as another release there gets assets, it will break again. We could filter out those by names also, but they also tend to change (and can be edited manually), so keeping it as is for now. Release Notes: - Fixed gopls language server downloads ([7534](https://github.com/zed-industries/zed/issues/7534))
76 lines
2.0 KiB
Rust
76 lines
2.0 KiB
Rust
use crate::http::HttpClient;
|
|
use anyhow::{anyhow, bail, Context, Result};
|
|
use futures::AsyncReadExt;
|
|
use serde::Deserialize;
|
|
use std::sync::Arc;
|
|
|
|
pub struct GitHubLspBinaryVersion {
|
|
pub name: String,
|
|
pub url: String,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct GithubRelease {
|
|
pub name: String,
|
|
#[serde(rename = "prerelease")]
|
|
pub pre_release: bool,
|
|
pub assets: Vec<GithubReleaseAsset>,
|
|
pub tarball_url: String,
|
|
pub zipball_url: String,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct GithubReleaseAsset {
|
|
pub name: String,
|
|
pub browser_download_url: String,
|
|
}
|
|
|
|
pub async fn latest_github_release(
|
|
repo_name_with_owner: &str,
|
|
require_assets: bool,
|
|
pre_release: bool,
|
|
http: Arc<dyn HttpClient>,
|
|
) -> Result<GithubRelease, anyhow::Error> {
|
|
let mut response = http
|
|
.get(
|
|
&format!("https://api.github.com/repos/{repo_name_with_owner}/releases"),
|
|
Default::default(),
|
|
true,
|
|
)
|
|
.await
|
|
.context("error fetching latest release")?;
|
|
|
|
let mut body = Vec::new();
|
|
response
|
|
.body_mut()
|
|
.read_to_end(&mut body)
|
|
.await
|
|
.context("error reading latest release")?;
|
|
|
|
if response.status().is_client_error() {
|
|
let text = String::from_utf8_lossy(body.as_slice());
|
|
bail!(
|
|
"status error {}, response: {text:?}",
|
|
response.status().as_u16()
|
|
);
|
|
}
|
|
|
|
let releases = match serde_json::from_slice::<Vec<GithubRelease>>(body.as_slice()) {
|
|
Ok(releases) => releases,
|
|
|
|
Err(_) => {
|
|
log::error!(
|
|
"Error deserializing GitHub API response text: {:?}",
|
|
String::from_utf8_lossy(body.as_slice())
|
|
);
|
|
return Err(anyhow!("error deserializing latest release"));
|
|
}
|
|
};
|
|
|
|
releases
|
|
.into_iter()
|
|
.filter(|release| !require_assets || !release.assets.is_empty())
|
|
.find(|release| release.pre_release == pre_release)
|
|
.ok_or(anyhow!("Failed to find a release"))
|
|
}
|