From 89b1e76003c1212c371449bcdd8eddf3d9ead18b Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 8 Feb 2024 16:17:47 +0200 Subject: [PATCH] Fix gopls langserver downloads (#7571) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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)) --- crates/copilot/src/copilot.rs | 5 +++-- crates/util/src/github.rs | 4 +++- crates/zed/src/languages/c.rs | 3 ++- crates/zed/src/languages/csharp.rs | 11 +++++++---- crates/zed/src/languages/deno.rs | 3 ++- crates/zed/src/languages/elixir.rs | 17 +++++++++-------- crates/zed/src/languages/gleam.rs | 2 +- crates/zed/src/languages/go.rs | 3 ++- crates/zed/src/languages/lua.rs | 14 +++++++++----- crates/zed/src/languages/rust.rs | 9 +++++++-- crates/zed/src/languages/toml.rs | 3 ++- crates/zed/src/languages/typescript.rs | 9 +++++++-- crates/zed/src/languages/zig.rs | 5 +++-- 13 files changed, 57 insertions(+), 31 deletions(-) diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index d4d7539a05..b8d38c757e 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -976,7 +976,8 @@ async fn get_copilot_lsp(http: Arc) -> anyhow::Result { ///Check for the latest copilot language server and download it if we haven't already async fn fetch_latest(http: Arc) -> anyhow::Result { - let release = latest_github_release("zed-industries/copilot", false, http.clone()).await?; + let release = + latest_github_release("zed-industries/copilot", true, false, http.clone()).await?; let version_dir = &*paths::COPILOT_DIR.join(format!("copilot-{}", release.name)); @@ -997,7 +998,7 @@ async fn get_copilot_lsp(http: Arc) -> anyhow::Result { let mut response = http .get(url, Default::default(), true) .await - .map_err(|err| anyhow!("error downloading copilot release: {}", err))?; + .context("error downloading copilot release")?; let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut())); let archive = Archive::new(decompressed_bytes); archive.unpack(dist_dir).await?; diff --git a/crates/util/src/github.rs b/crates/util/src/github.rs index fc250be32f..8503c69267 100644 --- a/crates/util/src/github.rs +++ b/crates/util/src/github.rs @@ -27,6 +27,7 @@ pub struct GithubReleaseAsset { pub async fn latest_github_release( repo_name_with_owner: &str, + require_assets: bool, pre_release: bool, http: Arc, ) -> Result { @@ -68,6 +69,7 @@ pub async fn latest_github_release( releases .into_iter() - .find(|release| !release.assets.is_empty() && release.pre_release == pre_release) + .filter(|release| !require_assets || !release.assets.is_empty()) + .find(|release| release.pre_release == pre_release) .ok_or(anyhow!("Failed to find a release")) } diff --git a/crates/zed/src/languages/c.rs b/crates/zed/src/languages/c.rs index 655ac044c1..8b5902ff75 100644 --- a/crates/zed/src/languages/c.rs +++ b/crates/zed/src/languages/c.rs @@ -28,7 +28,8 @@ impl super::LspAdapter for CLspAdapter { &self, delegate: &dyn LspAdapterDelegate, ) -> Result> { - let release = latest_github_release("clangd/clangd", false, delegate.http_client()).await?; + let release = + latest_github_release("clangd/clangd", true, false, delegate.http_client()).await?; let asset_name = format!("clangd-mac-{}.zip", release.name); let asset = release .assets diff --git a/crates/zed/src/languages/csharp.rs b/crates/zed/src/languages/csharp.rs index e70bc78279..9d3c63ed51 100644 --- a/crates/zed/src/languages/csharp.rs +++ b/crates/zed/src/languages/csharp.rs @@ -29,10 +29,6 @@ impl super::LspAdapter for OmniSharpAdapter { &self, delegate: &dyn LspAdapterDelegate, ) -> Result> { - let release = - latest_github_release("OmniSharp/omnisharp-roslyn", false, delegate.http_client()) - .await?; - let mapped_arch = match ARCH { "aarch64" => Some("arm64"), "x86_64" => Some("x64"), @@ -42,6 +38,13 @@ impl super::LspAdapter for OmniSharpAdapter { match mapped_arch { None => Ok(Box::new(())), Some(arch) => { + let release = latest_github_release( + "OmniSharp/omnisharp-roslyn", + true, + false, + delegate.http_client(), + ) + .await?; let asset_name = format!("omnisharp-osx-{}-net6.0.tar.gz", arch); let asset = release .assets diff --git a/crates/zed/src/languages/deno.rs b/crates/zed/src/languages/deno.rs index 475181ec3f..0020f94a46 100644 --- a/crates/zed/src/languages/deno.rs +++ b/crates/zed/src/languages/deno.rs @@ -70,7 +70,8 @@ impl LspAdapter for DenoLspAdapter { &self, delegate: &dyn LspAdapterDelegate, ) -> Result> { - let release = latest_github_release("denoland/deno", false, delegate.http_client()).await?; + let release = + latest_github_release("denoland/deno", true, false, delegate.http_client()).await?; let asset_name = format!("deno-{}-apple-darwin.zip", consts::ARCH); let asset = release .assets diff --git a/crates/zed/src/languages/elixir.rs b/crates/zed/src/languages/elixir.rs index 6172be1683..f6b19ad066 100644 --- a/crates/zed/src/languages/elixir.rs +++ b/crates/zed/src/languages/elixir.rs @@ -111,19 +111,19 @@ impl LspAdapter for ElixirLspAdapter { delegate: &dyn LspAdapterDelegate, ) -> Result> { let http = delegate.http_client(); - let release = latest_github_release("elixir-lsp/elixir-ls", false, http).await?; + let release = latest_github_release("elixir-lsp/elixir-ls", true, false, http).await?; let version_name = release .name .strip_prefix("Release ") .context("Elixir-ls release name does not start with prefix")? .to_owned(); - let asset_name = format!("elixir-ls-{}.zip", &version_name); + let asset_name = format!("elixir-ls-{version_name}.zip"); let asset = release .assets .iter() .find(|asset| asset.name == asset_name) - .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?; + .ok_or_else(|| anyhow!("no asset found matching {asset_name:?}"))?; let version = GitHubLspBinaryVersion { name: version_name, @@ -313,20 +313,21 @@ impl LspAdapter for NextLspAdapter { &self, delegate: &dyn LspAdapterDelegate, ) -> Result> { - let release = - latest_github_release("elixir-tools/next-ls", false, delegate.http_client()).await?; - let version = release.name.clone(); let platform = match consts::ARCH { "x86_64" => "darwin_amd64", "aarch64" => "darwin_arm64", other => bail!("Running on unsupported platform: {other}"), }; - let asset_name = format!("next_ls_{}", platform); + let release = + latest_github_release("elixir-tools/next-ls", true, false, delegate.http_client()) + .await?; + let version = release.name; + let asset_name = format!("next_ls_{platform}"); let asset = release .assets .iter() .find(|asset| asset.name == asset_name) - .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?; + .with_context(|| format!("no asset found matching {asset_name:?}"))?; let version = GitHubLspBinaryVersion { name: version, url: asset.browser_download_url.clone(), diff --git a/crates/zed/src/languages/gleam.rs b/crates/zed/src/languages/gleam.rs index 90b10a3657..d8020a0a85 100644 --- a/crates/zed/src/languages/gleam.rs +++ b/crates/zed/src/languages/gleam.rs @@ -35,7 +35,7 @@ impl LspAdapter for GleamLspAdapter { delegate: &dyn LspAdapterDelegate, ) -> Result> { let release = - latest_github_release("gleam-lang/gleam", false, delegate.http_client()).await?; + latest_github_release("gleam-lang/gleam", true, false, delegate.http_client()).await?; let asset_name = format!( "gleam-{version}-{arch}-apple-darwin.tar.gz", diff --git a/crates/zed/src/languages/go.rs b/crates/zed/src/languages/go.rs index 2fb0d35cf0..871ff0886f 100644 --- a/crates/zed/src/languages/go.rs +++ b/crates/zed/src/languages/go.rs @@ -45,7 +45,8 @@ impl super::LspAdapter for GoLspAdapter { &self, delegate: &dyn LspAdapterDelegate, ) -> Result> { - let release = latest_github_release("golang/tools", false, delegate.http_client()).await?; + let release = + latest_github_release("golang/tools", false, false, delegate.http_client()).await?; let version: Option = release.name.strip_prefix("gopls/v").map(str::to_string); if version.is_none() { log::warn!( diff --git a/crates/zed/src/languages/lua.rs b/crates/zed/src/languages/lua.rs index c9753e0f6c..c25bb3d125 100644 --- a/crates/zed/src/languages/lua.rs +++ b/crates/zed/src/languages/lua.rs @@ -30,15 +30,19 @@ impl super::LspAdapter for LuaLspAdapter { &self, delegate: &dyn LspAdapterDelegate, ) -> Result> { - let release = - latest_github_release("LuaLS/lua-language-server", false, delegate.http_client()) - .await?; - let version = release.name.clone(); let platform = match consts::ARCH { "x86_64" => "x64", "aarch64" => "arm64", other => bail!("Running on unsupported platform: {other}"), }; + let release = latest_github_release( + "LuaLS/lua-language-server", + true, + false, + delegate.http_client(), + ) + .await?; + let version = &release.name; let asset_name = format!("lua-language-server-{version}-darwin-{platform}.tar.gz"); let asset = release .assets @@ -46,7 +50,7 @@ impl super::LspAdapter for LuaLspAdapter { .find(|asset| asset.name == asset_name) .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?; let version = GitHubLspBinaryVersion { - name: release.name.clone(), + name: release.name, url: asset.browser_download_url.clone(), }; Ok(Box::new(version) as Box<_>) diff --git a/crates/zed/src/languages/rust.rs b/crates/zed/src/languages/rust.rs index ffbe706fe8..bd00e9350c 100644 --- a/crates/zed/src/languages/rust.rs +++ b/crates/zed/src/languages/rust.rs @@ -31,8 +31,13 @@ impl LspAdapter for RustLspAdapter { &self, delegate: &dyn LspAdapterDelegate, ) -> Result> { - let release = - latest_github_release("rust-lang/rust-analyzer", false, delegate.http_client()).await?; + let release = latest_github_release( + "rust-lang/rust-analyzer", + true, + false, + delegate.http_client(), + ) + .await?; let asset_name = format!("rust-analyzer-{}-apple-darwin.gz", consts::ARCH); let asset = release .assets diff --git a/crates/zed/src/languages/toml.rs b/crates/zed/src/languages/toml.rs index 129b5fcb66..e16109be9a 100644 --- a/crates/zed/src/languages/toml.rs +++ b/crates/zed/src/languages/toml.rs @@ -26,7 +26,8 @@ impl LspAdapter for TaploLspAdapter { &self, delegate: &dyn LspAdapterDelegate, ) -> Result> { - let release = latest_github_release("tamasfe/taplo", false, delegate.http_client()).await?; + let release = + latest_github_release("tamasfe/taplo", true, false, delegate.http_client()).await?; let asset_name = format!("taplo-full-darwin-{arch}.gz", arch = std::env::consts::ARCH); let asset = release diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs index 08dc21965b..ff83220922 100644 --- a/crates/zed/src/languages/typescript.rs +++ b/crates/zed/src/languages/typescript.rs @@ -246,8 +246,13 @@ impl LspAdapter for EsLintLspAdapter { // At the time of writing the latest vscode-eslint release was released in 2020 and requires // special custom LSP protocol extensions be handled to fully initialize. Download the latest // prerelease instead to sidestep this issue - let release = - latest_github_release("microsoft/vscode-eslint", true, delegate.http_client()).await?; + let release = latest_github_release( + "microsoft/vscode-eslint", + false, + false, + delegate.http_client(), + ) + .await?; Ok(Box::new(GitHubLspBinaryVersion { name: release.name, url: release.tarball_url, diff --git a/crates/zed/src/languages/zig.rs b/crates/zed/src/languages/zig.rs index 734d21e2ea..8fac5c195f 100644 --- a/crates/zed/src/languages/zig.rs +++ b/crates/zed/src/languages/zig.rs @@ -28,8 +28,9 @@ impl LspAdapter for ZlsAdapter { &self, delegate: &dyn LspAdapterDelegate, ) -> Result> { - let release = latest_github_release("zigtools/zls", false, delegate.http_client()).await?; - let asset_name = format!("zls-{}-macos.tar.gz", ARCH); + let release = + latest_github_release("zigtools/zls", true, false, delegate.http_client()).await?; + let asset_name = format!("zls-{ARCH}-macos.tar.gz"); let asset = release .assets .iter()