Merge pull request #280 from AleoHQ/feature/automatic-update

Automatic updating of the binary
This commit is contained in:
Howard Wu 2020-08-21 02:44:22 -07:00 committed by GitHub
commit f7a2a733db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 169 additions and 85 deletions

View File

@ -42,16 +42,19 @@ jobs:
- name: Zip
run: |
mkdir leo_${{ steps.get_version.outputs.version }}_ubuntu
mv target/release/leo leo_${{ steps.get_version.outputs.version }}_ubuntu
zip -r leo_${{ steps.get_version.outputs.version }}_ubuntu.zip leo_${{ steps.get_version.outputs.version }}_ubuntu
mkdir tempdir
mv target/release/leo tempdir
cd tempdir
zip -r leo-${{ steps.get_version.outputs.version }}-x86_64-unknown-linux-gnu.zip leo
cd ..
mv tempdir/leo-${{ steps.get_version.outputs.version }}-x86_64-unknown-linux-gnu.zip .
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
leo_${{ steps.get_version.outputs.version }}_ubuntu.zip
leo-${{ steps.get_version.outputs.version }}-x86_64-unknown-linux-gnu.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -88,16 +91,19 @@ jobs:
- name: Zip
run: |
mkdir leo_${{ steps.get_version.outputs.version }}_mac
mv target/release/leo leo_${{ steps.get_version.outputs.version }}_mac
zip -r leo_${{ steps.get_version.outputs.version }}_mac.zip leo_${{ steps.get_version.outputs.version }}_mac
mkdir tempdir
mv target/release/leo tempdir
cd tempdir
zip -r leo-${{ steps.get_version.outputs.version }}-x86_64-apple-darwin.zip leo
cd ..
mv tempdir/leo-${{ steps.get_version.outputs.version }}-x86_64-apple-darwin.zip .
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
leo_${{ steps.get_version.outputs.version }}_mac.zip
leo-${{ steps.get_version.outputs.version }}-x86_64-apple-darwin.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -135,15 +141,18 @@ jobs:
- name: Zip
run: |
mkdir leo_${{ steps.get_version.outputs.version }}_windows
mv target/release/leo.exe leo_${{ steps.get_version.outputs.version }}_windows
Compress-Archive leo_${{ steps.get_version.outputs.version }}_windows leo_${{ steps.get_version.outputs.version }}_windows.zip
mkdir tempdir
mv target/release/leo tempdir
cd tempdir
Compress-Archive leo-${{ steps.get_version.outputs.version }}-x86_64-pc-windows-gnu leo
cd ..
mv leo-${{ steps.get_version.outputs.version }}-x86_64-pc-windows-gnu .
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
leo_${{ steps.get_version.outputs.version }}_windows.zip
leo-${{ steps.get_version.outputs.version }}-x86_64-pc-windows-gnu.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1
Cargo.lock generated
View File

@ -2202,6 +2202,7 @@ dependencies = [
"semver",
"serde_json",
"tempfile",
"zip",
]
[[package]]

View File

