Skip to content

Commit

Permalink
Add semver_matches function (#1713)
Browse files Browse the repository at this point in the history
  • Loading branch information
t3hmrman authored Oct 27, 2023
1 parent e01dbda commit 64d7d07
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ libc = "0.2.0"
log = "0.4.4"
num_cpus = "1.15.0"
regex = "1.5.4"
semver = "1.0.20"
serde = { version = "1.0.130", features = ["derive", "rc"] }
serde_json = "1.0.68"
sha2 = "0.10"
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,10 @@ These functions can fail, for example if a path does not have an extension, whic
- `sha256_file(path)` - Return the SHA-256 hash of the file at `path` as a hexadecimal string.
- `uuid()` - Return a randomly generated UUID.

#### Semantic Versions

- `semver_matches(version, requirement)`<sup>master</sup> - Check whether a [semantic `version`](https://semver.org), e.g., `"0.1.0"` matches a `requirement`, e.g., `">=0.1.0"`, returning `"true"` if so and `"false"` otherwise.

### Recipe Attributes

Recipes may be annotated with attributes that change their behavior.
Expand Down
22 changes: 22 additions & 0 deletions src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use {
ToKebabCase, ToLowerCamelCase, ToShoutyKebabCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase,
ToUpperCamelCase,
},
semver::{Version, VersionReq},
Function::*,
};

Expand Down Expand Up @@ -46,6 +47,7 @@ pub(crate) fn get(name: &str) -> Option<Function> {
"quote" => Unary(quote),
"replace" => Ternary(replace),
"replace_regex" => Ternary(replace_regex),
"semver_matches" => Binary(semver_matches),
"sha256" => Unary(sha256),
"sha256_file" => Unary(sha256_file),
"shoutykebabcase" => Unary(shoutykebabcase),
Expand Down Expand Up @@ -411,3 +413,23 @@ fn without_extension(_context: &FunctionContext, path: &str) -> Result<String, S

Ok(parent.join(file_stem).to_string())
}

/// Check whether a string processes properly as semver (e.x. "0.1.0")
/// and matches a given semver requirement (e.x. ">=0.1.0")
fn semver_matches(
_context: &FunctionContext,
version: &str,
requirement: &str,
) -> Result<String, String> {
Ok(
requirement
.parse::<VersionReq>()
.map_err(|err| format!("invalid semver requirement: {err}"))?
.matches(
&version
.parse::<Version>()
.map_err(|err| format!("invalid semver version: {err}"))?,
)
.to_string(),
)
}
15 changes: 15 additions & 0 deletions tests/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,21 @@ test! {
stderr: "echo Bar\n",
}

#[test]
fn semver_matches() {
Test::new()
.justfile(
"
foo:
echo {{ semver_matches('0.1.0', '>=0.1.0') }}
echo {{ semver_matches('0.1.0', '=0.0.1') }}
",
)
.stdout("true\nfalse\n")
.stderr("echo true\necho false\n")
.run();
}

fn assert_eval_eq(expression: &str, result: &str) {
Test::new()
.justfile(format!("x := {expression}"))
Expand Down
1 change: 1 addition & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub(crate) struct Output {
pub(crate) tempdir: TempDir,
}

#[must_use]
pub(crate) struct Test {
pub(crate) args: Vec<String>,
pub(crate) current_dir: PathBuf,
Expand Down

0 comments on commit 64d7d07

Please sign in to comment.