Skip to main content

idt/installers/
terraform_ls.rs

1use 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}