From 94805ceb8d67bbfaaab0741f16ea9d9cd304f399 Mon Sep 17 00:00:00 2001 From: Alexey Olshanskiy Date: Tue, 8 Oct 2024 21:01:44 +0300 Subject: [PATCH 1/2] Add helm_ls download --- Cargo.toml | 2 +- languages/helm/config.toml | 4 +- src/helm.rs | 121 ++++++++++++++++++++++++++++++++++--- 3 files changed, 115 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4e1d8d3..42b0702 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,4 @@ path = "src/helm.rs" crate-type = ["cdylib"] [dependencies] -zed_extension_api = "0.0.4" \ No newline at end of file +zed_extension_api = "0.1.0" diff --git a/languages/helm/config.toml b/languages/helm/config.toml index fcc0fc4..348e6e6 100644 --- a/languages/helm/config.toml +++ b/languages/helm/config.toml @@ -3,8 +3,8 @@ grammar = "helm" path_suffixes = [ "gotmpl", "helmfile.yaml", - "templates/**/*.tpl", - "templates/**/*.yaml", + "**/templates/**/*.tpl", + "**/templates/**/*.yaml", ] line_comments = ["# "] block_comment = ["{{/* ", " */}}"] diff --git a/src/helm.rs b/src/helm.rs index 54b277e..8b0d232 100644 --- a/src/helm.rs +++ b/src/helm.rs @@ -1,27 +1,130 @@ +use std::fs; +use zed::LanguageServerId; use zed_extension_api::{self as zed, Result}; -struct HelmExtension; +struct HelmExtension { + cached_binary_path: Option, +} + +impl HelmExtension { + fn language_server_binary_path( + &mut self, + language_server_id: &LanguageServerId, + worktree: &zed::Worktree, + ) -> Result { + if let Some(path) = &self.cached_binary_path { + if fs::metadata(path).map_or(false, |stat| stat.is_file()) { + return Ok(path.clone()); + } + } + + if let Some(path) = worktree.which("helm_ls") { + self.cached_binary_path = Some(path.clone()); + return Ok(path); + } + + zed::set_language_server_installation_status( + language_server_id, + &zed::LanguageServerInstallationStatus::CheckingForUpdate, + ); + let release = zed::latest_github_release( + "mrjosh/helm-ls", + zed::GithubReleaseOptions { + require_assets: true, + pre_release: true, + }, + )?; + + let (platform, arch) = zed::current_platform(); + let asset_name = format!( + "helm_ls_{os}_{arch}{extension}", + os = match platform { + zed::Os::Mac => "darwin", + zed::Os::Linux => "linux", + zed::Os::Windows => "windows", + }, + arch = match arch { + zed::Architecture::Aarch64 => "arm64", + zed::Architecture::X86 => "x86", + zed::Architecture::X8664 => "x86_64", + }, + extension = match platform { + zed::Os::Mac | zed::Os::Linux => "", + zed::Os::Windows => ".exe", + } + ); + + let asset = release + .assets + .iter() + .find(|asset| asset.name == asset_name) + .ok_or_else(|| format!("no asset found matching {:?}", asset_name))?; + + let version_dir = format!("helm_ls_{}", release.version); + fs::create_dir_all(&version_dir) + .map_err(|err| format!("failed to create directory '{version_dir}': {err}"))?; + let binary_path = format!( + "{version_dir}/helm_ls_{os}_{arch}", + os = match platform { + zed::Os::Mac => "darwin", + zed::Os::Linux => "linux", + zed::Os::Windows => "windows", + }, + arch = match arch { + zed::Architecture::Aarch64 => "arm64", + zed::Architecture::X86 => "x86", + zed::Architecture::X8664 => "x86_64", + }, + ); + + if !fs::metadata(&binary_path).map_or(false, |stat| stat.is_file()) { + zed::set_language_server_installation_status( + language_server_id, + &zed::LanguageServerInstallationStatus::Downloading, + ); + + zed::download_file( + &asset.download_url, + &binary_path, + zed::DownloadedFileType::Uncompressed, + ) + .map_err(|e| format!("failed to download file: {e}"))?; + + zed::make_file_executable(&binary_path)?; + + let entries = + fs::read_dir(".").map_err(|e| format!("failed to list working directory {e}"))?; + for entry in entries { + let entry = entry.map_err(|e| format!("failed to load directory entry {e}"))?; + if entry.file_name().to_str() != Some(&version_dir) { + fs::remove_dir_all(entry.path()).ok(); + } + } + } + + self.cached_binary_path = Some(binary_path.clone()); + Ok(binary_path) + } +} impl zed::Extension for HelmExtension { fn new() -> Self { - Self + Self { + cached_binary_path: None, + } } fn language_server_command( &mut self, - _config: zed::LanguageServerConfig, + language_server_id: &LanguageServerId, worktree: &zed::Worktree, ) -> Result { - let path = worktree - .which("helm_ls") - .ok_or_else(|| "Helm is not installed".to_string())?; - Ok(zed::Command { - command: path, + command: self.language_server_binary_path(language_server_id, worktree)?, args: vec!["serve".to_string()], env: Default::default(), }) } } -zed::register_extension!(HelmExtension); \ No newline at end of file +zed::register_extension!(HelmExtension); From 3df4fa2e9c96c29dad4c4125d5c5508d68d0ca22 Mon Sep 17 00:00:00 2001 From: Alexey Olshanskiy Date: Thu, 10 Oct 2024 13:44:05 +0300 Subject: [PATCH 2/2] Fix path suffixes --- languages/helm/config.toml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/languages/helm/config.toml b/languages/helm/config.toml index 348e6e6..adc73c0 100644 --- a/languages/helm/config.toml +++ b/languages/helm/config.toml @@ -1,11 +1,6 @@ name = "Helm" grammar = "helm" -path_suffixes = [ - "gotmpl", - "helmfile.yaml", - "**/templates/**/*.tpl", - "**/templates/**/*.yaml", -] +path_suffixes = ["gotmpl", "helmfile.yaml", "tpl"] line_comments = ["# "] block_comment = ["{{/* ", " */}}"] brackets = [