snarkvm_debug/cli/helpers/
updater.rs

1// Copyright (C) 2019-2023 Aleo Systems Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7// http://www.apache.org/licenses/LICENSE-2.0
8
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::cli::errors::UpdaterError;
16
17use anyhow::Result;
18use colored::Colorize;
19use self_update::{backends::github, version::bump_is_greater, Status};
20
21pub struct Updater;
22
23// TODO Add logic for users to easily select release versions.
24impl Updater {
25    const SNARKVM_BIN_NAME: &'static str = "snarkvm";
26    const SNARKVM_REPO_NAME: &'static str = "snarkvm";
27    const SNARKVM_REPO_OWNER: &'static str = "AleoHQ";
28
29    /// Show all available releases for `snarkvm`.
30    #[allow(clippy::format_push_string)]
31    pub fn show_available_releases() -> Result<String> {
32        let releases = github::ReleaseList::configure()
33            .repo_owner(Self::SNARKVM_REPO_OWNER)
34            .repo_name(Self::SNARKVM_REPO_NAME)
35            .build()?
36            .fetch()?;
37
38        let mut output = "List of available versions\n".to_string();
39        for release in releases {
40            output += &format!("  * {}\n", release.version);
41        }
42        Ok(output)
43    }
44
45    /// Update `snarkvm` to the latest release.
46    pub fn update_to_latest_release(show_output: bool) -> Result<Status> {
47        let status = github::Update::configure()
48            .repo_owner(Self::SNARKVM_REPO_OWNER)
49            .repo_name(Self::SNARKVM_REPO_NAME)
50            .bin_name(Self::SNARKVM_BIN_NAME)
51            .current_version(env!("CARGO_PKG_VERSION"))
52            .show_download_progress(show_output)
53            .no_confirm(true)
54            .show_output(show_output)
55            .build()?
56            .update()?;
57
58        Ok(status)
59    }
60
61    /// Check if there is an available update for `snarkvm` and return the newest release.
62    pub fn update_available() -> Result<String, UpdaterError> {
63        let updater = github::Update::configure()
64            .repo_owner(Self::SNARKVM_REPO_OWNER)
65            .repo_name(Self::SNARKVM_REPO_NAME)
66            .bin_name(Self::SNARKVM_BIN_NAME)
67            .current_version(env!("CARGO_PKG_VERSION"))
68            .build()?;
69
70        let current_version = updater.current_version();
71        let latest_release = updater.get_latest_release()?;
72
73        if bump_is_greater(&current_version, &latest_release.version)? {
74            Ok(latest_release.version)
75        } else {
76            Err(UpdaterError::OldReleaseVersion(current_version, latest_release.version))
77        }
78    }
79
80    /// Display the CLI message.
81    pub fn print_cli() -> String {
82        if let Ok(latest_version) = Self::update_available() {
83            let mut output = "🟢 A new version is available! Run".bold().green().to_string();
84            output += &" `aleo update` ".bold().white();
85            output += &format!("to update to v{latest_version}.").bold().green();
86            output
87        } else {
88            "".to_string()
89        }
90    }
91}