Skip to content

Commit

Permalink
extend update-informer
Browse files Browse the repository at this point in the history
  • Loading branch information
tknickman committed Dec 1, 2022
1 parent cf3630e commit fd53200
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 327 deletions.
134 changes: 123 additions & 11 deletions 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
Expand Up @@ -31,7 +31,7 @@ members = [
"crates/turbopack-swc-utils",
"crates/turbopack",
"crates/turbopack-tests",
"crates/update-notifier",
"crates/turbo-updater",
"shim",
"xtask",
]
Expand Down
16 changes: 16 additions & 0 deletions crates/turbo-updater/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "turbo-updater"
version = "0.1.0"
edition = "2021"
description = "Minimal wrapper around update-informer to provide NPM registry support and consistent UI"
license = "MPL-2.0"
publish = false

[dependencies]
colored = "2.0"
serde = { version = "1.0.126", features = ["derive"] }
strip-ansi-escapes = "0.1.1"
terminal_size = "0.2"
thiserror = "1.0"
update-informer = "0.5.0"
ureq = { version = "2.3.0", features = ["json"] }
74 changes: 74 additions & 0 deletions crates/turbo-updater/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use std::time::Duration;

use colored::*;
use serde::Deserialize;
use thiserror::Error as ThisError;
use update_informer::{Check, Package, Registry, Result as UpdateResult};
use ureq;

mod ui;

const DEFAULT_TIMEOUT: Duration = Duration::from_millis(800);
const DEFAULT_INTERVAL: Duration = Duration::from_secs(60 * 60 * 24);

#[derive(ThisError, Debug)]
pub enum UpdateNotifierError {
#[error("Failed to write to terminal")]
RenderError(#[from] ui::utils::GetDisplayLengthError),
}

#[derive(Deserialize)]
struct NpmVersionData {
version: String,
}

struct NPMRegistry;

impl Registry for NPMRegistry {
const NAME: &'static str = "npm_registry";
fn get_latest_version(pkg: &Package, _timeout: Duration) -> UpdateResult<Option<String>> {
let url = format!("https://registry.npmjs.org/{}/latest", pkg);
let resp = ureq::get(&url).timeout(_timeout).call()?;
let result = resp.into_json::<NpmVersionData>().unwrap();
Ok(Some(result.version))
}
}

pub fn check_for_updates(
package_name: &str,
github_repo: &str,
footer: Option<&str>,
current_version: &str,
timeout: Option<Duration>,
interval: Option<Duration>,
) -> Result<(), UpdateNotifierError> {
let timeout = timeout.unwrap_or(DEFAULT_TIMEOUT);
let interval = interval.unwrap_or(DEFAULT_INTERVAL);
let informer = update_informer::new(NPMRegistry, package_name, current_version)
.timeout(timeout)
.interval(interval);
if let Some(version) = informer.check_version().ok().flatten() {
let latest_version = version.to_string();
let msg = format!(
"
Update available {version_prefix}{current_version} ≫ {latest_version}
Changelog: {github_repo}/releases/tag/{latest_version}
Run \"{update_cmd}\" to update
",
version_prefix = "v".dimmed(),
current_version = current_version.dimmed(),
latest_version = latest_version.green().bold(),
github_repo = github_repo,
// TODO: make this package manager aware
update_cmd = "npm i -g turbo".cyan().bold(),
);

if let Some(footer) = footer {
return ui::message(&format!("{}\n{}", msg, footer));
}

return ui::message(&msg);
}

Ok(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,10 @@ pub fn message(text: &str) -> Result<(), UpdateNotifierError> {
let lines: Vec<&str> = text.split('\n').map(|line| line.trim()).collect();

// get the display width of each line so we can center it within the box later
let lines_display_width: Result<Vec<usize>, utils::GetDisplayLengthError> = lines
let lines_display_width = lines
.iter()
.map(|line| utils::get_display_length(line))
.collect();

let lines_display_width = match lines_display_width {
Ok(lines_display_width) => lines_display_width,
Err(e) => return Err(UpdateNotifierError::DisplayLengthError(e)),
};
.collect::<Result<Vec<_>, _>>()?;

// find the longest line to determine layout
let longest_line = lines_display_width
Expand All @@ -45,7 +40,7 @@ pub fn message(text: &str) -> Result<(), UpdateNotifierError> {
let term_width = if term_width > 2 {
usize::from(term_width) - 2
} else {
usize::from(term_width)
term_width.into()
};

let can_fit_box = term_width >= full_message_width;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ pub fn render_message(
// Left aligned text with no border.
// Used when term width is unknown.
Layout::Unknown => {
log::debug!("rendering unknown layout");
for line in lines.iter() {
println!("{}", line);
}
Expand All @@ -85,7 +84,6 @@ pub fn render_message(
// Left aligned text with top and bottom border.
// Used when text cannot be centered without wrapping
Layout::Small => {
log::debug!("rendering small layout");
x_border(width, BorderAlignment::Divider);
for (line, line_display_width) in lines.iter().zip(lines_display_width.iter()) {
if *line_display_width == 0 {
Expand All @@ -101,7 +99,6 @@ pub fn render_message(
// Used when text can be centered without wrapping, but
// there isn't enough room to include the box with padding.
Layout::Medium => {
log::debug!("rendering medium layout");
x_border(width, BorderAlignment::Divider);
for (line, line_display_width) in lines.iter().zip(lines_display_width.iter()) {
if *line_display_width == 0 {
Expand All @@ -123,7 +120,6 @@ pub fn render_message(

// Centered text with border on all sides
Layout::Large => {
log::debug!("rendering large layout");
x_border(full_message_width, BorderAlignment::Top);
for (line, line_display_width) in lines.iter().zip(lines_display_width.iter()) {
if *line_display_width == 0 {
Expand Down
20 changes: 0 additions & 20 deletions crates/update-notifier/Cargo.toml

This file was deleted.

0 comments on commit fd53200

Please sign in to comment.