Skip to content

Update informer for CLI applications written in Rust 🦀

License

Notifications You must be signed in to change notification settings

mgrachev/update-informer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Update-informer CI

Update informer for CLI applications written in Rust 🦀

It checks for a new version on Crates.io and GitHub 🚀

Benefits

  • Support of Crates.io and GitHub.
  • Configurable frequency of checks.
  • Minimum dependencies - only ureq, semver and serde.

The idea is actually not new, as GitHub has been doing for a long time in its CLI application.
There is also a popular JavaScript library.

Usage

Add update-informer to Cargo.toml:

[dependencies]
update-informer = "0.1.0"

To check for a new version on Crates.io, use the check_version function.
This function takes the project name and current version as well as check interval:

use update_informer::{check_version, registry::Crates};

if let Ok(Some(version)) = check_version(Crates, "repo", "0.1.0", Duration::from_secs(60 * 60 * 24)) {
    println!("New version is available: {}", version);
}

Also, you can take the name and version of the project from Cargo using environment variables:

use update_informer::{check_version, registry::Crates};

check_version(Crates, env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"), Duration::from_secs(60 * 60 * 24));

Note that the first check will start only after the interval has expired:

use update_informer::{check_version, registry::Crates};

const EVERY_HOUR: Duration = Duration::from_secs(60 * 60);

check_version(Crates, "repo", "0.1.0", EVERY_HOUR); // The check will start only after an hour

To check for a new version on GitHub (note that the project name must contain the owner):

use update_informer::{check_version, registry::GitHub};

check_version(GitHub, "owner/repo", "0.1.0", Duration::from_secs(60 * 60 * 24));

Example

A real example of using update_informer with colored crate:

use colored::*;
use std::time::Duration;
use update_informer::{check_version, registry::Crates};

fn main() {
    let pkg_name = env!("CARGO_PKG_NAME");
    let current_version = env!("CARGO_PKG_VERSION");
    let interval = Duration::from_secs(60 * 60 * 24);

    if let Ok(Some(version)) = check_version(Crates, pkg_name, current_version, interval) {
        let msg = format!(
            "A new release of {pkg_name} is available: v{current_version} -> {new_version}",
            pkg_name = pkg_name.italic().cyan(),
            current_version = current_version,
            new_version = version.to_string().green()
        );

        let release_url = format!(
            "https://github.com/{pkg_name}/{pkg_name}/releases/tag/{version}",
            pkg_name = pkg_name,
            version = version
        )
            .yellow();

        println!("\n{msg}\n{url}", msg = msg, url = release_url);
    }
}

The result will look like: example

Tests

In order not to check for updates in tests, you can use the stub_check_version function, which returns the desired version.

Example of usage in unit tests:

use std::time::Duration;
use update_informer::registry::Crates;

#[cfg(not(test))]
let result = update_informer::check_version(Crates, "repo", "0.1.0", Duration::from_secs(60 * 60 * 24));

#[cfg(test)]
let result = update_informer::stub_check_version(Crates, "repo", "0.1.0", Duration::from_secs(60 * 60 * 24), "1.0.0");

if let Ok(Some(version)) = result {
    println!("New version is available: {}", version);
}

To use the stub_check_version function in integration tests, you must first add the feature flag to Cargo.toml:

[features]
stub_check_version = []

Then use this feature flag in your code and integration tests:

#[cfg(not(feature = "stub_check_version"))]
let result = update_informer::check_version(Crates, "repo", "0.1.0", Duration::from_secs(60 * 60 * 24));

#[cfg(feature = "stub_check_version")]
let result = update_informer::stub_check_version(Crates, "repo", "0.1.0", Duration::from_secs(60 * 60 * 24), "1.0.0");

Sponsors

Sponsored by Evrone

License

MIT