Skip to content

Commit 32d7a39

Browse files
committed
Allow --variable to pass file content as a value
Signed-off-by: itowlson <[email protected]>
1 parent 2195da8 commit 32d7a39

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

crates/runtime-factors/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,15 @@ pub struct TriggerAppArgs {
110110

111111
/// Variable(s) to be passed to the app
112112
///
113-
/// A single key-value pair can be passed as `key=value`. Alternatively, the
114-
/// path to a JSON or TOML file may be given as `@file.json` or
113+
/// A single key-value pair can be passed as `key=value`, or `key=@file` to
114+
/// read the value from a text file. Alternatively, any number of key-value
115+
/// pairs may be passed via a JSON or TOML file using the syntax `@file.json` or
115116
/// `@file.toml`.
116117
///
117118
/// This option may be repeated. If the same key is specified multiple times
118119
/// the last value will be used.
119120
#[clap(long, value_parser = clap::value_parser!(VariableSource),
120-
value_name = "KEY=VALUE | @FILE.json | @FILE.toml")]
121+
value_name = "KEY=VALUE | KEY=@FILE | @FILE.json | @FILE.toml")]
121122
pub variable: Vec<VariableSource>,
122123

123124
/// Cache variables to avoid reading files twice

crates/variables-static/src/source.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,25 @@ use std::{collections::HashMap, path::PathBuf, str::FromStr};
44

55
#[derive(Clone, Debug)]
66
pub enum VariableSource {
7+
/// The value of the given variable name is the given string
78
Literal(String, String),
9+
/// The value of the given variable name is the content of the given file (as a string)
10+
FileContent(String, PathBuf),
11+
/// The file contains a map of variable names to (string) values
812
JsonFile(PathBuf),
13+
/// The file contains a map of variable names to (string) values
914
TomlFile(PathBuf),
1015
}
1116

1217
impl VariableSource {
1318
pub fn get_variables(&self) -> anyhow::Result<HashMap<String, String>> {
1419
match self {
1520
VariableSource::Literal(key, val) => Ok([(key.to_string(), val.to_string())].into()),
21+
VariableSource::FileContent(key, path) => {
22+
let val = std::fs::read_to_string(path)
23+
.with_context(|| format!("Failed to read {}.", quoted_path(path)))?;
24+
Ok([(key.to_string(), val)].into())
25+
}
1626
VariableSource::JsonFile(path) => {
1727
let json_bytes = std::fs::read(path)
1828
.with_context(|| format!("Failed to read {}.", quoted_path(path)))?;
@@ -43,7 +53,14 @@ impl FromStr for VariableSource {
4353
_ => bail!("variable files must end in .json or .toml"),
4454
}
4555
} else if let Some((key, val)) = s.split_once('=') {
46-
Ok(VariableSource::Literal(key.to_string(), val.to_string()))
56+
if let Some(path) = val.strip_prefix('@') {
57+
Ok(VariableSource::FileContent(
58+
key.to_string(),
59+
PathBuf::from(path),
60+
))
61+
} else {
62+
Ok(VariableSource::Literal(key.to_string(), val.to_string()))
63+
}
4764
} else {
4865
bail!("variables must be in the form 'key=value' or '@file'")
4966
}
@@ -66,6 +83,14 @@ mod tests {
6683
Ok(other) => panic!("wrong variant {other:?}"),
6784
Err(err) => panic!("{err:?}"),
6885
}
86+
match "[email protected]".parse() {
87+
Ok(VariableSource::FileContent(key, path)) => {
88+
assert_eq!(key, "k");
89+
assert_eq!(path, PathBuf::from("v.txt"));
90+
}
91+
Ok(other) => panic!("wrong variant {other:?}"),
92+
Err(err) => panic!("{err:?}"),
93+
}
6994
match "@file.json".parse() {
7095
Ok(VariableSource::JsonFile(_)) => {}
7196
Ok(other) => panic!("wrong variant {other:?}"),
@@ -93,6 +118,17 @@ mod tests {
93118
assert_eq!(vars["k"], "v");
94119
}
95120

121+
#[test]
122+
fn file_content_get_variables() {
123+
let mut file = tempfile::NamedTempFile::with_suffix(".txt").unwrap();
124+
file.write_all(br#"sausage time!"#).unwrap();
125+
let path = file.into_temp_path();
126+
let vars = VariableSource::FileContent("k".to_string(), path.to_path_buf())
127+
.get_variables()
128+
.unwrap();
129+
assert_eq!(vars["k"], "sausage time!");
130+
}
131+
96132
#[test]
97133
fn json_get_variables() {
98134
let mut json_file = tempfile::NamedTempFile::with_suffix(".json").unwrap();

0 commit comments

Comments
 (0)