Skip to content

Commit

Permalink
Merge pull request #31 from perryrh0dan/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
perryrh0dan authored Sep 1, 2020
2 parents d1425cd + f350ce5 commit 75c4ed8
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 96 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"type": "lldb",
"request": "launch",
"program": "${workspaceRoot}/target/debug/tmpo",
"args": ["init", "-r", "https://github.com/perryrh0dan/templates", "-t", "typescript"],
// "args": ["init", "-r", "https://github.com/perryrh0dan/templates", "-t", "typescript"],
// "args": ["repository", "remove"],
"cwd": "${workspaceRoot}",
}
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tmpo"
version = "1.2.3"
version = "1.3.0"
authors = ["Thomas Pöhlmann <thomaspoehlmann96@googlemail.com>"]
edition = "2018"

Expand Down
101 changes: 9 additions & 92 deletions src/action/default/update.rs
Original file line number Diff line number Diff line change
@@ -1,103 +1,20 @@
use std::fs::File;
use log;

use crate::out;
use crate::cli::input::confirm;
use crate::update;

extern crate tar;
extern crate self_update;
extern crate flate2;
use clap::{crate_version};
use tar::Archive;
use flate2::read::GzDecoder;

pub fn update(interactive: bool) {
let releases = self_update::backends::github::ReleaseList::configure()
.repo_owner("perryrh0dan")
.repo_name("tmpo")
.build().unwrap()
.fetch().unwrap();

// check version
let version = crate_version!();
if releases[0].version == version {
if interactive { out::info::no_app_update() };
return;
}

println!("Checking target-arch: {}", &self_update::get_target());
println!("Checking current version: {}", &version);
println!("New release found! {} --> {}", &version, &releases[0].version);

let asset = match releases[0].asset_for(&self_update::get_target()) {
Some(value) => value,
None => {
println!("New release is not compatible");
return;
}
pub fn update() {
let asset = match update::check_version() {
Some(asset) => asset,
None => return,
};

println!("New release is compatible");
println!();

// user input
if interactive {
let update = confirm("The new release will be downloaded/extraced and the existing binary will be replaced. Do you want to continue?");

if !update {
let update = confirm("The new release will be downloaded/extraced and the existing binary will be replaced.\nDo you want to continue?");
if !update {
return;
}
}

let tmp_dir = tempfile::Builder::new().tempdir_in(::std::env::current_dir().unwrap()).unwrap();
let tmp_tarball_path = tmp_dir.path().join(&asset.name);
std::fs::File::create(&tmp_tarball_path).unwrap();
let tmp_tarball = std::fs::OpenOptions::new().create(true).append(true).open(&tmp_tarball_path).unwrap();

// download asset
let mut headers = reqwest::header::HeaderMap::new();
headers.insert(reqwest::header::ACCEPT, "application/octet-stream".parse().unwrap());
match self_update::Download::from_url(&asset.download_url).show_progress(true).set_headers(headers).download_to(&tmp_tarball) {
Ok(_) => (),
Err(error) => println!("{}", error)
};

// extract tar.gz archive
let tar_gz = File::open(tmp_tarball_path).unwrap();
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);
match archive.unpack(&tmp_dir) {
Ok(_) => (),
Err(error) => println!("{}", error)
};

// move file to current executable
let bin_name = "tmpo";
let tmp_file = tmp_dir.path().join("replacement_tmp");
let bin_path = tmp_dir.path().join(bin_name);
let success = match self_update::Move::from_source(&bin_path)
.replace_using_temp(&tmp_file)
.to_dest(&::std::env::current_exe().unwrap()) {
Ok(_) => ( true ),
Err(error) => match error {
self_update::errors::Error::Io { .. } => {
out::error::selfupdate_no_permission();
false
},
_ => {
log::error!("{}", error);
false
}
}
};

// remove tmp folder
match std::fs::remove_dir_all(tmp_dir) {
Ok(_) => (),
Err(error) => println!("{}", error),
};
println!();

if success {
out::success::app_updated();
}
update::update(asset);
}
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod meta;
mod out;
mod repository;
mod template;
mod update;
mod utils;

use clap::{crate_version, App, AppSettings, Arg};
Expand Down Expand Up @@ -128,7 +129,7 @@ fn main() {
action::default::init::init(&config, init_matches);
}
("update", Some(_update_matches)) => {
action::default::update::update(true);
action::default::update::update();
}
("repository", Some(repository_matches)) => {
match repository_matches.subcommand() {
Expand Down
143 changes: 143 additions & 0 deletions src/update/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
use log;
use std::fs::File;

use crate::out;

extern crate flate2;
extern crate self_update;
extern crate tar;
use clap::crate_version;
use flate2::read::GzDecoder;
use tar::Archive;

#[cfg(windows)]
const BIN_NAME: &str = "tmpo.exe";

#[cfg(not(windows))]
const BIN_NAME: &str = "tmpo";

pub fn check_version() -> Option<self_update::update::ReleaseAsset> {
log::info!("Fetch release list");
let releases = self_update::backends::github::ReleaseList::configure()
.repo_owner("perryrh0dan")
.repo_name("tmpo")
.build()
.unwrap()
.fetch()
.unwrap();

// check version
let version = crate_version!();
if releases[0].version == version {
log::info!("No update");
out::info::no_app_update();
return None;
}

println!("Checking target-arch: {}", &self_update::get_target());
println!("Checking current version: {}", &version);
println!(
"New release found! {} --> {}",
&version, &releases[0].version
);

log::info!(
"New release found! {} --> {}",
&version,
&releases[0].version
);

let asset = match releases[0].asset_for(&self_update::get_target()) {
Some(value) => value,
None => {
println!("New release is not compatible");
return None;
}
};

println!("New release is compatible");
println!();

return Some(asset);
}

pub fn update(asset: self_update::update::ReleaseAsset) {
let tmp_dir = tempfile::Builder::new()
.tempdir_in(::std::env::current_dir().unwrap())
.unwrap();
let tmp_tarball_path = tmp_dir.path().join(&asset.name);
std::fs::File::create(&tmp_tarball_path).unwrap();
let tmp_tarball = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(&tmp_tarball_path)
.unwrap();

// download asset
let mut headers = reqwest::header::HeaderMap::new();
headers.insert(
reqwest::header::ACCEPT,
"application/octet-stream".parse().unwrap(),
);

log::info!(
"Download asset to: {}",
&tmp_tarball_path.to_owned().to_str().unwrap()
);
match self_update::Download::from_url(&asset.download_url)
.show_progress(true)
.set_headers(headers)
.download_to(&tmp_tarball)
{
Ok(_) => (),
Err(error) => {
log::error!("{}", error);
return;
}
};

// extract tar.gz archive
log::info!("Extract tar.gz archive");
let tar_gz = File::open(tmp_tarball_path).unwrap();
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);
match archive.unpack(&tmp_dir) {
Ok(_) => (),
Err(error) => {
log::error!("{}", error);
return;
}
};

// move file to current executable
let tmp_file = tmp_dir.path().join("replacement_tmp");
let bin_path = tmp_dir.path().join(BIN_NAME);
let dest_path = std::env::current_exe().unwrap();

log::info!(
"Move {} to {}",
bin_path.to_owned().to_str().unwrap(),
dest_path.to_owned().to_str().unwrap()
);
match self_update::Move::from_source(&bin_path)
.replace_using_temp(&tmp_file)
.to_dest(&dest_path)
{
Ok(_) => (),
Err(error) => {
log::error!("{}", error);
match error {
self_update::errors::Error::Io { .. } => {
out::error::selfupdate_no_permission();
return;
}
_ => {
out::error::unknown();
return;
}
}
}
};

out::success::app_updated();
}

0 comments on commit 75c4ed8

Please sign in to comment.