Skip to content

Commit

Permalink
feat: add check updates command
Browse files Browse the repository at this point in the history
  • Loading branch information
alexng353 committed Dec 2, 2024
1 parent 1142071 commit dbe15b4
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 3 deletions.
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ dirs = "5.0.1"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
reqwest = { version = "0.12.8", default-features = false, features = [
"rustls-tls", "json"
"rustls-tls",
"json",
] }
chrono = { version = "0.4.38", features = ["serde"], default-features = false }
chrono = { version = "0.4.38", features = [
"serde",
"clock",
], default-features = false }
graphql_client = { version = "0.14.0", features = ["reqwest-rustls"] }
paste = "1.0.15"
tokio = { version = "1.40.0", features = ["full"] }
Expand Down
34 changes: 34 additions & 0 deletions src/commands/check_updates.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use crate::check_update;

use super::*;
use serde_json::json;

/// Test the update check
#[derive(Parser)]
pub struct Args {}

pub async fn command(_args: Args, json: bool) -> Result<()> {
let mut configs = Configs::new()?;

if json {
let result = configs.check_update(true).await;

if let Ok(Some(latest_version)) = result {
let json = json!({
"latest_version": latest_version,
"current_version": env!("CARGO_PKG_VERSION"),
});
println!("{}", serde_json::to_string_pretty(&json)?);
} else {
let json = json!({
"latest_version": None::<String>,
"current_version": env!("CARGO_PKG_VERSION"),
});
println!("{}", serde_json::to_string_pretty(&json)?);
}
return Ok(());
}

check_update!(configs, true);
Ok(())
}
2 changes: 2 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ pub mod up;
pub mod variables;
pub mod volume;
pub mod whoami;

pub mod check_updates;
52 changes: 52 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ use std::{
};

use anyhow::{Context, Result};
use chrono::{DateTime, Utc};
use colored::Colorize;
use inquire::ui::{Attributes, RenderConfig, StyleSheet, Styled};
use is_terminal::IsTerminal;
use serde::{Deserialize, Serialize};

use crate::{
Expand Down Expand Up @@ -42,6 +44,7 @@ pub struct RailwayUser {
pub struct RailwayConfig {
pub projects: BTreeMap<String, LinkedProject>,
pub user: RailwayUser,
pub last_update_check: Option<DateTime<Utc>>,
}

#[derive(Debug)]
Expand All @@ -57,6 +60,13 @@ pub enum Environment {
Dev,
}

#[derive(Deserialize)]
struct GithubApiRelease {
tag_name: String,
}

const GITHUB_API_RELEASE_URL: &str = "https://api.github.com/repos/railwayapp/cli/releases/latest";

impl Configs {
pub fn new() -> Result<Self> {
let environment = Self::get_environment_id();
Expand All @@ -79,6 +89,7 @@ impl Configs {
RailwayConfig {
projects: BTreeMap::new(),
user: RailwayUser { token: None },
last_update_check: None,
}
});

Expand All @@ -95,6 +106,7 @@ impl Configs {
root_config: RailwayConfig {
projects: BTreeMap::new(),
user: RailwayUser { token: None },
last_update_check: None,
},
})
}
Expand All @@ -103,6 +115,7 @@ impl Configs {
self.root_config = RailwayConfig {
projects: BTreeMap::new(),
user: RailwayUser { token: None },
last_update_check: None,
};
Ok(())
}
Expand Down Expand Up @@ -313,4 +326,43 @@ impl Configs {

Ok(())
}

pub async fn check_update(&mut self, force: bool) -> anyhow::Result<Option<String>> {
// outputting would break json output on CI
if !std::io::stdout().is_terminal() && !force {
return Ok(None);
}

let should_update = if let Some(last_update_check) = self.root_config.last_update_check {
Utc::now().date_naive() != last_update_check.date_naive() || force
} else {
true
};

if !should_update {
return Ok(None);
}

let client = reqwest::Client::new();
let response = client
.get(GITHUB_API_RELEASE_URL)
.header("User-Agent", "railwayapp")
.send()
.await?;

self.root_config.last_update_check = Some(Utc::now());
self.write()
.context("Failed to write config in should_update")?;

let response = response.json::<GithubApiRelease>().await?;
let latest_version = response.tag_name.trim_start_matches('v');

let current_version = env!("CARGO_PKG_VERSION");

if latest_version == current_version {
return Ok(None);
}

Ok(Some(latest_version.to_owned()))
}
}
16 changes: 16 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,19 @@ macro_rules! interact_or {
}
};
}

#[macro_export]
macro_rules! check_update {
($obj:expr, $force:expr) => {{
let result = $obj.check_update($force).await;

if let Ok(Some(latest_version)) = result {
println!(
"{} v{} visit {} for more info",
"New version available:".green().bold(),
latest_version.yellow(),
"https://docs.railway.com/guides/cli".purple(),
);
}
}};
}
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ commands_enum!(
variables,
whoami,
volume,
redeploy
redeploy,
check_updates
);

#[tokio::main]
Expand Down

0 comments on commit dbe15b4

Please sign in to comment.