summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Adossi ("vados") <vados@vadosware.io>2023-10-28 05:07:46 +0900
committerGitHub <noreply@github.com>2023-10-27 20:07:46 +0000
commit64d7d071855c9634cb38b2b35d999bf179a48869 (patch)
treecac8460c5f2292d019e7097cda34f7e8d7241023
parente01dbda156ad33149064277abac45aa1eceaf60c (diff)
Add `semver_matches` function (#1713)
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--README.md4
-rw-r--r--src/function.rs22
-rw-r--r--tests/functions.rs15
-rw-r--r--tests/test.rs1
6 files changed, 50 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4aa30724..49c5fa28 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -337,6 +337,7 @@ dependencies = [
"num_cpus",
"pretty_assertions",
"regex",
+ "semver",
"serde",
"serde_json",
"sha2",
@@ -574,6 +575,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
+name = "semver"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
+
+[[package]]
name = "serde"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 20ba6d92..34217b76 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/README.md b/README.md
index 2d625f09..36bbd242 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/src/function.rs b/src/function.rs
index 84c21c03..086ede1b 100644
--- a/src/function.rs
+++ b/src/function.rs
@@ -4,6 +4,7 @@ use {
ToKebabCase, ToLowerCamelCase, ToShoutyKebabCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase,
ToUpperCamelCase,
},
+ semver::{Version, VersionReq},
Function::*,
};
@@ -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),
@@ -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(),
+ )
+}
diff --git a/tests/functions.rs b/tests/functions.rs
index 5511329a..150f293d 100644
--- a/tests/functions.rs
+++ b/tests/functions.rs
@@ -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}"))
diff --git a/tests/test.rs b/tests/test.rs
index e8dc786b..4aad92b7 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -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,