envvault/cli/commands/
update.rs1use std::process::Command;
9
10use console::style;
11
12use crate::cli::output;
13use crate::errors::{EnvVaultError, Result};
14
15#[derive(Debug, PartialEq)]
17pub enum InstallMethod {
18 Cargo,
19 Homebrew,
20 Script,
21}
22
23pub fn detect_install_method() -> InstallMethod {
25 let exe = match std::env::current_exe() {
26 Ok(p) => p.to_string_lossy().to_string(),
27 Err(_) => return InstallMethod::Script,
28 };
29
30 if exe.contains(".cargo/bin") {
31 InstallMethod::Cargo
32 } else if exe.contains("Cellar") || exe.contains("homebrew") || exe.contains("linuxbrew") {
33 InstallMethod::Homebrew
34 } else {
35 InstallMethod::Script
36 }
37}
38
39pub fn execute() -> Result<()> {
41 let current = env!("CARGO_PKG_VERSION");
42
43 let latest = crate::version_check::check_latest_version(current);
45 match &latest {
46 Some(ver) => {
47 output::info(&format!(
48 "Update available: {} → {}",
49 style(current).red(),
50 style(ver).green().bold()
51 ));
52 }
53 None => {
54 output::success(&format!("Already on the latest version ({current})."));
55 return Ok(());
56 }
57 }
58
59 let method = detect_install_method();
60
61 match method {
62 InstallMethod::Cargo => run_cargo_update(),
63 InstallMethod::Homebrew => run_brew_update(),
64 InstallMethod::Script => run_script_update(),
65 }
66}
67
68fn run_cargo_update() -> Result<()> {
69 output::info("Detected cargo install. Running: cargo install envvault-cli --force");
70 println!();
71
72 let status = Command::new("cargo")
73 .args(["install", "envvault-cli", "--force"])
74 .status()
75 .map_err(|e| {
76 EnvVaultError::CommandFailed(format!(
77 "failed to run cargo: {e}. Run manually: cargo install envvault-cli --force"
78 ))
79 })?;
80
81 if status.success() {
82 println!();
83 output::success("Update complete!");
84 Ok(())
85 } else {
86 Err(EnvVaultError::CommandFailed(
87 "cargo install failed. Run manually: cargo install envvault-cli --force".into(),
88 ))
89 }
90}
91
92fn run_brew_update() -> Result<()> {
93 output::info("Detected Homebrew install. Running: brew upgrade envvault");
94 println!();
95
96 let status = Command::new("brew")
97 .args(["upgrade", "envvault"])
98 .status()
99 .map_err(|e| {
100 EnvVaultError::CommandFailed(format!(
101 "failed to run brew: {e}. Run manually: brew upgrade envvault"
102 ))
103 })?;
104
105 if status.success() {
106 println!();
107 output::success("Update complete!");
108 Ok(())
109 } else {
110 Err(EnvVaultError::CommandFailed(
111 "brew upgrade failed. Run manually: brew upgrade envvault".into(),
112 ))
113 }
114}
115
116fn run_script_update() -> Result<()> {
117 output::info("Running install script to update...");
118 println!();
119
120 let status = Command::new("sh")
121 .args([
122 "-c",
123 "curl -fsSL https://raw.githubusercontent.com/whynaidu/envvault/main/install.sh | sh",
124 ])
125 .status()
126 .map_err(|e| {
127 EnvVaultError::CommandFailed(format!(
128 "failed to run install script: {e}. Run manually:\n \
129 curl -fsSL https://raw.githubusercontent.com/whynaidu/envvault/main/install.sh | sh"
130 ))
131 })?;
132
133 if status.success() {
134 println!();
135 output::success("Update complete!");
136 Ok(())
137 } else {
138 Err(EnvVaultError::CommandFailed(
139 "install script failed. Run manually:\n \
140 curl -fsSL https://raw.githubusercontent.com/whynaidu/envvault/main/install.sh | sh"
141 .into(),
142 ))
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn detect_method_from_cargo_path() {
152 let method = detect_install_method();
155 assert!(
156 method == InstallMethod::Cargo
157 || method == InstallMethod::Script
158 || method == InstallMethod::Homebrew
159 );
160 }
161}