idt/installers/
terraform_ls.rs1use std::path::Path;
2
3use rootcause::prelude::ResultExt as _;
4use ytil_sys::Arch;
5use ytil_sys::Os;
6use ytil_sys::SysInfo;
7
8use crate::downloaders::http::deflate::ChecksumSource;
9use crate::downloaders::http::deflate::HttpDeflateOption;
10use crate::installers::Installer;
11use crate::installers::SystemDependent;
12
13pub struct TerraformLs<'a> {
14 pub bin_dir: &'a Path,
15 pub sys_info: &'a SysInfo,
16}
17
18impl SystemDependent for TerraformLs<'_> {
19 fn target_arch_and_os(&self) -> (&str, &str) {
20 let SysInfo { os, arch } = self.sys_info;
21 let os = match os {
22 Os::MacOs => "darwin",
23 Os::Linux => "linux",
24 };
25 let arch = match arch {
26 Arch::Arm => "arm64",
27 Arch::X86 => "amd64",
28 };
29 (arch, os)
30 }
31}
32
33impl Installer for TerraformLs<'_> {
34 fn bin_name(&self) -> &'static str {
35 "terraform-ls"
36 }
37
38 fn install(&self) -> rootcause::Result<()> {
39 let (arch, os) = self.target_arch_and_os();
40
41 let repo = format!("hashicorp/{}", self.bin_name());
42 let latest_release_tag = crate::downloaders::http::github::get_latest_release_tag(&repo)?;
43 let latest_release = latest_release_tag
44 .get(1..)
45 .ok_or_else(|| rootcause::report!("error trimming 'v' prefix from release tag"))
46 .attach_with(|| format!("tag={latest_release_tag:?}"))?;
47
48 let filename = format!("{0}_{latest_release}_{os}_{arch}.zip", self.bin_name());
49 let checksums_url = format!(
50 "https://releases.hashicorp.com/{0}/{latest_release}/{0}_{latest_release}_SHA256SUMS",
51 self.bin_name()
52 );
53
54 let target = crate::downloaders::http::run(
55 &format!(
56 "https://releases.hashicorp.com/{0}/{latest_release}/{filename}",
57 self.bin_name()
58 ),
59 &HttpDeflateOption::ExtractZip {
60 dest_dir: self.bin_dir,
61 dest_name: Some(self.bin_name()),
62 },
63 Some(&ChecksumSource {
64 checksums_url: &checksums_url,
65 filename: &filename,
66 }),
67 )?;
68
69 ytil_sys::file::chmod_x(target)?;
70
71 Ok(())
72 }
73}