Skip to content

Commit

Permalink
release 0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
foxzool committed Nov 30, 2024
1 parent c7cb109 commit 28cb90b
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 71 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Changelog

## [unreleased]
## [0.5.0]

* bump `bevy_ecs` version to `0.15.0`
* upgrade `cron` to `0.13.0`
* support english pattern for cronjob by [english-to-cron](https://github.com/kaplanelad/english-to-cron)
* system run time is now in Local time

## [0.5.0-rc.1] - 2024-10-23

Expand Down
11 changes: 11 additions & 0 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 @@ -17,7 +17,7 @@ bevy_ecs = { version = "0.15.0" }

cron = "0.13.0"
chrono = "0.4.19"

english-to-cron = "0.1.2"

[dev-dependencies]
bevy = { version = "0.15.0", default-features = false, features = [] }
Expand Down
26 changes: 22 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# bevy_cronjob

`bevy_cronjob` is a simple helper to run cronjobs (at repeated schedule) in Bevy.
`bevy_cronjob` is a simple helper to run cronjob (at repeated schedule) in Bevy.

## Usage

Expand All @@ -26,9 +26,12 @@ fn main() {
))),
)
.add_plugins(LogPlugin::default())
.add_systems(Update, print_per_5_sec.run_if(schedule_passed("0/5 * * * * *")))
.add_systems(Update, print_per_min.run_if(schedule_passed("0 * * * * *")))
.add_systems(Update, print_per_hour.run_if(schedule_passed("0 0 * * * *")))
.add_systems(
Update,
print_per_5_sec.run_if(schedule_passed("every 5 seconds")),
)
.add_systems(Update, print_per_min.run_if(schedule_passed("every 1 minute")))
.add_systems(Update, print_per_hour.run_if(schedule_passed("every hour")))
.run();
}
Expand Down Expand Up @@ -61,6 +64,21 @@ every 15 seconds.
Ranges can be specified with a dash. For example `1-5 * * * * *`' would execute on every second for the first 5 seconds
of a minute.

## Full List of Supported English Patterns

