Skip to content

Commit

Permalink
Added semver.is_valid and semver.compare (microsoft#49)
Browse files Browse the repository at this point in the history
* Completed semver.is_valid and semver.compare
* Addressed PR comments

Signed-off-by: Minh Nguyen <[email protected]>

---------

Signed-off-by: Minh Nguyen <[email protected]>
Co-authored-by: Anand Krishnamoorthi <[email protected]>
  • Loading branch information
justanotherminh and anakrish authored Nov 17, 2023
1 parent a75f7c5 commit e838d5a
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"

[dependencies]
anyhow = "1.0.66"
semver = "1.0.20"
ordered-float = "3.4.0"
serde = {version = "1.0.150", features = ["derive", "rc"] }
serde_json = "1.0.89"
Expand Down
3 changes: 2 additions & 1 deletion src/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod deprecated;
mod encoding;
pub mod numbers;
mod objects;
mod semver;
pub mod sets;
mod strings;
mod time;
Expand Down Expand Up @@ -59,7 +60,7 @@ lazy_static! {
//http::register(&mut m);
//net::register(&mut m);
//uuid::register(&mut m);
//semantic_versions::register(&mut m);
semver::register(&mut m);
//rego::register(&mut m);
//opa::register(&mut m);
debugging::register(&mut m);
Expand Down
43 changes: 43 additions & 0 deletions src/builtins/semver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::ast::{Expr, Ref};
use crate::builtins;
use crate::builtins::utils::{ensure_args_count, ensure_string};
use crate::lexer::Span;
use crate::value::Value;

use semver::Version;

use std::cmp::Ordering;
use std::collections::HashMap;

use anyhow::{Ok, Result};

pub fn register(m: &mut HashMap<&'static str, builtins::BuiltinFcn>) {
m.insert("semver.compare", (compare, 2));
m.insert("semver.is_valid", (is_valid, 1));
}

fn compare(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
let name = "semver.compare";
ensure_args_count(span, name, params, args, 2)?;

let v1 = ensure_string(name, &params[0], &args[0])?;
let v2 = ensure_string(name, &params[1], &args[1])?;
let version1 = Version::parse(&v1)?;
let version2 = Version::parse(&v2)?;
let result = match version1.cmp_precedence(&version2) {
Ordering::Less => -1,
Ordering::Equal => 0,
Ordering::Greater => 1,
};
Ok(Value::from_float(result as f64))
}

fn is_valid(span: &Span, params: &[Ref<Expr>], args: &[Value]) -> Result<Value> {
let name = "semver.is_valid";
ensure_args_count(span, name, params, args, 1)?;
let v = ensure_string(name, &params[0], &args[0])?;
Ok(Value::Bool(Version::parse(&v).is_ok()))
}
47 changes: 47 additions & 0 deletions tests/interpreter/cases/builtins/semver/compare.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

cases:
- note: semver.compare passing
data: {}
modules:
- |
package test
vers = [
"1.9.10",
"1.8.15"
]
# Compare each version against itself and others.
r = [ a | a = semver.compare(vers[_], vers[_]) ]
query: data.test.r
want_result: [0, 1, -1, 1]
skip: true # TODO: remove this

- note: semver.compare wrong arg1 type
data: {}
modules:
- |
package test
a = semver.compare("", 1)
query: data.test.a
error: expects string argument

- note: semver.compare wrong arg2 type
data: {}
modules:
- |
package test
a = semver.compare(1, "")
query: data.test.a
error: expects string argument

- note: semver extra arg
data: {}
modules:
- |
package test
a = semver.compare("", "", "")
query: data.test.a
error: expects 2 arguments
39 changes: 39 additions & 0 deletions tests/interpreter/cases/builtins/semver/is_valid.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

cases:
- note: semver.is_valid passing
data: {}
modules:
- |
package test
vers = [
"1.9.10",
"1.8.15",
"1.1",
"1.1.12-rc1+foo"
]
r = [ a | a = semver.is_valid(vers[_]) ]
query: data.test.r
want_result: [true, true, false]
skip: true # TODO: remove this

- note: semver.compare wrong arg1 type
data: {}
modules:
- |
package test
a = semver.is_valid(1)
query: data.test.a
error: expects string argument

- note: semver.is_valid extra arg
data: {}
modules:
- |
package test
a = semver.is_valid("", "")
query: data.test.a
error: expects 1 argument

0 comments on commit e838d5a

Please sign in to comment.