Popularity
3.2
Growing
Activity
7.8
-
137
2
2

Description

Update informer for CLI applications written in Rust 🦀 It checks for a new version on Crates.io and GitHub 🚀

Programming language: Rust
License: MIT License
Latest version: v0.4.0

Update-informer alternatives and similar packages

Based on the "Build system" category.
Alternatively, view update-informer alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of Update-informer or a related project?

Add another 'Build system' Package

README

Update-informer CI Crates.io docs.rs codecov

Update informer for CLI applications written in Rust 🦀

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

Benefits

  • Support of Crates.io, GitHub and PyPI.
  • Configurable check frequency and request timeout.
  • Minimum dependencies - only directories, 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.

Update-informer is created & supported by Evrone.

Usage

Add update-informer to Cargo.toml:

[dependencies]
update-informer = "0.4.0"

By default, update-informer can only check on Crates.io. To enable support for other registries, use features:

[dependencies]
update-informer = { version = "0.4.0", default_features = false, features = ["github"] }

Available features:

Name Default?
cargo Yes
github No
pypi No

Crates.io

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

use update_informer::{registry::Crates, Check, UpdateInformer};

let informer = UpdateInformer::new(Crates, "crate_name", "0.1.0");
if let Ok(Some(version)) = informer.check_version() {
    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::{registry::Crates, Check, UpdateInformer};

let name = env!("CARGO_PKG_NAME");
let version = env!("CARGO_PKG_VERSION");
UpdateInformer::new(Crates, name, version).check_version();

Interval

Note that the first check will start only after the interval has expired. By default, the interval is 24 hours, but you can change it:

use std::time::Duration;
use update_informer::{registry::Crates, Check, UpdateInformer};

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

let informer = UpdateInformer::new(Crates, "crate_name", "0.1.0").interval(EVERY_HOUR);
informer.check_version(); // The check will start only after an hour

Cache file

By default, update-informer creates a file in the cache directory to avoid spam requests to the registry API.

In order not to cache requests, use a zero interval:

use std::time::Duration;
use update_informer::{registry::Crates, Check, UpdateInformer};

let informer = UpdateInformer::new(Crates, "crate_name", "0.1.0").interval(Duration::ZERO);
informer.check_version();

Request timeout

You can also change the request timeout. By default, it is 5 seconds:

 use std::time::Duration;
 use update_informer::{registry::Crates, Check, UpdateInformer};

 const THIRTY_SECONDS: Duration = Duration::from_secs(30);

 let informer = UpdateInformer::new(Crates, "crate_name", "0.1.0").timeout(THIRTY_SECONDS);
 informer.check_version();

GitHub

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

use update_informer::{registry::GitHub, Check, UpdateInformer};

let informer = UpdateInformer::new(GitHub, "owner/repo", "0.1.0");
informer.check_version();

PyPi

To check for a new version on PyPI:

use update_informer::{registry::PyPI, Check, UpdateInformer};

let informer = UpdateInformer::new(PyPI, "package_name", "0.1.0");
informer.check_version();

Example

A real example of using update_informer with colored crate

use colored::*;
use update_informer::{registry::Crates, Check, UpdateInformer};

fn main() {
    let pkg_name = env!("CARGO_PKG_NAME");
    let current_version = env!("CARGO_PKG_VERSION");

    let informer = UpdateInformer::new(Crates, pkg_name, current_version);
    if let Ok(Some(version)) = informer.check_version() {
        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:

Tests

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

Example of usage in unit tests:

use update_informer::{registry::Crates, Check, FakeUpdateInformer, UpdateInformer};

let name = "crate_name";
let version = "0.1.0";

#[cfg(not(test))]
let informer = UpdateInformer::new(Crates, name, version);

#[cfg(test)]
let informer = FakeUpdateInformer::new(Crates, name, version, "1.0.0");

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

Integration tests

To use the FakeUpdateInformer::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 informer = UpdateInformer::new(Crates, name, version);

#[cfg(feature = "stub_check_version")]
let informer = FakeUpdateInformer::new(Crates, name, version, "1.0.0");

informer.check_version();

Sponsors

License

MIT


*Note that all licence references and agreements mentioned in the Update-informer README section above are relevant to that project's source code only.