supported by [english-to-cron](https://github.com/kaplanelad/english-to-cron)

| English Phrase | CronJob Syntax |
|--------------------------------------------------|------------------|
| every 15 seconds | 0/15 * * * * ? * |
| run every minute | 0 * * * * ? * |
| fire every day at 4:00 pm | 0 0 16 */1 * ? * |
| at 10:00 am | 0 0 10 * * ? * |
| run at midnight on the 1st and 15th of the month | 0 0 0 1,15 * ? * |
| On Sunday at 12:00 | 0 0 12 ? * SUN * |
| 7pm every Thursday | 0 0 19 ? * THU * |
| midnight on Tuesdays | 0 0 ? * TUE * |

## Supported Versions

| bevy | bevy_cronjob |
Expand Down
8 changes: 4 additions & 4 deletions examples/cronjobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use bevy::{
};
use bevy_ecs::prelude::IntoSystemConfigs;

use bevy_cronjob::{schedule_passed, EVERY_HOUR, EVERY_MIN};
use bevy_cronjob::{schedule_passed};

fn main() {
App::new()
Expand All @@ -19,10 +19,10 @@ fn main() {
.add_plugins(LogPlugin::default())
.add_systems(
Update,
print_per_5_sec.run_if(schedule_passed("0/5 * * * * *")),
print_per_5_sec.run_if(schedule_passed("every 5 seconds")),
)
.add_systems(Update, print_per_min.run_if(schedule_passed(EVERY_MIN)))
.add_systems(Update, print_per_hour.run_if(schedule_passed(EVERY_HOUR)))
.add_systems(Update, print_per_min.run_if(schedule_passed("every 1 minute")))
.add_systems(Update, print_per_hour.run_if(schedule_passed("every hour")))
.run();
}

Expand Down
176 changes: 115 additions & 61 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::str::FromStr;
use bevy_ecs::prelude::Local;
use chrono::DateTime;
use cron::Schedule;
pub use english_to_cron::str_cron_syntax;

/// bevy_cronjob is a simple helper to run cronjobs (at repeated schedule) in Bevy.
/// # Usage
Expand All @@ -24,9 +25,9 @@ use cron::Schedule;
/// ))),
/// )
/// .add_plugins(LogPlugin::default())
/// .add_systems(Update, print_per_5_sec.run_if(schedule_passed("0/5 * * * * *")))
/// .add_systems(Update, print_per_min.run_if(schedule_passed("0 * * * * *")))
/// .add_systems(Update, print_per_hour.run_if(schedule_passed("0 0 * * * *")))
/// .add_systems(Update, print_per_5_sec.run_if(schedule_passed("0/5 * * * ? *")))
/// .add_systems(Update, print_per_min.run_if(schedule_passed("0 * * * ? *")))
/// .add_systems(Update, print_per_hour.run_if(schedule_passed("0 0 * * ? *")))
/// .run();
/// }
///
Expand Down Expand Up @@ -60,95 +61,95 @@ use cron::Schedule;
/// for the first 5 seconds of a minute.
/// run every 5 sec
pub const EVERY_5_SEC: &str = "0/5 * * * * * *";
pub const EVERY_5_SEC: &str = "0/5 * * * * ? *";
/// run every 10 sec
pub const EVERY_10_SEC: &str = "0/10 * * * * * *";
pub const EVERY_10_SEC: &str = "0/10 * * * * ? *";
/// run every 30 sec
pub const EVERY_30_SEC: &str = "0/30 * * * * * *";
pub const EVERY_30_SEC: &str = "0/30 * * * * ? *";
/// run every minute
pub const EVERY_MIN: &str = "0 * * * * * *";
pub const EVERY_MIN: &str = "0 * * * * ? *";
/// run every 5 minutes
pub const EVERY_5_MIN: &str = "0 */5 * * * * *";
pub const EVERY_5_MIN: &str = "0 0/5 * * * ? *";
/// run every 10 minutes
pub const EVERY_10_MIN: &str = "0 */10 * * * * *";
pub const EVERY_10_MIN: &str = "0 0/10 * * * ? *";
/// run every 30 minutes
pub const EVERY_30_MIN: &str = "0 */30 * * * * *";
pub const EVERY_30_MIN: &str = "0 0/30 * * * ? *";
/// run every hour
pub const EVERY_HOUR: &str = "0 0 * * * * *";
pub const EVERY_HOUR: &str = "0 0 * * * ? *";
/// run every day
pub const EVERY_DAY: &str = "0 0 0 * * * *";
pub const EVERY_DAY: &str = "0 0 0 */1 * ? *";

/// run every day at 1 am UTC
pub const EVERY_1_AM: &str = "0 0 1 * * * *";
/// run every day at 1 am
pub const EVERY_1_AM: &str = "0 0 1 */1 * ? *";

/// run every day at 2 am UTC
pub const EVERY_2_AM: &str = "0 0 2 * * * *";
/// run every day at 2 am
pub const EVERY_2_AM: &str = "0 0 2 */1 * ? *";

/// run every day at 3 am UTC
pub const EVERY_3_AM: &str = "0 0 3 * * * *";
/// run every day at 3 am
pub const EVERY_3_AM: &str = "0 0 3 */1 * ? *";

/// run every day at 4 am UTC
pub const EVERY_4_AM: &str = "0 0 4 * * * *";
/// run every day at 4 am
pub const EVERY_4_AM: &str = "0 0 4 */1 * ? *";

/// run every day at 5 am UTC
pub const EVERY_5_AM: &str = "0 0 5 * * * *";
/// run every day at 5 am
pub const EVERY_5_AM: &str = "0 0 5 */1 * ? *";

/// run every day at 6 am UTC
pub const EVERY_6_AM: &str = "0 0 6 * * * *";
/// run every day at 6 am
pub const EVERY_6_AM: &str = "0 0 6 */1 * ? *";

/// run every day at 7 am UTC
pub const EVERY_7_AM: &str = "0 0 7 * * * *";
/// run every day at 7 am
pub const EVERY_7_AM: &str = "0 0 7 */1 * ? *";

/// run every day at 8 am UTC
pub const EVERY_8_AM: &str = "0 0 8 * * * *";
/// run every day at 8 am
pub const EVERY_8_AM: &str = "0 0 8 */1 * ? *";

/// run every day at 9 am UTC
pub const EVERY_9_AM: &str = "0 0 9 * * * *";
/// run every day at 9 am
pub const EVERY_9_AM: &str = "0 0 9 */1 * ? *";

/// run every day at 10 am UTC
pub const EVERY_10_AM: &str = "0 0 10 * * * *";
/// run every day at 10 am
pub const EVERY_10_AM: &str = "0 0 10 */1 * ? *";

/// run every day at 11 am UTC
pub const EVERY_11_AM: &str = "0 0 11 * * * *";
/// run every day at 11 am
pub const EVERY_11_AM: &str = "0 0 11 */1 * ? *";

/// run every day at 12 pm UTC
pub const EVERY_12_PM: &str = "0 0 12 * * * *";
/// run every day at 12 pm
pub const EVERY_12_PM: &str = "0 0 12 */1 * ? *";

/// run every day at 1 pm UTC
pub const EVERY_1_PM: &str = "0 0 13 * * * *";
/// run every day at 1 pm
pub const EVERY_1_PM: &str = "0 0 13 */1 * ? *";

/// run every day at 2 pm UTC
pub const EVERY_2_PM: &str = "0 0 14 * * * *";
/// run every day at 2 pm
pub const EVERY_2_PM: &str = "0 0 14 */1 * ? *";

/// run every day at 3 pm UTC
pub const EVERY_3_PM: &str = "0 0 15 * * * *";
/// run every day at 3 pm
pub const EVERY_3_PM: &str = "0 0 15 */1 * ? *";

/// run every day at 4 pm UTC
pub const EVERY_4_PM: &str = "0 0 16 * * * *";
/// run every day at 4 pm
pub const EVERY_4_PM: &str = "0 0 16 */1 * ? *";

/// run every day at 5 pm UTC
pub const EVERY_5_PM: &str = "0 0 17 * * * *";
/// run every day at 5 pm
pub const EVERY_5_PM: &str = "0 0 17 */1 * ? *";

/// run every day at 6 pm UTC
pub const EVERY_6_PM: &str = "0 0 18 * * * *";
/// run every day at 6 pm
pub const EVERY_6_PM: &str = "0 0 18 */1 * ? *";

/// run every day at 7 pm UTC
pub const EVERY_7_PM: &str = "0 0 19 * * * *";
/// run every day at 7 pm
pub const EVERY_7_PM: &str = "0 0 19 */1 * ? *";

/// run every day at 8 pm UTC
pub const EVERY_8_PM: &str = "0 0 20 * * * *";
/// run every day at 8 pm
pub const EVERY_8_PM: &str = "0 0 20 */1 * ? *";

/// run every day at 9 pm UTC
pub const EVERY_9_PM: &str = "0 0 21 * * * *";
/// run every day at 9 pm
pub const EVERY_9_PM: &str = "0 0 21 */1 * ? *";

/// run every day at 10 pm UTC
pub const EVERY_10_PM: &str = "0 0 22 * * * *";
/// run every day at 10 pm
pub const EVERY_10_PM: &str = "0 0 22 */1 * ? *";

/// run every day at 11 pm UTC
pub const EVERY_11_PM: &str = "0 0 23 * * * *";
/// run every day at 11 pm
pub const EVERY_11_PM: &str = "0 0 23 */1 * ? *";

/// run every day at 12 am UTC
pub const EVERY_12_AM: &str = "0 0 0 * * * *";
/// run every day at 12 am
pub const EVERY_12_AM: &str = "0 0 0 */1 * ? *";

/// Creates a closure that checks if the cron expression has passed
/// # expression format:
Expand All @@ -165,10 +166,26 @@ pub const EVERY_12_AM: &str = "0 0 0 * * * *";
/// |0 * * * * * | every minute |
/// |0 5,10 * * * * | every hour on 5 and 10 min|
/// |0 0 1 * * * | every day on 1:00:00|
///
/// # english expression:
/// | expression | equal crontab expression|
/// |------|------|
/// |every 5 seconds | 0/5 * * * * *|
/// |every minute | 0 * * * * *|
/// |every hour | 0 0 * * * *|
/// |every day | 0 0 0 */1 * *|
/// |every day at 1 am | 0 0 1 */1 * *|
///
pub fn schedule_passed(
expression: &str,
) -> impl FnMut(Local<Option<DateTime<chrono::Local>>>) -> bool {
let schedule = Schedule::from_str(expression).expect("Failed to parse cron expression");
let new_expression = if expression.chars().any(|c| c.is_ascii_alphabetic()) {
str_cron_syntax(expression).expect("Failed to parse cron expression")
} else {
expression.to_string()
};

let schedule = Schedule::from_str(&new_expression).expect("Failed to parse cron expression");
move |mut local_schedule: Local<Option<DateTime<chrono::Local>>>| {
if let Some(datetime) = schedule.upcoming(chrono::Local).next() {
let now = chrono::Local::now();
Expand All @@ -187,3 +204,40 @@ pub fn schedule_passed(
false
}
}

#[test]
fn test_expression() {
assert_eq!(EVERY_5_SEC, str_cron_syntax("every 5 seconds").unwrap());
assert_eq!(EVERY_10_SEC, str_cron_syntax("every 10 seconds").unwrap());
assert_eq!(EVERY_30_SEC, str_cron_syntax("every 30 seconds").unwrap());
assert_eq!(EVERY_MIN, str_cron_syntax("every minute").unwrap());
assert_eq!(EVERY_5_MIN, str_cron_syntax("every 5 minutes").unwrap());
assert_eq!(EVERY_10_MIN, str_cron_syntax("every 10 minutes").unwrap());
assert_eq!(EVERY_30_MIN, str_cron_syntax("every 30 minutes").unwrap());
assert_eq!(EVERY_HOUR, str_cron_syntax("every hour").unwrap());
assert_eq!(EVERY_DAY, str_cron_syntax("every day").unwrap());
assert_eq!(EVERY_1_AM, str_cron_syntax("every day at 1 am").unwrap());
assert_eq!(EVERY_2_AM, str_cron_syntax("every day at 2 am").unwrap());
assert_eq!(EVERY_3_AM, str_cron_syntax("every day at 3 am").unwrap());
assert_eq!(EVERY_4_AM, str_cron_syntax("every day at 4 am").unwrap());
assert_eq!(EVERY_5_AM, str_cron_syntax("every day at 5 am").unwrap());
assert_eq!(EVERY_6_AM, str_cron_syntax("every day at 6 am").unwrap());
assert_eq!(EVERY_7_AM, str_cron_syntax("every day at 7 am").unwrap());
assert_eq!(EVERY_8_AM, str_cron_syntax("every day at 8 am").unwrap());
assert_eq!(EVERY_9_AM, str_cron_syntax("every day at 9 am").unwrap());
assert_eq!(EVERY_10_AM, str_cron_syntax("every day at 10 am").unwrap());
assert_eq!(EVERY_11_AM, str_cron_syntax("every day at 11 am").unwrap());
assert_eq!(EVERY_12_PM, str_cron_syntax("every day at 12 pm").unwrap());
assert_eq!(EVERY_1_PM, str_cron_syntax("every day at 1 pm").unwrap());
assert_eq!(EVERY_2_PM, str_cron_syntax("every day at 2 pm").unwrap());
assert_eq!(EVERY_3_PM, str_cron_syntax("every day at 3 pm").unwrap());
assert_eq!(EVERY_4_PM, str_cron_syntax("every day at 4 pm").unwrap());
assert_eq!(EVERY_5_PM, str_cron_syntax("every day at 5 pm").unwrap());
assert_eq!(EVERY_6_PM, str_cron_syntax("every day at 6 pm").unwrap());
assert_eq!(EVERY_7_PM, str_cron_syntax("every day at 7 pm").unwrap());
assert_eq!(EVERY_8_PM, str_cron_syntax("every day at 8 pm").unwrap());
assert_eq!(EVERY_9_PM, str_cron_syntax("every day at 9 pm").unwrap());
assert_eq!(EVERY_10_PM, str_cron_syntax("every day at 10 pm").unwrap());
assert_eq!(EVERY_11_PM, str_cron_syntax("every day at 11 pm").unwrap());
assert_eq!(EVERY_12_AM, str_cron_syntax("every day at 12 am").unwrap());
}

0 comments on commit 28cb90b

Please sign in to comment.