use anyhow::Result;
use colored::Colorize;
use crate::{config::Config, shell, toolchain, user_version::VersionSpec};
pub fn run(config: &Config, spec_str: &str) -> Result<()> {
let spec = VersionSpec::parse(spec_str)?;
let version = toolchain::resolve_installed(config, &spec)?;
toolchain::set_active_version(config, &version)?;
println!(
"{} Now using Go {} (global).",
"✓".green(),
version.tag().bold()
);
println!(
" Active in all shells (CMD, Git Bash, PowerShell) and editors via {}.",
"~/.gvsn/current".cyan()
);
let hint = match shell::detect() {
Some(sh) if sh.name() == "powershell" => {
format!(
"gvsn env --shell powershell | Out-String | {}",
"Invoke-Expression".cyan()
)
}
Some(sh) => format!("eval \"$(gvsn env --shell {})\"", sh.name().cyan()),
None => "eval \"$(gvsn env)\"".to_string(),
};
println!(" (current session without wrapper: {hint})");
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
fn install_version(config: &Config, tag: &str) {
std::fs::create_dir_all(config.version_dir(tag)).unwrap();
}
#[test]
fn run_sets_global_version_and_current_link() {
let dir = tempdir().unwrap();
let config = Config {
root: dir.path().to_path_buf(),
};
install_version(&config, "go1.22.4");
run(&config, "1.22.4").unwrap();
assert_eq!(
std::fs::read_to_string(config.version_file()).unwrap(),
"go1.22.4"
);
assert!(config.current_dir().exists());
}
#[test]
fn run_errors_when_version_not_installed() {
let dir = tempdir().unwrap();
let config = Config {
root: dir.path().to_path_buf(),
};
assert!(run(&config, "1.22.4").is_err());
}
#[test]
fn run_errors_on_invalid_spec() {
let dir = tempdir().unwrap();
let config = Config {
root: dir.path().to_path_buf(),
};
assert!(run(&config, "garbage").is_err());
}
}