icepick workflow: detach simulator from normal flow
This commit is contained in:
parent
57ab484995
commit
f09fb4dd59
|
@ -107,8 +107,9 @@ pub fn do_cli_thing() {
|
||||||
workflows.push((module.name.clone(), module.workflows.clone()));
|
workflows.push((module.name.clone(), module.workflows.clone()));
|
||||||
}
|
}
|
||||||
let workflows = workflows.leak();
|
let workflows = workflows.leak();
|
||||||
let mut workflow_command =
|
let mut workflow_command = clap::Command::new("workflow")
|
||||||
clap::Command::new("workflow").about("Run a pre-defined Icepick workflow");
|
.about("Run a pre-defined Icepick workflow")
|
||||||
|
.arg(clap::arg!(--"simulate-workflow").global(true));
|
||||||
for module in workflows.iter() {
|
for module in workflows.iter() {
|
||||||
let mut module_subcommand = clap::Command::new(module.0.as_str());
|
let mut module_subcommand = clap::Command::new(module.0.as_str());
|
||||||
for workflow in &module.1 {
|
for workflow in &module.1 {
|
||||||
|
@ -124,12 +125,16 @@ pub fn do_cli_thing() {
|
||||||
for command in commands.iter() {
|
for command in commands.iter() {
|
||||||
let mut subcommand = clap::Command::new(command.0.as_str());
|
let mut subcommand = clap::Command::new(command.0.as_str());
|
||||||
for op in &command.2 {
|
for op in &command.2 {
|
||||||
let mut op_command = clap::Command::new(op.name.replace('_', "-")).about(&op.description);
|
let mut op_command =
|
||||||
|
clap::Command::new(op.name.replace('_', "-")).about(&op.description);
|
||||||
for arg in &op.arguments {
|
for arg in &op.arguments {
|
||||||
let mut op_arg = clap::Arg::new(arg.name.replace('_', "-")).help(arg.description.as_str());
|
let mut op_arg =
|
||||||
|
clap::Arg::new(arg.name.replace('_', "-")).help(arg.description.as_str());
|
||||||
op_arg = match arg.r#type {
|
op_arg = match arg.r#type {
|
||||||
ArgumentType::Required => op_arg.required(true),
|
ArgumentType::Required => op_arg.required(true),
|
||||||
ArgumentType::Optional => op_arg.required(false).long(arg.name.replace('_', "-")),
|
ArgumentType::Optional => {
|
||||||
|
op_arg.required(false).long(arg.name.replace('_', "-"))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
op_command = op_command.arg(op_arg);
|
op_command = op_command.arg(op_arg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,44 @@ impl Workflow {
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn simulate_workflow(&self, mut data: HashSet<String>, operations: &[InvocableOperation]) {
|
||||||
|
// simulate the steps by using a HashSet to traverse the inputs and outputs and ensure
|
||||||
|
// there's no inconsistencies
|
||||||
|
for (i, step) in self.steps.iter().enumerate() {
|
||||||
|
// NOTE: overflow possible but unlikely
|
||||||
|
let step_index = i + 1;
|
||||||
|
|
||||||
|
// Find the relevant Operation
|
||||||
|
let Some(invocable) = operations.iter().find(|op| op.name == step.r#type) else {
|
||||||
|
panic!("Could not find operation: {}", step.r#type);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if we have the keys we want to pass into the module.
|
||||||
|
for in_memory_name in step.inputs.values() {
|
||||||
|
if !data.contains(in_memory_name) && !step.values.contains_key(in_memory_name) {
|
||||||
|
panic!("Failed simulation: step #{step_index}: missing value {in_memory_name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the module accepts those keys.
|
||||||
|
for module_input_name in step.inputs.keys() {
|
||||||
|
if !invocable
|
||||||
|
.operation
|
||||||
|
.arguments
|
||||||
|
.iter()
|
||||||
|
.any(|arg| *module_input_name == arg.name)
|
||||||
|
{
|
||||||
|
eprintln!("Simulation: step #{step_index}: input value {module_input_name} will be passed through as JSON input");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the keys we get from the module.
|
||||||
|
for in_memory_name in step.outputs.values() {
|
||||||
|
data.insert(in_memory_name.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle(&self, matches: &clap::ArgMatches, modules: Commands) {
|
pub fn handle(&self, matches: &clap::ArgMatches, modules: Commands) {
|
||||||
let inputs = self.load_inputs(matches);
|
let inputs = self.load_inputs(matches);
|
||||||
let data: HashMap<String, Value> = inputs
|
let data: HashMap<String, Value> = inputs
|
||||||
|
@ -103,43 +141,11 @@ impl Workflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulate the steps by using a HashSet to traverse the inputs and outputs and ensure
|
if matches.get_flag("simulate-workflow") {
|
||||||
// there's no inconsistencies
|
self.simulate_workflow(data.into_keys().collect(), &operations);
|
||||||
let mut simulated_values = data.keys().collect::<HashSet<_>>();
|
return;
|
||||||
for (i, step) in self.steps.iter().enumerate() {
|
|
||||||
// NOTE: overflow possible but unlikely
|
|
||||||
let step_index = i + 1;
|
|
||||||
|
|
||||||
// Find the relevant Operation
|
|
||||||
let Some(invocable) = operations.iter().find(|op| op.name == step.r#type) else {
|
|
||||||
panic!("Could not find operation: {}", step.r#type);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if we have the keys we want to pass into the module.
|
|
||||||
for in_memory_name in step.inputs.values() {
|
|
||||||
if !simulated_values.contains(in_memory_name)
|
|
||||||
&& !step.values.contains_key(in_memory_name)
|
|
||||||
{
|
|
||||||
panic!("Failed simulation: step #{step_index}: missing value {in_memory_name}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the module accepts those keys.
|
todo!("Unsimulated transaction!");
|
||||||
for module_input_name in step.inputs.keys() {
|
|
||||||
if !invocable
|
|
||||||
.operation
|
|
||||||
.arguments
|
|
||||||
.iter()
|
|
||||||
.any(|arg| *module_input_name == arg.name)
|
|
||||||
{
|
|
||||||
eprintln!("Simulation: step #{step_index}: input value {module_input_name} will be passed through as JSON input");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the keys we get from the module.
|
|
||||||
for in_memory_name in step.outputs.values() {
|
|
||||||
simulated_values.insert(in_memory_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue