add an update checker (#222)

This commit is contained in:
Carson McManus 2023-06-25 09:24:53 -04:00 committed by GitHub
parent f1855ba7c0
commit d87caa06f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 150 additions and 22 deletions

59
Cargo.lock generated
View file

@ -416,13 +416,22 @@ dependencies = [
"generic-array",
]
[[package]]
name = "directories"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
dependencies = [
"dirs-sys 0.4.1",
]
[[package]]
name = "dirs"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309"
dependencies = [
"dirs-sys",
"dirs-sys 0.3.7",
]
[[package]]
@ -436,6 +445,18 @@ dependencies = [
"winapi",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.48.0",
]
[[package]]
name = "discard"
version = "1.0.4"
@ -966,7 +987,7 @@ dependencies = [
"libc",
"log",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys",
"windows-sys 0.36.1",
]
[[package]]
@ -1069,6 +1090,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "os_str_bytes"
version = "6.1.0"
@ -1095,7 +1122,7 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
"windows-sys",
"windows-sys 0.36.1",
]
[[package]]
@ -1837,9 +1864,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.81"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
dependencies = [
"itoa 1.0.2",
"ryu",
@ -2112,6 +2139,7 @@ dependencies = [
"tempdir",
"text_io",
"thiserror",
"update-informer",
"uuid",
"zeroize",
]
@ -2495,6 +2523,18 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "update-informer"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d952f24d9cd8b7564d22c7b2cde3429c48b50c6f4e72b07b382ae4ee5f21b3"
dependencies = [
"directories",
"semver 1.0.9",
"serde",
"serde_json",
]
[[package]]
name = "url"
version = "2.2.2"
@ -2721,6 +2761,15 @@ dependencies = [
"windows_x86_64_msvc 0.36.1",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.0"

View file

@ -1,8 +1,6 @@
[workspace]
members = [
"steamguard"
]
members = ["steamguard"]
[package]
name = "steamguard-cli"
@ -16,8 +14,9 @@ repository = "https://github.com/dyc3/steamguard-cli"
license = "GPL-3.0-or-later"
[features]
default = ["qr"]
default = ["qr", "updater"]
qr = ["qrcode"]
updater = ["update-informer"]
# [[bin]]
# name = "steamguard-cli"
@ -61,6 +60,7 @@ gethostname = "0.4.3"
secrecy = { version = "0.8", features = ["serde"] }
zeroize = "^1.4.3"
serde_path_to_error = "0.1.11"
update-informer = { version = "1.0.0", optional = true, default-features = false, features = ["github"] }
[dev-dependencies]
tempdir = "0.3"

View file

@ -104,6 +104,14 @@ pub(crate) struct GlobalArgs {
pub passkey: Option<String>,
#[clap(short, long, arg_enum, default_value_t=Verbosity::Info, help = "Set the log level. Be warned, trace is capable of printing sensitive data.")]
pub verbosity: Verbosity,
#[cfg(feature = "updater")]
#[clap(
long,
help = "Disable checking for updates.",
long_help = "Disable checking for updates. By default, steamguard-cli will check for updates every now and then. This can be disabled with this flag."
)]
pub no_update_check: bool,
}
#[derive(Debug, Clone, Parser)]

View file

@ -33,30 +33,55 @@ mod encryption;
mod errors;
mod secret_string;
pub(crate) mod tui;
#[cfg(feature = "updater")]
mod updater;
fn main() {
std::process::exit(match run() {
let args = commands::Args::parse();
stderrlog::new()
.verbosity(args.global.verbosity as usize)
.module(module_path!())
.module("steamguard")
.init()
.unwrap();
debug!("{:?}", args);
#[cfg(feature = "updater")]
let should_do_update_check = !args.global.no_update_check;
let exit_code = match run(args) {
Ok(_) => 0,
Err(e) => {
error!("{:?}", e);
255
}
});
};
#[cfg(feature = "updater")]
if should_do_update_check {
match updater::check_for_update() {
Ok(Some(version)) => {
eprintln!();
info!(
"steamguard-cli v{} is available. Download it here: https://github.com/dyc3/steamguard-cli/releases",
version
);
}
Ok(None) => {
debug!("No update available");
}
Err(e) => {
warn!("Failed to check for updates: {}", e);
}
}
}
std::process::exit(exit_code);
}
fn run() -> anyhow::Result<()> {
let args = commands::Args::parse();
info!("{:?}", args);
fn run(args: commands::Args) -> anyhow::Result<()> {
let globalargs = args.global;
stderrlog::new()
.verbosity(globalargs.verbosity as usize)
.module(module_path!())
.module("steamguard")
.init()
.unwrap();
let cmd: CommandType = match args.sub.unwrap_or(Subcommands::Code(args.code)) {
Subcommands::Debug(args) => CommandType::Const(Box::new(args)),
Subcommands::Completion(args) => CommandType::Const(Box::new(args)),

46
src/updater.rs Normal file
View file

@ -0,0 +1,46 @@
use std::time::Duration;
use serde::de::DeserializeOwned;
use update_informer::{
http_client::{HeaderMap, HttpClient},
registry, Check, Version,
};
use crate::debug;
pub fn check_for_update() -> update_informer::Result<Option<Version>> {
let name = "dyc3/steamguard-cli";
let version = env!("CARGO_PKG_VERSION");
debug!("Checking for updates to {} v{}", name, version);
let informer = update_informer::new(registry::GitHub, name, version)
.http_client(ReqwestHttpClient)
.interval(Duration::from_secs(60 * 60 * 24 * 2));
informer.check_version()
}
struct ReqwestHttpClient;
impl HttpClient for ReqwestHttpClient {
fn get<T: DeserializeOwned>(
url: &str,
timeout: Duration,
headers: HeaderMap,
) -> update_informer::Result<T> {
let mut req = reqwest::blocking::Client::builder()
.timeout(timeout)
.build()?
.get(url)
.header(reqwest::header::USER_AGENT, "steamguard-cli");
for (key, value) in headers {
req = req.header(key, value);
}
let resp = req.send()?;
debug!("Update check response status: {:?}", resp.status());
let json = resp.json()?;
Ok(json)
}
}