1use std::path::Path;
2
3use rootcause::prelude::ResultExt as _;
4use ytil_cmd::silent_cmd;
5
6use crate::Installer;
7
8pub struct Nvim<'a> {
9 pub dev_tools_dir: &'a Path,
10 pub bin_dir: &'a Path,
11}
12
13impl Installer for Nvim<'_> {
14 fn bin_name(&self) -> &'static str {
15 "nvim"
16 }
17
18 fn install(&self) -> rootcause::Result<()> {
19 let nvim_source_dir = self.dev_tools_dir.join(self.bin_name()).join("source");
22 let nvim_release_dir = self.dev_tools_dir.join(self.bin_name()).join("release");
23
24 silent_cmd("sh")
25 .args([
26 "-c",
27 &format!(
28 r#"
29 ([ ! -d "{0}" ] && \
30 git clone https://github.com/neovim/neovim {0} || true) && \
31 cd {0} && \
32 git checkout master && \
33 git pull origin master && \
34 make distclean && \
35 make CMAKE_BUILD_TYPE=Release CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX={1}" && \
36 make install
37 "#,
38 nvim_source_dir.display(),
39 nvim_release_dir.display(),
40 ),
41 ])
42 .status()
43 .context("failed to spawn build command")?
44 .exit_ok()
45 .context("build failed")
46 .attach_with(|| format!("tool={}", self.bin_name()))
47 .attach_with(|| format!("source_dir={}", nvim_source_dir.display()))?;
48
49 let target = nvim_release_dir.join("bin").join(self.bin_name());
50 ytil_sys::file::ln_sf(&target, &self.bin_dir.join(self.bin_name()))?;
51 ytil_sys::file::chmod_x(&target)?;
52
53 Ok(())
54 }
55
56 fn health_check_args(&self) -> Option<&[&str]> {
57 Some(&["-V1", "-v"])
58 }
59}