diff --git a/Cargo.toml b/Cargo.toml index b6b70d9fcb..ef4acdf515 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,8 @@ snarkos-utilities = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", package = clap = { version = "2.33.3" } colored = { version = "2.0" } dirs = { version = "3.0.1" } +console = { version = "0.12.0" } +dotenv = { version = "0.15.0" } env_logger = { version = "0.7" } from-pest = { version = "0.3.1" } lazy_static = { version = "1.4.0" } @@ -41,6 +43,7 @@ num-bigint = { version = "0.3" } rand = { version = "0.7" } rand_core = { version = "0.5.1" } reqwest = { version = "0.10.7", features = ["blocking", "json"] } +self_update = { version = "0.19.0" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0" } toml = { version = "0.5" } diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs index b5c14e8b99..16b9e266dd 100644 --- a/leo/commands/mod.rs +++ b/leo/commands/mod.rs @@ -56,5 +56,8 @@ pub use self::test::*; pub mod remove; pub use self::remove::*; +pub mod update; +pub use self::update::*; + pub mod watch; pub use self::watch::*; diff --git a/leo/commands/update.rs b/leo/commands/update.rs new file mode 100644 index 0000000000..5597011f0c --- /dev/null +++ b/leo/commands/update.rs @@ -0,0 +1,95 @@ +// Copyright (C) 2019-2020 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::{cli::CLI, cli_types::*}; + +use self_update::{backends::github, cargo_crate_version}; + +const LEO_BIN_NAME: &str = "leo"; +const LEO_REPO_OWNER: &str = "AleoHQ"; +const LEO_REPO_NAME: &str = "leo"; + +#[derive(Debug)] +pub struct UpdateCommand; + +impl UpdateCommand { + // Show all available releases for all platforms + fn show_available_releases() -> Result<(), self_update::errors::Error> { + let releases = github::ReleaseList::configure() + .repo_owner(LEO_REPO_OWNER) + .repo_name(LEO_REPO_NAME) + .build()? + .fetch()?; + + log::info!("List of available Leo's verions"); + for release in releases { + log::info!("* {}", release.version); + } + Ok(()) + } + + // Update to the latest release on the current platform + fn update_to_latest_release() -> Result<(), self_update::errors::Error> { + let status = github::Update::configure() + .repo_owner(LEO_REPO_OWNER) + .repo_name(LEO_REPO_NAME) + .bin_name(LEO_BIN_NAME) + .show_download_progress(true) + .current_version(cargo_crate_version!()) + .build()? + .update()?; + + log::info!("Leo has successfully updated to {} version", status.version()); + Ok(()) + } +} + +impl CLI for UpdateCommand { + type Options = (bool,); + type Output = (); + + const ABOUT: AboutType = "Update Leo itself"; + const ARGUMENTS: &'static [ArgumentType] = &[]; + const FLAGS: &'static [FlagType] = &[("--list")]; + const NAME: NameType = "update"; + const OPTIONS: &'static [OptionType] = &[]; + const SUBCOMMANDS: &'static [SubCommandType] = &[]; + + fn parse(arguments: &clap::ArgMatches) -> Result { + let show_all_versions = arguments.is_present("list"); + Ok((show_all_versions,)) + } + + fn output(options: Self::Options) -> Result { + match options { + (true,) => match UpdateCommand::show_available_releases() { + Ok(_) => return Ok(()), + Err(e) => { + log::error!("Cannot get Leo version"); + log::error!("Log: {}", e); + } + }, + (false,) => match UpdateCommand::update_to_latest_release() { + Ok(_) => return Ok(()), + Err(e) => { + log::error!("Cannot update Leo"); + log::error!("Log: {}", e); + } + }, + } + Ok(()) + } +} diff --git a/leo/main.rs b/leo/main.rs index 27a08d90da..5d2fdae163 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -51,6 +51,7 @@ fn main() -> Result<(), CLIError> { DeployCommand::new().display_order(12), CleanCommand::new().display_order(13), LintCommand::new().display_order(14), + UpdateCommand::new().display_order(15), ]) .set_term_width(0) .get_matches(); @@ -71,6 +72,7 @@ fn main() -> Result<(), CLIError> { ("deploy", Some(arguments)) => DeployCommand::process(arguments), ("clean", Some(arguments)) => CleanCommand::process(arguments), ("lint", Some(arguments)) => LintCommand::process(arguments), + ("update", Some(arguments)) => UpdateCommand::process(arguments), _ => unreachable!(), } }