Update-informer

CI Version Docs.rs Codecov Downloads

update-informer

Update informer for CLI applications written in Rust 🦀

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

Benefits

Idea

The idea is actually not new. This feature has long been present in the [GitHub CLI application] and [npm].
There is also a popular [JavaScript library].

Usage

Add update-informer to Cargo.toml:

toml [dependencies] update-informer = "1.0"

By default, update-informer can only check on Crates.io and uses [ureq] as a default HTTP client. To enable support for other registries or change the HTTP client, use features:

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

Available features:

| Name | Type | Default? | | --------- | ----------- | -------- | | crates | Registry | Yes | | github | Registry | No | | npm | Registry | No | | pypi | Registry | No | | [ureq] | HTTP client | Yes | | [reqwest] | HTTP client | No |

Checking for a new version

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

```rust use update_informer::{registry, Check};

let name = env!("CARGOPKGNAME"); let version = env!("CARGOPKGVERSION"); let informer = update_informer::new(registry::Crates, name, version);

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

More examples you can find [here].

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:

```rust use std::time::Duration; use update_informer::{registry, Check};

const EVERYHOUR: Duration = Duration::fromsecs(60 * 60);

let informer = updateinformer::new(registry::Crates, "cratename", "0.1.0").interval(EVERYHOUR); informer.checkversion(); // The check will start only after an hour ```

Caching

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:

```rust use std::time::Duration; use update_informer::{registry, Check};

let informer = updateinformer::new(registry::Crates, "cratename", "0.1.0").interval(Duration::ZERO); informer.check_version(); ```

Request timeout

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

```rust use std::time::Duration; use update_informer::{registry, Check};

const THIRTYSECONDS: Duration = Duration::fromsecs(30);

let informer = updateinformer::new(registry::Crates, "cratename", "0.1.0").timeout(THIRTYSECONDS); informer.checkversion(); ```

Implementing your own registry

You can implement your own registry to check updates. For example:

```rust use updateinformer::{httpclient::{GenericHttpClient, HttpClient}, registry, Check, Package, Registry, Result};

[derive(serde::Deserialize)]

struct Response { version: String, }

struct YourOwnRegistry; impl Registry for YourOwnRegistry { const NAME: &'static str = "yourownregistry";

fn get_latest_version<T: HttpClient>(http_client: GenericHttpClient<T>, pkg: &Package) -> Result<Option<String>> {
    let url = "https://turbo.build/api/binaries/version";
    let resp = http_client.get::<Response>(&url)?;

    Ok(Some(resp.version))
}

}

let informer = updateinformer::new(YourOwnRegistry, "turbo", "0.1.0"); informer.checkversion(); ```

Using your own HTTP client

You can use your own HTTP client to check updates. For example, [isahc]:

```rust use isahc::ReadResponseExt; use std::time::Duration; use serde::de::DeserializeOwned; use updateinformer::{httpclient::{HeaderMap, HttpClient}, registry, Check};

struct YourOwnHttpClient;

impl HttpClient for YourOwnHttpClient { fn get( url: &str, timeout: Duration, _headers: HeaderMap, ) -> updateinformer::Result { let json = isahc::get(url)?.json()?; Ok(json) } }

let informer = updateinformer::new(registry::Crates, "cratename", "0.1.0").httpclient(YourOwnHttpClient); informer.checkversion(); ```

Tests

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

```rust use update_informer::{registry, Check};

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

[cfg(not(test))]

let informer = update_informer::new(registry::Crates, name, version);

[cfg(test)]

let informer = update_informer::fake(registry::Crates, name, version, "1.0.0");

if let Some(version) = informer.check_version().ok().flatten() { 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:

toml [features] stub_check_version = []

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

```rust use update_informer::{registry, Check};

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

[cfg(not(feature = "stubcheckversion"))]

let informer = update_informer::new(registry::Crates, name, version);

[cfg(feature = "stubcheckversion")]

let informer = update_informer::fake(registry::Crates, name, version, "1.0.0");

informer.check_version(); ```

Users

MSRV

Minimum Supported Rust Version: 1.56.1

Sponsors

[update-informer] is created & supported by [Evrone]

License

[MIT]