Skip to content

Commit b62bd95

Browse files
authored
Merge pull request #577 from Metaswitch/md/fix-get-env
fix: restore get_env() template function
2 parents d3fc9df + acec0de commit b62bd95

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

docs/content/intro/feature-overview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,6 @@ Example uses include referencing environmental variables in the `floki` config,
232232
docker_switches:
233233
- -v {{ env.HOME }}/.vim:/home/build/.vim
234234
```
235+
`get_env(name="HOME")` is also available, and takes an optional `default` for when the variable isn't set.
236+
235237
Note that extensive use may reduce the reproducibility and shareability of your `floki.yaml`.

src/config.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,20 @@ fn makeloader(
195195
}
196196
}
197197

198+
// Reimplementation of tera 1's `get_env`, which was dropped in tera 2.
199+
fn get_env(kwargs: tera::Kwargs, _: &tera::State) -> tera::TeraResult<tera::Value> {
200+
let name: String = kwargs.must_get("name")?;
201+
match std::env::var(&name) {
202+
Ok(value) => Ok(value.into()),
203+
Err(_) => match kwargs.get::<tera::Value>("default")? {
204+
Some(default) => Ok(default),
205+
None => Err(tera::Error::message(format!(
206+
"Environment variable `{name}` not found"
207+
))),
208+
},
209+
}
210+
}
211+
198212
// Renders a template from a given string.
199213
pub fn render_template(template: &str, source_filename: &Path) -> Result<String, FlokiError> {
200214
let template_path = source_filename.display().to_string();
@@ -216,6 +230,7 @@ pub fn render_template(template: &str, source_filename: &Path) -> Result<String,
216230
tera.register_function("yaml", makeloader(&canonical_path, LoaderType::Yaml));
217231
tera.register_function("json", makeloader(&canonical_path, LoaderType::Json));
218232
tera.register_function("toml", makeloader(&canonical_path, LoaderType::Toml));
233+
tera.register_function("get_env", get_env);
219234

220235
tera.add_raw_template(&template_path, template)
221236
.map_err(|e| FlokiError::ProblemRenderingTemplate {
@@ -413,6 +428,34 @@ mod test {
413428
Ok(())
414429
}
415430

431+
#[test]
432+
fn test_tera_get_env() -> Result<(), Box<dyn std::error::Error>> {
433+
// Uses PATH rather than setting a var, as set_var is unsound in a threaded
434+
// test binary.
435+
let template = r#"shell: {{ get_env(name="PATH") }}"#;
436+
assert_eq!(
437+
render_template(template, Path::new("floki.yaml"))?,
438+
format!("shell: {}", std::env::var("PATH")?)
439+
);
440+
Ok(())
441+
}
442+
443+
#[test]
444+
fn test_tera_get_env_default() -> Result<(), Box<dyn std::error::Error>> {
445+
let template = r#"shell: {{ get_env(name="FLOKI_TEST_UNSET", default="bar") }}"#;
446+
assert_eq!(
447+
render_template(template, Path::new("floki.yaml"))?,
448+
"shell: bar"
449+
);
450+
Ok(())
451+
}
452+
453+
#[test]
454+
fn test_tera_get_env_missing_errors() {
455+
let template = r#"shell: {{ get_env(name="FLOKI_TEST_UNSET") }}"#;
456+
assert!(render_template(template, Path::new("floki.yaml")).is_err());
457+
}
458+
416459
#[test]
417460
fn test_strip_yaml_tags_drops_reference_tag() {
418461
let yaml = "value: !reference [template, script]";

0 commit comments

Comments
 (0)