Merge pull request #305 from AleoHQ/feature/auto-update-confirmation

Update auto update displays and confirmation prompts
This commit is contained in:
Howard Wu 2020-09-02 20:30:42 -07:00 committed by GitHub
commit f02b6d89fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 57 deletions

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{cli_types::*, errors::CLIError, logger};
use crate::{cli_types::*, errors::CLIError, logger, updater::Updater};
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
@ -90,6 +90,10 @@ pub trait CLI {
false => logger::init_logger("leo", 1),
}
if arguments.subcommand().0 != "update" {
Updater::print_cli();
}
let options = Self::parse(arguments)?;
let _output = Self::output(options)?;
Ok(())

View File

@ -14,48 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{cli::CLI, cli_types::*};
use self_update::{backends::github, cargo_crate_version, Status};
const LEO_BIN_NAME: &str = "leo";
const LEO_REPO_OWNER: &str = "AleoHQ";
const LEO_REPO_NAME: &str = "leo";
use crate::{cli::CLI, cli_types::*, updater::Updater};
#[derive(Debug)]
pub struct UpdateCommand;
impl UpdateCommand {
/// Show all available releases for `leo`
pub 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()?;
tracing::info!("List of available Leo's versions");
for release in releases {
tracing::info!("* {}", release.version);
}
Ok(())
}
/// Update `leo` to the latest release
pub fn update_to_latest_release() -> Result<Status, 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()?;
Ok(status)
}
}
impl CLI for UpdateCommand {
type Options = (bool,);
type Output = ();
@ -78,14 +41,14 @@ impl CLI for UpdateCommand {
let _enter = span.enter();
match options {
(true,) => match UpdateCommand::show_available_releases() {
(true,) => match Updater::show_available_releases() {
Ok(_) => return Ok(()),
Err(e) => {
tracing::error!("Could not fetch that latest version of Leo");
tracing::error!("{}", e);
}
},
(false,) => match UpdateCommand::update_to_latest_release() {
(false,) => match Updater::update_to_latest_release(true) {
Ok(status) => {
if status.uptodate() {
tracing::info!("Leo is already on the latest version: {}", status.version());

View File

@ -56,7 +56,7 @@ pub struct Config {
impl Default for Config {
fn default() -> Self {
Self { auto_update: true }
Self { auto_update: false }
}
}

View File

@ -152,6 +152,13 @@ impl_cli_error!(
ZipFileError
);
impl From<clap::Error> for CLIError {
fn from(error: clap::Error) -> Self {
tracing::error!("{}\n", error);
CLIError::Crate("clap", format!("{}", error))
}
}
impl From<leo_compiler::errors::CompilerError> for CLIError {
fn from(error: leo_compiler::errors::CompilerError) -> Self {
tracing::error!("{}\n", error);

View File

@ -25,3 +25,4 @@ pub mod config;
pub mod errors;
pub mod logger;
pub mod synthesizer;
pub mod updater;

View File

@ -14,13 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use leo_lang::{cli::*, commands::*, config::Config, errors::CLIError};
use leo_lang::{cli::*, commands::*, errors::CLIError, logger, updater::Updater};
use clap::{App, AppSettings, Arg};
#[cfg_attr(tarpaulin, skip)]
fn main() -> Result<(), CLIError> {
let arguments = App::new("leo")
let app = App::new("leo")
.version(include_str!("./leo-version"))
.about("Leo compiler and package manager")
.author("The Aleo Team <hello@aleo.org>")
@ -28,7 +28,6 @@ fn main() -> Result<(), CLIError> {
AppSettings::ColoredHelp,
AppSettings::DisableHelpSubcommand,
AppSettings::DisableVersion,
AppSettings::SubcommandRequiredElseHelp,
])
.args(&[Arg::with_name("debug")
.short("d")
@ -53,18 +52,10 @@ fn main() -> Result<(), CLIError> {
LintCommand::new().display_order(14),
UpdateCommand::new().display_order(15),
])
.set_term_width(0)
.get_matches();
.set_term_width(0);
let config = Config::read_config()?;
if config.auto_update {
if let Ok(status) = UpdateCommand::update_to_latest_release() {
if status.updated() {
tracing::info!("Leo has successfully updated to version: {}", status.version());
}
}
}
let mut help = app.clone();
let arguments = app.get_matches();
match arguments.subcommand() {
("new", Some(arguments)) => NewCommand::process(arguments),
@ -83,6 +74,17 @@ fn main() -> Result<(), CLIError> {
("clean", Some(arguments)) => CleanCommand::process(arguments),
("lint", Some(arguments)) => LintCommand::process(arguments),
("update", Some(arguments)) => UpdateCommand::process(arguments),
_ => unreachable!(),
_ => {
// Set logging environment
match arguments.is_present("debug") {
true => logger::init_logger("leo", 2),
false => logger::init_logger("leo", 1),
}
Updater::print_cli();
help.print_help()?;
Ok(())
}
}
}

86
leo/updater.rs Normal file
View File

@ -0,0 +1,86 @@
use crate::config::Config;
use colored::Colorize;
use self_update::{backends::github, version::bump_is_greater, Status};
pub struct Updater;
// TODO Add logic for users to easily select release versions.
impl Updater {
const LEO_BIN_NAME: &'static str = "leo";
const LEO_REPO_NAME: &'static str = "leo";
const LEO_REPO_OWNER: &'static str = "AleoHQ";
/// Show all available releases for `leo`.
pub fn show_available_releases() -> Result<(), self_update::errors::Error> {
let releases = github::ReleaseList::configure()
.repo_owner(Self::LEO_REPO_OWNER)
.repo_name(Self::LEO_REPO_NAME)
.build()?
.fetch()?;
tracing::info!("List of available Leo's versions");
for release in releases {
tracing::info!("* {}", release.version);
}
Ok(())
}
/// Update `leo` to the latest release.
pub fn update_to_latest_release(show_output: bool) -> Result<Status, self_update::errors::Error> {
let status = github::Update::configure()
.repo_owner(Self::LEO_REPO_OWNER)
.repo_name(Self::LEO_REPO_NAME)
.bin_name(Self::LEO_BIN_NAME)
.current_version(&include_str!("./leo-version").replace('v', ""))
.show_download_progress(true)
.no_confirm(true)
.show_output(show_output)
.build()?
.update()?;
Ok(status)
}
/// Check if there is an available update for `leo` and return the newest release.
pub fn update_available() -> Result<Option<String>, self_update::errors::Error> {
let updater = github::Update::configure()
.repo_owner(Self::LEO_REPO_OWNER)
.repo_name(Self::LEO_REPO_NAME)
.bin_name(Self::LEO_BIN_NAME)
.current_version(&include_str!("./leo-version").replace('v', ""))
.build()?;
let current_version = updater.current_version();
let latest_release = updater.get_latest_release()?;
if bump_is_greater(&current_version, &latest_release.version)? {
Ok(Some(latest_release.version))
} else {
Ok(None)
}
}
/// Display the CLI message, if the Leo configuration allows.
pub fn print_cli() {
let config = Config::read_config().unwrap();
if config.auto_update {
// If the auto update configuration is on, attempt to update the version.
if let Ok(status) = Self::update_to_latest_release(false) {
if status.updated() {
tracing::info!("Successfully updated to {}", status.version());
}
}
} else {
// If the auto update configuration is off, notify the user to update leo.
if let Some(latest_version) = Self::update_available().unwrap() {
let mut message = format!("{}", "🟢 A new version is available! Run".bold().green());
message += &format!("{}", " `leo update` ".bold().white());
message += &format!("{}", &(format!("to update to v{}.", latest_version)).bold().green());
tracing::info!("\n{}\n", message);
}
}
}
}