Skip to content

Commit 7f46eac

Browse files
authored
Update banner to show latest available version (#131)
When stating a Parseable instance it will check for latest release and if the current version is outdated then additional info is printed on banner about latest release along with download link. Changes - Banner will display current version - Banner will display latest version if current version is not latest along with download link
1 parent 63b7ffa commit 7f46eac

File tree

4 files changed

+95
-2
lines changed

4 files changed

+95
-2
lines changed

server/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "parseable"
3-
version = "0.0.1"
3+
version = "0.0.3"
44
authors = [
55
"NitishTiwari <[email protected]>",
66
"AdheipSingh <[email protected]>",
@@ -18,6 +18,7 @@ async-trait = "0.1"
1818
aws-sdk-s3 = "0.17"
1919
bytes = "1"
2020
chrono = "0.4.19"
21+
chrono-humanize = "0.2.2"
2122
crossterm = "0.23.2"
2223
datafusion = "11.0"
2324
object_store = { version = "0.4", features=["aws"] }
@@ -34,6 +35,7 @@ os_info = "3.0.7"
3435
hostname = "0.3"
3536
rand = "0.8.4"
3637
rust-flatten-json = "0.2.0"
38+
semver = "1.0.14"
3739
serde = "^1.0.8"
3840
serde_derive = "^1.0.8"
3941
serde_json = "^1.0.8"
@@ -47,7 +49,7 @@ clokwerk = "0.4.0-rc1"
4749
actix-web-static-files = "4.0"
4850
static-files = "0.2.1"
4951
walkdir = "2"
50-
ureq = "2.5.0"
52+
ureq = { version = "2.5.0", features = ["json"] }
5153

5254
[build-dependencies]
5355
static-files = "0.2.1"

server/src/banner.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,60 @@ pub fn warning_line() {
4343
"Warning:".to_string().red().bold(),
4444
);
4545
}
46+
47+
pub mod version {
48+
use chrono::Duration;
49+
use chrono_humanize::{Accuracy, Tense};
50+
use crossterm::style::Stylize;
51+
use semver::Version;
52+
53+
use crate::utils::github;
54+
55+
pub fn print() {
56+
// print current version
57+
let current_version = current_version();
58+
// not eprintln because if it is old release then time passed with be displayed beside it
59+
eprint!(
60+
"
61+
{} {} ",
62+
"Current Version:".to_string().blue().bold(),
63+
current_version
64+
);
65+
66+
// check for latest release, if it cannot be fetched then print error as warn and return
67+
let latest_release = match github::get_latest() {
68+
Ok(latest_release) => latest_release,
69+
Err(e) => {
70+
log::warn!("{}", e);
71+
return;
72+
}
73+
};
74+
75+
if latest_release.version > current_version {
76+
let time_since_latest_release = chrono::Utc::now() - latest_release.date;
77+
let time_since_latest_release = humanize_time(time_since_latest_release);
78+
79+
let fmt_latest_version = format!(
80+
"( v{} released {} ago )",
81+
latest_release.version, time_since_latest_release
82+
);
83+
84+
eprint!("{}", fmt_latest_version.yellow().bold());
85+
eprintln!(
86+
"
87+
Download latest version from https://github.com/parseablehq/parseable/releases/latest"
88+
);
89+
} else {
90+
eprintln!();
91+
}
92+
}
93+
94+
fn current_version() -> Version {
95+
let current_version = env!("CARGO_PKG_VERSION");
96+
semver::Version::parse(current_version).expect("CARGO_PKG_VERSION is always valid semver")
97+
}
98+
99+
fn humanize_time(time_passed: Duration) -> String {
100+
chrono_humanize::HumanTime::from(time_passed).to_text_en(Accuracy::Rough, Tense::Present)
101+
}
102+
}

server/src/option.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ impl Config {
6161
pub fn print(&self) {
6262
let scheme = CONFIG.parseable.get_scheme();
6363
self.status_info(&scheme);
64+
banner::version::print();
6465
self.warning();
6566
self.storage_info();
6667
banner::system_info();

server/src/utils.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,39 @@ pub fn hostname_unchecked() -> String {
129129
hostname::get().unwrap().into_string().unwrap()
130130
}
131131

132+
pub mod github {
133+
use anyhow::anyhow;
134+
use chrono::{DateTime, Utc};
135+
136+
pub struct LatestRelease {
137+
pub version: semver::Version,
138+
pub date: DateTime<Utc>,
139+
}
140+
141+
pub fn get_latest() -> Result<LatestRelease, anyhow::Error> {
142+
let json: serde_json::Value =
143+
ureq::get("https://api.github.com/repos/parseablehq/parseable/releases/latest")
144+
.call()?
145+
.into_json()?;
146+
147+
let version = json["tag_name"]
148+
.as_str()
149+
.and_then(|ver| ver.strip_prefix('v'))
150+
.and_then(|ver| semver::Version::parse(ver).ok())
151+
.ok_or_else(|| anyhow!("Bad parse when parsing verison"))?;
152+
153+
let date = json["published_at"]
154+
.as_str()
155+
.ok_or_else(|| anyhow!("Bad parse when parsing published date"))?;
156+
157+
let date = chrono::DateTime::parse_from_rfc3339(date)
158+
.expect("date-time from github is in rfc3339 format")
159+
.into();
160+
161+
Ok(LatestRelease { version, date })
162+
}
163+
}
164+
132165
/// Convert minutes to a slot range
133166
/// e.g. given minute = 15 and OBJECT_STORE_DATA_GRANULARITY = 10 returns "10-19"
134167
pub fn minute_to_slot(minute: u32, data_granularity: u32) -> Option<String> {

0 commit comments

Comments
 (0)