Adjust the otto-models crate to allow for positional and keyword argument parameters for steps

This is required to support syntaxes like:

    sh 'make build'

or

    sh script: 'make build'

Though the latter does not currently have any support in the parser
This commit is contained in:
R Tyler Croy 2020-11-03 15:13:06 -08:00
parent ae2ac97cbb
commit a29500dcc6
3 changed files with 66 additions and 7 deletions

View File

@ -145,7 +145,7 @@ pub fn run(
ipc: sock,
endpoints: endpoints.clone(),
};
let invocation: step::Invocation<Value> = step::Invocation {
let invocation: step::Invocation<StepParameters> = step::Invocation {
configuration,
parameters: step.parameters.clone(),
};
@ -234,7 +234,7 @@ mod tests {
symbol: "echo".to_string(),
uuid: otto_models::generate_uuid(),
context: otto_models::generate_uuid(),
parameters: params,
parameters: StepParameters::Positional(vec![params]),
};
let manifests =
load_manifests_for("../stdlib", &vec![step]).expect("Failed to look into stdlib?");

View File

@ -6,7 +6,7 @@ use uuid::Uuid;
/**
* A Pipeline contains the total configuration and steps for a single pipeline run
*/
#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Pipeline {
#[serde(default = "generate_uuid")]
pub uuid: Uuid,
@ -39,7 +39,7 @@ pub enum Status {
* A context is some bucket of variables and configuration within a pipeline
* this will most frequently be a "stage" in the conventional sense
*/
#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Context {
#[serde(default = "generate_uuid")]
pub uuid: Uuid,
@ -60,18 +60,18 @@ impl Context {
/**
* A step is the smallest unit of execution for the pipeline
*/
#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Step {
#[serde(default = "generate_uuid")]
pub uuid: Uuid,
/// The uuid of the context to which this step is associated
pub context: Uuid,
pub symbol: String,
pub parameters: Value,
pub parameters: StepParameters,
}
impl Step {
pub fn new(context: Uuid, symbol: String, parameters: Value) -> Self {
pub fn new(context: Uuid, symbol: String, parameters: StepParameters) -> Self {
Self {
uuid: generate_uuid(),
context, symbol, parameters,
@ -79,8 +79,39 @@ impl Step {
}
}
/**
* The StepParameters enum helps map map both positional and keyword
* parameters for a given step.
*
* Steps should all support either positional or keyword parameters.
*
* Step libraries define their parameters in an array, so the positional parameters are expected to
* map into those directly, meaning there are no optional parameters.
*
* When using keyword parameters, users should be able to pick and choose which parameters to
* define.
*/
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum StepParameters {
Positional(Vec<Value>),
Keyword(HashMap<String, Value>),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
struct MockStep {
symbol: String,
parameters: StepParameters,
}
/**
* Generate a UUID v4 for use in structs, etc
*
* ```rust
* # use otto_models::generate_uuid;
* let uuid = generate_uuid();
* assert_eq!(false, uuid.is_nil());
* ```
*/
pub fn generate_uuid() -> Uuid {
Uuid::new_v4()
@ -88,4 +119,31 @@ pub fn generate_uuid() -> Uuid {
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize_positional() {
let buf = r#"
symbol: sh
uuid: '5599cffb-f23a-4e0f-a0b9-f74654641b2b'
context: '3ce1f6fb-79ca-4564-a47e-98265f53ef7f'
parameters:
- 'ls -lah | tail -n 5'"#;
let step = serde_yaml::from_str::<Step>(&buf).expect("Failed to deserialize");
assert_eq!(step.symbol, "sh");
}
#[test]
fn deserialize_kwargs() {
let buf = r#"
symbol: sh
uuid: '5599cffb-f23a-4e0f-a0b9-f74654641b2b'
context: '3ce1f6fb-79ca-4564-a47e-98265f53ef7f'
parameters:
script: 'ls -lah | tail -n 5'"#;
let step = serde_yaml::from_str::<Step>(&buf).expect("Failed to deserialize");
assert_eq!(step.symbol, "sh");
}
}

View File

@ -50,6 +50,7 @@ fn parse_stage(parser: &mut Pairs<Rule>) -> (Context, Vec<Step>) {
let command = parse_str(&mut parts.pop().unwrap());
let parameters = serde_yaml::Value::String(command);
let parameters = StepParameters::Positional(vec![parameters]);
let step = Step::new(stage.uuid, symbol, parameters);
steps.push(step);
}