Skip to content

Commit

Permalink
feat: add stub_check_version function and update docs (#13)
Browse files Browse the repository at this point in the history
Signed-off-by: Mikhail Grachev <[email protected]>
  • Loading branch information
mgrachev authored Dec 30, 2021
1 parent e828f63 commit 4f07b5c
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 29 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
### 🚀 Added

### ⚙️ Changed

### 🛠 Fixed

## [v0.1.0] - 2021-12-30
### 🚀 Added
- Add `stub_check_version` function and update docs [#13](https://github.com/mgrachev/update-informer/pull/13) ([@mgrachev](https://github.com/mgrachev))
- Add documentation and update examples [#12](https://github.com/mgrachev/update-informer/pull/12) ([@mgrachev](https://github.com/mgrachev))
- Save latest version to file and add interval check [#11](https://github.com/mgrachev/update-informer/pull/11) ([@mgrachev](https://github.com/mgrachev))
- Set up CI/CD [#10](https://github.com/mgrachev/update-informer/pull/10) ([@mgrachev](https://github.com/mgrachev))
Expand All @@ -16,3 +24,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### ⚙️ Changed

### 🛠 Fixed

[v0.1.0]: https://github.com/mgrachev/update-informer/releases/tag/v0.1.0
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ license = "MIT"
readme = "README.md"

[dependencies]
semver = "1.0.4"
semver = "1.0"

serde = { version = "1.0.130", features = ["derive"] }
serde_json = "1.0.72"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

ureq = { version = "2.3.1", features = ["json"] }
ureq = { version = "2.4", features = ["json"] }

[dev-dependencies]
mockito = "0.30.0"
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 Grachev Mikhail
Copyright (c) 2021 Mikhail Grachev

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
86 changes: 77 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,8 @@ This function takes the project name and current version as well as check interv
```rust
use update_informer::{check_version, registry::Crates};

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

Expand All @@ -55,15 +50,88 @@ 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**:
To check for a new version on **GitHub** (note that the project name must contain the owner):

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

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

Note that the project name must contain the owner.
## Example

A real example of using `update_informer` with [colored](https://github.com/mackwic/colored) crate:

```rust
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](https://raw.githubusercontent.com/mgrachev/update-informer/main/images/example.png)

## 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:

```rust
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`:

```toml
[features]
stub_check_version = []
```

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

```rust
#[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

Expand Down
Binary file added images/example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 93 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,14 @@
//!
//! ## Usage
//!
//! 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:
//! 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:
//!
//! ```rust
//! use std::error::Error;
//! use std::time::Duration;
//! use update_informer::{check_version, registry::Crates};
//!
//! fn main() -> Result<(), Box<dyn Error>> {
//! match check_version(Crates, "repo", "0.1.0", Duration::from_secs(60 * 60 * 24))? {
//! Some(version) => {
//! println!("New version is available: {}", version);
//! }
//! None => {
//! println!("No new version");
//! }
//! }
//!
//! Ok(())
//! if let Ok(Some(version)) = check_version(Crates, "repo", "0.1.0", Duration::from_secs(60 * 60 * 24)) {
//! println!("New version is available: {}", version);
//! }
//! ```
//!
Expand All @@ -49,7 +39,7 @@
//! 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**:
//! To check for a new version on **GitHub** (note that the project name must contain the owner):
//!
//! ```rust
//! use std::time::Duration;
Expand All @@ -58,7 +48,46 @@
//! check_version(GitHub, "owner/repo", "0.1.0", Duration::from_secs(60 * 60 * 24));
//! ```
//!
//! Note that the project name must contain the owner.
//! ## 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:
//!
//! ```rust
//! 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`:
//!
//! ```toml
//! [features]
//! stub_check_version = []
//! ```
//!
//! Then use this feature flag in your code and integration tests:
//!
//! ```rust
//! use std::time::Duration;
//! use update_informer::registry::Crates;
//!
//! #[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");
//! ```
use crate::package::Package;
use crate::registry::Registry;
Expand Down Expand Up @@ -151,6 +180,45 @@ where
Ok(None)
}

/// Returns the desired version as a new version.
/// Used only for tests.
///
/// # Arguments
/// * `registry` - A registry service such as Crates.io or GitHub (not used).
/// * `name` - A project name (not used).
/// * `version` - Current version of the project (not used).
/// * `interval` - An interval how often to check for a new version (not used).
/// * `new_version` - A desired version.
///
/// # Examples
/// ```rust
/// use std::time::Duration;
/// use update_informer::{registry::Crates, stub_check_version};
///
/// let result = stub_check_version(Crates, "repo", "0.1.0", Duration::from_secs(60 * 60 * 24), "1.0.0");
/// assert!(result.is_ok());
///
/// let version = result.unwrap();
/// assert!(version.is_some());
/// assert_eq!(version.unwrap().to_string(), "v1.0.0");
/// ```
pub fn stub_check_version<R, N, V>(
_registry: R,
_name: N,
_version: V,
_interval: Duration,
new_version: V,
) -> Result<Option<Version>, Error>
where
R: Registry,
N: AsRef<str>,
V: AsRef<str>,
{
let version = Version::parse(new_version)?;

Ok(Some(version))
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -288,4 +356,14 @@ mod tests {
assert!(result.is_ok());
});
}

#[test]
fn stub_check_version_test() {
let version = "1.0.0";
let result = stub_check_version(Crates, PKG_NAME, CURRENT_VERSION, ONE_DAY, version);
let version = Version::parse(version).expect("parse version");

assert!(result.is_ok());
assert_eq!(result.unwrap(), Some(version));
}
}

0 comments on commit 4f07b5c

Please sign in to comment.