Skip to content

Commit

Permalink
Detect version from global.json
Browse files Browse the repository at this point in the history
  • Loading branch information
Phault committed Feb 4, 2024
1 parent 0dad802 commit 7890c77
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 6 deletions.
1 change: 1 addition & 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 @@ -11,6 +11,7 @@ crate-type = ['cdylib']
[dependencies]
extism-pdk = { version = "1.0.1" }
proto_pdk = { version = "0.15.2" }
semver = "1.0.21"
serde = "1.0.195"

[dev-dependencies]
Expand Down
71 changes: 69 additions & 2 deletions src/global_json.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use std::ops::Mul;

use proto_pdk::{UnresolvedVersionSpec, Version};
use semver::Error;
use serde::Deserialize;

/// Represents `global.json`
Expand All @@ -6,13 +10,76 @@ pub struct GlobalJson {
pub sdk: Option<GlobalJsonSdk>,
}

#[derive(Deserialize)]
#[derive(Deserialize, Default)]
pub struct GlobalJsonSdk {
pub version: Option<String>,

#[serde(rename = "allowPrerelease")]
pub allow_prerelease: Option<bool>,

#[serde(rename = "rollForward")]
pub roll_forward: Option<String>,
pub roll_forward: Option<RollForward>,
}

#[derive(Deserialize, Clone)]
pub enum RollForward {
#[serde(rename = "major")]
Major,
#[serde(rename = "minor")]
Minor,
#[serde(rename = "feature")]
Feature,
#[serde(rename = "patch")]
Patch,
#[serde(rename = "latestMajor")]
LatestMajor,
#[serde(rename = "latestMinor")]
LatestMinor,
#[serde(rename = "latestFeature")]
LatestFeature,
#[serde(rename = "latestPatch")]
LatestPatch,
#[serde(rename = "disable")]
Disable,
}

impl GlobalJsonSdk {
pub fn to_version_spec(&self) -> Result<UnresolvedVersionSpec, Error> {
let roll_forward = if self.version.is_some() {
self.roll_forward
.clone()
.unwrap_or(RollForward::LatestPatch)
} else {
RollForward::LatestMajor
};

let min_version = self.version.clone().unwrap_or("0.0.0".into());

// proto does not support this earliest matching, it will always pick the latest you allow it
match roll_forward {
RollForward::LatestMajor | RollForward::Major => {
UnresolvedVersionSpec::parse(format!(">={}", min_version))
}
RollForward::LatestMinor | RollForward::Minor => {
UnresolvedVersionSpec::parse(format!("^{}", min_version))
}
RollForward::LatestFeature | RollForward::Feature => {
UnresolvedVersionSpec::parse(format!("~{}", min_version))
}
RollForward::LatestPatch | RollForward::Patch => {
let max_version = Version::parse(&min_version)?;
let max_version = format!(
"{}.{}.{}",
max_version.major,
max_version.minor,
// in 0.0.xyy x is the feature, yy is the patch
// hence we round semver patch to the next hundredth
max_version.patch.div_ceil(100).mul(100)
);

UnresolvedVersionSpec::parse(format!(">={min_version} <{max_version}"))
}
RollForward::Disable => UnresolvedVersionSpec::parse(min_version),
}
}
}
13 changes: 9 additions & 4 deletions src/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use std::collections::HashMap;
use extism_pdk::*;
use proto_pdk::*;

use crate::release_index::{fetch_channel_releases, fetch_release_index};
use crate::{
global_json::GlobalJson,
release_index::{fetch_channel_releases, fetch_release_index},
};

static NAME: &str = ".NET";
static BIN: &str = "dotnet";
Expand Down Expand Up @@ -92,10 +95,12 @@ pub fn detect_version_files(_: ()) -> FnResult<Json<DetectVersionOutput>> {
pub fn parse_version_file(
Json(input): Json<ParseVersionFileInput>,
) -> FnResult<Json<ParseVersionFileOutput>> {
let output = ParseVersionFileOutput::default();
let mut output = ParseVersionFileOutput::default();

if input.file == "global.json" && !input.content.is_empty() {
// TODO: parse and convert the odd rollForward stuff into a semver range
if input.file == "global.json" {
if let Ok(global_json) = json::from_str::<GlobalJson>(&input.content) {
output.version = global_json.sdk.unwrap_or_default().to_version_spec().ok();
}
}

Ok(Json(output))
Expand Down
17 changes: 17 additions & 0 deletions tests/versions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,20 @@ fn sets_latest_alias() {
assert!(output.aliases.contains_key("latest"));
assert_eq!(output.aliases.get("latest"), output.latest.as_ref());
}

// TODO: add tests for all the `rollForward` options
#[test]
fn parses_globaljson() {
let sandbox = create_empty_sandbox();
let plugin = create_plugin("dotnet-test", sandbox.path());

assert_eq!(
plugin.parse_version_file(ParseVersionFileInput {
content: r#"{ "sdk": { "version": "8.0.0", "rollForward": "latestFeature" } }"#.into(),
file: "global.json".into(),
}),
ParseVersionFileOutput {
version: Some(UnresolvedVersionSpec::parse("~8.0.0").unwrap()),
}
);
}

0 comments on commit 7890c77

Please sign in to comment.