Skip to content

Commit

Permalink
feat: add load_from_file jinja function (prefix-dev#468)
Browse files Browse the repository at this point in the history
  • Loading branch information
swarnimarun authored Jan 12, 2024
1 parent e1c4162 commit c7f699f
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 3 deletions.
40 changes: 39 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,11 @@ zip = { version = "0.6.6", default-features = false, features = [
"deflate",
] }
bzip2 = "0.4.4"
base64 = "0.21.6"
flate2 = "1.0.28"
xz2 = "0.1.7"
zstd = "0.13.0"
base64 = "0.21.6"
toml = "0.8.8"

[dev-dependencies]
insta = { version = "1.34.0", features = ["yaml"] }
Expand Down
2 changes: 1 addition & 1 deletion src/packaging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ fn contains_prefix_text(file_path: &Path, prefix: &Path) -> Result<bool, Packagi
}

#[allow(dead_code)]
fn to_forward_slash_lossy(path: &Path) -> std::borrow::Cow<'_, str> {
pub(crate) fn to_forward_slash_lossy(path: &Path) -> std::borrow::Cow<'_, str> {
#[cfg(target_os = "windows")]
{
let mut buf = String::new();
Expand Down
72 changes: 72 additions & 0 deletions src/recipe/jinja.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ fn set_jinja(config: &SelectorConfig) -> minijinja::Environment<'static> {
target_platform,
build_platform,
variant,
experimental,
..
} = config.clone();
env.add_function("cdt", move |package_name: String| {
Expand Down Expand Up @@ -241,6 +242,37 @@ fn set_jinja(config: &SelectorConfig) -> minijinja::Environment<'static> {
format!("{}{}", major, minor)
});

env.add_function("load_from_file", move |path: String| {
if !experimental {
return Err(minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"Experimental feature: provide the `--experimental` flag to enable this feature",
));
}
let src = std::fs::read_to_string(&path).map_err(|e| {
minijinja::Error::new(minijinja::ErrorKind::UndefinedError, e.to_string())
})?;
// tracing::info!("loading from path: {path}");
let filename = path
.split('/')
.last()
.expect("unreachable: split will always atleast return empty string");
// tracing::info!("loading filename: {filename}");
let value: minijinja::Value = match filename.split_once('.') {
Some((_, "yaml")) | Some((_, "yml")) => serde_yaml::from_str(&src).map_err(|e| {
minijinja::Error::new(minijinja::ErrorKind::CannotDeserialize, e.to_string())
})?,
Some((_, "json")) => serde_json::from_str(&src).map_err(|e| {
minijinja::Error::new(minijinja::ErrorKind::CannotDeserialize, e.to_string())
})?,
Some((_, "toml")) => toml::from_str(&src).map_err(|e| {
minijinja::Error::new(minijinja::ErrorKind::CannotDeserialize, e.to_string())
})?,
_ => Value::from(src),
};
Ok(value)
});

env
}

Expand Down Expand Up @@ -557,6 +589,8 @@ mod tests {

use rattler_conda_types::Platform;

use crate::packaging::to_forward_slash_lossy;

use super::*;

fn with_temp_dir(key: &'static str, f: impl Fn(&std::path::Path)) {
Expand Down Expand Up @@ -633,6 +667,44 @@ mod tests {
});
}

#[test]
#[rustfmt::skip]
fn eval_load_from_file() {
let options = SelectorConfig {
target_platform: Platform::Linux64,
build_platform: Platform::Linux64,
experimental: true,
..Default::default()
};

let jinja = Jinja::new(options);

let temp_dir = tempfile::tempdir().unwrap();
let path = temp_dir.path().join("test.json");
let path_str = to_forward_slash_lossy(&path);
std::fs::write(&path, "{ \"hello\": \"world\" }").unwrap();
assert_eq!(
jinja.eval(&format!("load_from_file('{}')['hello']", path_str)).expect("test 1").as_str(),
Some("world"),
);

let path = temp_dir.path().join("test.yaml");
std::fs::write(&path, "hello: world").unwrap();
let path_str = to_forward_slash_lossy(&path);
assert_eq!(
jinja.eval(&format!("load_from_file('{}')['hello']", path_str)).expect("test 2").as_str(),
Some("world"),
);

let path = temp_dir.path().join("test.toml");
let path_str = to_forward_slash_lossy(&path);
std::fs::write(&path, "hello = 'world'").unwrap();
assert_eq!(
jinja.eval(&format!("load_from_file('{}')['hello']", path_str)).expect("test 2").as_str(),
Some("world"),
);
}

#[test]
#[rustfmt::skip]
fn eval() {
Expand Down

0 comments on commit c7f699f

Please sign in to comment.