Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions registry/oc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ full = "http:oc"
bin = "oc"
version_list_url = "https://mirror.openshift.com/pub/openshift-v4/clients/ocp/"
version_regex = 'href="(\d+\.\d+\.\d+)/"'
version_expr = 'sortVersions(versions)'

[backends.options.platforms.linux-x64]
url = "https://mirror.openshift.com/pub/openshift-v4/clients/ocp/{{ version }}/openshift-client-linux-{{ version }}.tar.gz"
Expand Down
1 change: 1 addition & 0 deletions registry/openshift-install.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ full = "http:openshift-install"
bin = "openshift-install"
version_list_url = "https://mirror.openshift.com/pub/openshift-v4/clients/ocp/"
version_regex = 'href="(\d+\.\d+\.\d+)/"'
version_expr = 'sortVersions(versions)'

[backends.options.platforms.linux-x64]
url = "https://mirror.openshift.com/pub/openshift-v4/clients/ocp/{{ version }}/openshift-install-linux-{{ version }}.tar.gz"
Expand Down
39 changes: 31 additions & 8 deletions src/backend/version_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,9 @@ pub fn parse_version_list(
let mut versions = Vec::new();
let trimmed = content.trim();

// If an expr is provided, use it to evaluate and extract versions
// Fail hard if the expression is invalid - don't silently fall through
if let Some(expr_str) = version_expr {
versions = eval_version_expr(expr_str, trimmed)?;
}
// If a JSON path is provided (like ".[].version" or ".versions"), try to use it
// but fall back to text parsing if JSON parsing fails
else if let Some(json_path) = version_json_path {
if let Some(json_path) = version_json_path {
if let Ok(json) = serde_json::from_str::<serde_json::Value>(trimmed)
&& let Ok(extracted) = jq::extract(&json, json_path)
{
Expand Down Expand Up @@ -119,16 +114,30 @@ pub fn parse_version_list(

// DO NOT sort versions here - the backend/upstream determines version order.
// Sorting is handled elsewhere (e.g., versions host, resolve logic).
// If a version_expr is provided, use it to post-process the extracted versions
// (e.g. sortVersions). When no other extraction method produced results,
// the expr operates on `body` alone (the original behavior).
if let Some(expr_str) = version_expr {
versions = eval_version_expr(expr_str, trimmed, &versions)?;
}
Comment thread
greptile-apps[bot] marked this conversation as resolved.

Ok(versions)
}

/// Evaluate a version expression using expr-lang
fn eval_version_expr(expr_str: &str, body: &str) -> Result<Vec<String>> {
/// Evaluate a version expression using expr-lang.
/// When `versions` is non-empty, it is injected as a `versions` variable
/// so the expression can post-process previously extracted version lists.
fn eval_version_expr(expr_str: &str, body: &str, versions: &[String]) -> Result<Vec<String>> {
use versions::Versioning;

let mut ctx = Context::default();
ctx.insert("body".to_string(), Value::String(body.to_string()));
if !versions.is_empty() {
ctx.insert(
"versions".to_string(),
Value::Array(versions.iter().map(|v| Value::String(v.clone())).collect()),
);
}
Comment thread
greptile-apps[bot] marked this conversation as resolved.
Outdated
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

// expr-lang 1.0+ has built-in fromJSON, keys, values, len, toJSON functions
let mut env = Environment::new();
Expand Down Expand Up @@ -410,4 +419,18 @@ mod tests {
.unwrap();
assert_eq!(versions, vec!["1.0.0", "1.1.0", "1.2.0-rc1"]);
}

#[test]
fn test_parse_with_regex_and_version_expr_pipeline() {
let content =
r#"<a href="4.9.9/">4.9.9</a><a href="4.21.3/">4.21.3</a><a href="4.10.1/">4.10.1</a>"#;
let versions = parse_version_list(
content,
Some(r#"href="(\d+\.\d+\.\d+)/""#),
None,
Some("sortVersions(versions)"),
)
.unwrap();
assert_eq!(versions, vec!["4.9.9", "4.10.1", "4.21.3"]);
}
}
Loading