1use std::process::Command;
2
3use anyhow::{Context, Result, bail};
4use axoupdater::AxoUpdater;
5
6use crate::prompt::confirm;
7
8const REPO_URL: &str = "https://github.com/lararosekelley/git-stk";
10
11pub fn upgrade(head: bool, force: bool, yes: bool) -> Result<()> {
12 if head {
13 upgrade_to_head(yes)
14 } else {
15 upgrade_to_latest_release(force)
16 }
17}
18
19fn upgrade_to_head(yes: bool) -> Result<()> {
20 println!("--head builds and installs the latest unreleased commit from {REPO_URL}");
21 println!("HEAD is a pre-release snapshot: it may be broken or untested");
22
23 if !yes && !confirm("continue? [y/N] ")? {
24 println!("upgrade cancelled");
25 return Ok(());
26 }
27
28 let status = Command::new("cargo")
29 .args(["install", "--git", REPO_URL, "--locked", "git-stk"])
30 .status()
31 .context("failed to run cargo; --head requires a Rust toolchain")?;
32
33 if !status.success() {
34 bail!("cargo install exited with status {status}");
35 }
36
37 println!("installed git-stk from HEAD");
38 println!("to return to the latest release, run: git stk upgrade --force");
39 refresh_assets_with_new_binary();
40 Ok(())
41}
42
43fn refresh_assets_with_new_binary() {
48 let refreshed = Command::new("git-stk")
49 .args(["setup", "--refresh"])
50 .status()
51 .map(|status| status.success())
52 .unwrap_or(false);
53
54 if !refreshed {
55 eprintln!("warning: failed to refresh generated assets; run `git stk setup` manually");
56 }
57}
58
59fn upgrade_to_latest_release(force: bool) -> Result<()> {
60 let mut updater = AxoUpdater::new_for("git-stk");
61 updater
62 .load_receipt()
63 .map_err(anyhow::Error::from)
64 .context(
65 "no usable install receipt found; if git-stk was installed with cargo, \
66 upgrade with `cargo install git-stk --locked` instead",
67 )?;
68 updater.always_update(force);
69
70 match updater
71 .run_sync()
72 .context("failed to upgrade to the latest release")?
73 {
74 Some(result) => {
75 let old = result
76 .old_version
77 .map(|version| version.to_string())
78 .unwrap_or_else(|| "unknown".to_owned());
79 println!("upgraded git-stk {old} -> {}", result.new_version);
80 refresh_assets_with_new_binary();
81 }
82 None => println!(
83 "git-stk {} is already the latest release",
84 env!("CARGO_PKG_VERSION")
85 ),
86 }
87
88 Ok(())
89}