@ -43,7 +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" }
self_update = { version = "0.19.0", features = ["archive-zip"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }
toml = { version = "0.5" }

View File

@ -24,7 +24,7 @@
use crate::{
cli::CLI,
cli_types::*,
credentials::*,
config::*,
errors::{AddError::*, CLIError::AddError},
};
use leo_package::{

View File

@ -24,7 +24,7 @@
use crate::{
cli::CLI,
cli_types::*,
credentials::*,
config::*,
errors::{
CLIError::LoginError,
LoginError::{CannotGetToken, NoConnectionFound, NoCredentialsProvided, WrongLoginOrPassword},

View File

@ -18,7 +18,7 @@ use crate::{
cli::*,
cli_types::*,
commands::{BuildCommand, LoginCommand},
credentials::{read_token, PACKAGE_MANAGER_URL},
config::{read_token, PACKAGE_MANAGER_URL},
errors::{
commands::PublishError::{ConnectionUnavalaible, PackageNotPublished},
CLIError,

View File

@ -16,7 +16,7 @@
use crate::{cli::CLI, cli_types::*};
use self_update::{backends::github, cargo_crate_version};
use self_update::{backends::github, cargo_crate_version, Status};
const LEO_BIN_NAME: &str = "leo";
const LEO_REPO_OWNER: &str = "AleoHQ";
@ -26,8 +26,8 @@ const LEO_REPO_NAME: &str = "leo";
pub struct UpdateCommand;
impl UpdateCommand {
// Show all available releases for all platforms
fn show_available_releases() -> Result<(), self_update::errors::Error> {
/// 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)
@ -41,8 +41,8 @@ impl UpdateCommand {
Ok(())
}
// Update to the latest release on the current platform
fn update_to_latest_release() -> Result<(), self_update::errors::Error> {
/// 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)
@ -52,8 +52,7 @@ impl UpdateCommand {
.build()?
.update()?;
log::info!("Leo has successfully updated to {} version", status.version());
Ok(())
Ok(status)
}
}
@ -83,7 +82,14 @@ impl CLI for UpdateCommand {
}
},
(false,) => match UpdateCommand::update_to_latest_release() {
Ok(_) => return Ok(()),
Ok(status) => {
if status.uptodate() {
log::info!("Leo is already on the latest version: {}", status.version());
} else if status.updated() {
log::info!("Leo has successfully updated to version: {}", status.version());
}
return Ok(());
}
Err(e) => {
log::error!("Could not update Leo to the latest version");
log::error!("{}", e);

111
leo/config.rs Normal file
View File

@ -0,0 +1,111 @@
// 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 <https://www.gnu.org/licenses/>.
use crate::errors::CLIError;
use dirs::home_dir;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use std::{
fs::{self, create_dir_all, File},
io,
io::prelude::*,
path::{Path, PathBuf},
};
pub const PACKAGE_MANAGER_URL: &str = "https://apm-backend-prod.herokuapp.com/";
pub const LEO_CREDENTIALS_FILE: &str = "credentials";
pub const LEO_CONFIG_FILE: &str = "leo.config";
lazy_static! {
pub static ref LEO_CONFIG_DIRECTORY: PathBuf = {
let mut path = home_dir().expect("Invalid home directory");
path.push(".leo");
path
};
pub static ref LEO_CREDENTIALS_PATH: PathBuf = {
let mut path = LEO_CONFIG_DIRECTORY.to_path_buf();
path.push(LEO_CREDENTIALS_FILE);
path
};
pub static ref LEO_CONFIG_PATH: PathBuf = {
let mut path = LEO_CONFIG_DIRECTORY.to_path_buf();
path.push(LEO_CONFIG_FILE);
path
};
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Config {
pub auto_update: bool,
}
impl Default for Config {
fn default() -> Self {
Self { auto_update: true }
}
}
impl Config {
/// Read the config from the leo.config file
pub fn read_config() -> Result<Self, CLIError> {
let config_dir = LEO_CONFIG_DIRECTORY.clone();
let config_path = LEO_CONFIG_PATH.clone();
if !Path::exists(&config_path) {
// Create a new default leo.config file if it doesn't already exist
create_dir_all(&config_dir)?;
let default_config_string = toml::to_string(&Config::default())?;
fs::write(&config_path, default_config_string)?;
}
let toml_string = match fs::read_to_string(&config_path) {
Ok(toml) => toml,
Err(_) => {
create_dir_all(&config_dir)?;
String::new()
}
};
// Parse the contents into the `Config` struct
let config: Config = toml::from_str(&toml_string)?;
Ok(config)
}
}
pub fn write_token(token: &str) -> Result<(), io::Error> {
let config_dir = LEO_CONFIG_DIRECTORY.clone();
// Create Leo config directory if it not exists
if !Path::new(&config_dir.to_path_buf()).exists() {
create_dir_all(&config_dir)?;
}
let mut credentials = File::create(&LEO_CREDENTIALS_PATH.to_path_buf())?;
credentials.write_all(&token.as_bytes())?;
Ok(())
}
pub fn read_token() -> Result<String, io::Error> {
let mut credentials = File::open(&LEO_CREDENTIALS_PATH.to_path_buf())?;
let mut buf = String::new();
credentials.read_to_string(&mut buf)?;
Ok(buf)
}

View File

@ -1,59 +0,0 @@
// 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 <https://www.gnu.org/licenses/>.
use dirs::home_dir;
use lazy_static::lazy_static;
use std::{
fs::{create_dir_all, File},
io,
io::prelude::*,
path::{Path, PathBuf},
};
pub const PACKAGE_MANAGER_URL: &str = "https://apm-backend-prod.herokuapp.com/";
pub const LEO_CREDENTIALS_FILE: &str = "credentials";
lazy_static! {
pub static ref LEO_CREDENTIALS_DIR: PathBuf = {
let mut path = home_dir().expect("Invalid home directory");
path.push(".leo");
path
};
pub static ref LEO_CREDENTIALS_PATH: PathBuf = {
let mut path = LEO_CREDENTIALS_DIR.to_path_buf();
path.push(LEO_CREDENTIALS_FILE);
path
};
}
pub fn write_token(token: &str) -> Result<(), io::Error> {
// Create Leo credentials directory if it not exists
if !Path::new(&LEO_CREDENTIALS_DIR.to_path_buf()).exists() {
create_dir_all(&LEO_CREDENTIALS_DIR.to_path_buf())?;
}
let mut credentials = File::create(&LEO_CREDENTIALS_PATH.to_path_buf())?;
credentials.write_all(&token.as_bytes())?;
Ok(())
}
pub fn read_token() -> Result<String, io::Error> {
let mut credentials = File::open(&LEO_CREDENTIALS_PATH.to_path_buf())?;
let mut buf = String::new();
credentials.read_to_string(&mut buf)?;
Ok(buf)
}

View File

@ -97,6 +97,12 @@ pub enum CLIError {
#[error("{}", _0)]
TestError(TestError),
#[error("TomlSerError: {0}")]
TomlSerError(#[from] toml::ser::Error),
#[error("TomlDeError: {0}")]
TomlDeError(#[from] toml::de::Error),
#[error("{}", _0)]
VerificationKeyFileError(VerificationKeyFileError),
}

View File

@ -21,7 +21,7 @@ pub mod cli;
pub mod cli_types;
pub mod commands;
#[cfg_attr(tarpaulin, skip)]
pub mod credentials;
pub mod config;
pub mod errors;
pub mod logger;
pub mod synthesizer;

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 leo::{cli::*, commands::*, errors::CLIError};
use leo::{cli::*, commands::*, config::Config, errors::CLIError};
use clap::{App, AppSettings, Arg};
@ -56,6 +56,16 @@ fn main() -> Result<(), CLIError> {
.set_term_width(0)
.get_matches();
let config = Config::read_config()?;
if config.auto_update {
if let Ok(status) = UpdateCommand::update_to_latest_release() {
if status.updated() {
log::info!("Leo has successfully updated to version: {}", status.version());
}
}
}
match arguments.subcommand() {
("new", Some(arguments)) => NewCommand::process(arguments),
("init", Some(arguments)) => InitCommand::process(arguments),