Skip to content
This repository has been archived by the owner on Jul 17, 2024. It is now read-only.

Commit

Permalink
new: Support named captures for regex. (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
milesj authored Jan 4, 2024
1 parent 53fcaf7 commit 1a3901f
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 13 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 0.7.1

#### 🚀 Updates

- Added `resolve.version-pattern` and improved regex handling.
- Now supports named captures: `major`, `minor`, `patch`, `pre`, `build`
- Will construct the version from the above captures.
- Deprecated `resolve.git-tag-pattern` (use the above instead).

## 0.7.0

#### 🚀 Updates
Expand Down
60 changes: 51 additions & 9 deletions src/proto.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::schema::{PlatformMapper, Schema, SchemaType};
use extism_pdk::*;
use proto_pdk::*;
use regex::Captures;
use serde_json::Value as JsonValue;

#[host_fn]
Expand Down Expand Up @@ -66,39 +67,80 @@ pub fn remove_v_prefix(value: &str) -> &str {
value
}

fn create_version(cap: Captures) -> String {
// If no named, use entire string (legacy)
if cap.name("major").is_none() {
return cap.get(1).unwrap().as_str().to_string();
}

// Otherwise piece named parts together
let mut version = String::new();

version.push_str(cap.name("major").map(|c| c.as_str()).unwrap_or("0"));
version.push('.');
version.push_str(cap.name("minor").map(|c| c.as_str()).unwrap_or("0"));
version.push('.');
version.push_str(cap.name("patch").map(|c| c.as_str()).unwrap_or("0"));

if let Some(pre) = cap.name("pre").map(|c| c.as_str()) {
if !pre.starts_with('-') {
version.push('-');
}
version.push_str(pre);
}

if let Some(build) = cap.name("build").map(|c| c.as_str()) {
if !build.starts_with('+') {
version.push('+');
}
version.push_str(build);
}

version
}

#[plugin_fn]
pub fn load_versions(Json(_): Json<LoadVersionsInput>) -> FnResult<Json<LoadVersionsOutput>> {
let schema = get_schema()?;

if let Some(repository) = schema.resolve.git_url {
let pattern = regex::Regex::new(&schema.resolve.git_tag_pattern)?;
let pattern = regex::Regex::new(
schema
.resolve
.git_tag_pattern
.as_ref()
.unwrap_or(&schema.resolve.version_pattern),
)?;

let tags = load_git_tags(repository)?;
let tags = tags
.into_iter()
.filter_map(|t| {
pattern
.captures(&t)
.map(|captures| captures.get(1).unwrap().as_str().to_string())
})
.filter_map(|t| pattern.captures(&t).map(create_version))
.collect::<Vec<_>>();

return Ok(Json(LoadVersionsOutput::from(tags)?));
}

if let Some(endpoint) = schema.resolve.manifest_url {
let response: Vec<JsonValue> = fetch_url(endpoint)?;
let pattern = regex::Regex::new(&schema.resolve.version_pattern)?;
let version_key = &schema.resolve.manifest_version_key;
let response: Vec<JsonValue> = fetch_url(endpoint)?;
let mut versions = vec![];

let mut push_version = |v: &str| {
if let Some(cap) = pattern.captures(v) {
versions.push(create_version(cap));
}
};

for row in response {
match row {
JsonValue::String(v) => {
versions.push(remove_v_prefix(&v).to_string());
push_version(&v);
}
JsonValue::Object(o) => {
if let Some(JsonValue::String(v)) = o.get(version_key) {
versions.push(remove_v_prefix(v).to_string());
push_version(v);
}
}
_ => {}
Expand Down
8 changes: 5 additions & 3 deletions src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ pub struct GlobalsSchema {
#[derive(Debug, Deserialize)]
#[serde(default, rename_all = "kebab-case")]
pub struct ResolveSchema {
pub version_pattern: String,
// Manifest
pub manifest_url: Option<String>,
pub manifest_version_key: String,
// Tags
pub git_url: Option<String>,
pub git_tag_pattern: String,
pub git_tag_pattern: Option<String>,
}

impl Default for ResolveSchema {
Expand All @@ -55,8 +56,9 @@ impl Default for ResolveSchema {
manifest_url: None,
manifest_version_key: "version".to_string(),
git_url: None,
git_tag_pattern:
r"^v?(([0-9]+)\.([0-9]+)\.([0-9]+)(-[0-9a-zA-Z\.]+)?(\+[-0-9a-zA-Z\.]+)?)$"
git_tag_pattern: None,
version_pattern:
r"^v?((?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<patch>[0-9]+)(?<pre>-[0-9a-zA-Z\.]+)?(?<build>\+[-0-9a-zA-Z\.]+)?)$"
.to_string(),
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/versions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ generate_resolve_versions_tests!(
"1.0.3" => "1.0.3",
"1.4" => "1.4.0",
"1.5" => "1.5.1",
"1" => "1.18.5",
"1" => "1.19.0",
},
Some(locate_fixture("schemas").join("base.toml"))
);
Expand Down

0 comments on commit 1a3901f

Please sign in to comment.