Skip to content

Commit b217005

Browse files
committed
Support InlineTools in Workflow step fixes #111
1 parent dffddeb commit b217005

9 files changed

Lines changed: 64 additions & 26 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Unreleased
22
## 🚀 Features
33
- added NetworkAccess Requirment via `--net/--enable-network` in `s4n tool create` #104
4+
- Support InlineTools in Workflow step #111
45

56
## 🐛 Bugfixes
67
- fixed a bug with Dockerfile path resolution
78
- handle NetworkAccess Requirment in runner
8-
- ramping up runner conformance from 160/378 to 164/378
9+
- ramping up runner conformance from 160/378 to 176/378
910

1011
# v0.5.2
1112
## 🐛 Bugfixes

crates/cwl-execution/src/lib.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub fn execute_cwlfile(cwlfile: impl AsRef<Path>, raw_inputs: &[String], outdir:
7777
}
7878
}
7979

80-
let output_values = execute(cwlfile, inputs, outdir)?;
80+
let output_values = execute(cwlfile, inputs, outdir, None)?;
8181
let json = serde_json::to_string_pretty(&output_values)?;
8282
println!("{json}");
8383

@@ -88,11 +88,16 @@ pub fn execute(
8888
cwlfile: impl AsRef<Path>,
8989
inputs: HashMap<String, DefaultValue>,
9090
outdir: Option<impl AsRef<Path>>,
91+
cwl_doc: Option<&CWLDocument>,
9192
) -> Result<HashMap<String, DefaultValue>, Box<dyn Error>> {
9293
//load cwl
93-
let contents = fs::read_to_string(&cwlfile).map_err(|e| format!("Could not read CWL File {:?}: {e}", cwlfile.as_ref()))?;
94-
let contents = preprocess_cwl(&contents, &cwlfile)?;
95-
let mut doc: CWLDocument = serde_yaml::from_str(&contents).map_err(|e| format!("Could not parse CWL File {:?}: {e}", cwlfile.as_ref()))?;
94+
let mut doc: CWLDocument = if let Some(doc) = cwl_doc {
95+
doc.clone()
96+
} else {
97+
let contents = fs::read_to_string(&cwlfile).map_err(|e| format!("Could not read CWL File {:?}: {e}", cwlfile.as_ref()))?;
98+
let contents = preprocess_cwl(&contents, &cwlfile)?;
99+
serde_yaml::from_str(&contents).map_err(|e| format!("Could not parse CWL File {:?}: {e}", cwlfile.as_ref()))?
100+
};
96101

97102
match doc {
98103
CWLDocument::CommandLineTool(_) | CWLDocument::ExpressionTool(_) => run_tool(

crates/cwl-execution/src/runner.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use cwl::{
2121
inputs::{CommandLineBinding, WorkflowStepInput},
2222
requirements::{DockerRequirement, InlineJavascriptRequirement, StringOrInclude},
2323
types::{CWLType, DefaultValue, Directory, Entry, File, PathItem},
24-
wf::Workflow,
24+
wf::{StringOrDocument, Workflow},
2525
CWLDocument, StringOrNumber,
2626
};
2727
use log::{info, warn};
@@ -66,7 +66,11 @@ pub fn run_workflow(
6666
let mut outputs: HashMap<String, DefaultValue> = HashMap::new();
6767
for step_id in sorted_step_ids {
6868
if let Some(step) = workflow.get_step(&step_id) {
69-
let path = workflow_folder.join(step.run.clone());
69+
let path = if let StringOrDocument::String(run) = &step.run {
70+
Some(workflow_folder.join(run))
71+
} else {
72+
None
73+
};
7074

7175
//map inputs to correct fields
7276
let mut step_inputs = HashMap::new();
@@ -113,8 +117,13 @@ pub fn run_workflow(
113117
}
114118
}
115119
}
116-
117-
let step_outputs = execute(&path, step_inputs, Some(tmp_path.clone()))?;
120+
let step_outputs = if let Some(path) = path {
121+
execute(&path, step_inputs, Some(tmp_path.clone()), None)?
122+
} else if let StringOrDocument::Document(doc) = &step.run {
123+
execute(workflow_folder, step_inputs, Some(tmp_path.clone()), Some(doc))?
124+
} else {
125+
unreachable!()
126+
};
118127
for (key, value) in step_outputs {
119128
outputs.insert(format!("{}/{}", step.id, key), value);
120129
}

crates/cwl/src/clt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl Default for CommandLineTool {
5959
label: Option::default(),
6060
doc: Option::default(),
6161
class: String::from("CommandLineTool"),
62-
cwl_version: String::from("v1.2"),
62+
cwl_version: Some(String::from("v1.2")),
6363
inputs: Vec::default(),
6464
requirements: Option::default(),
6565
hints: Option::default(),

crates/cwl/src/et.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl Default for ExpressionTool {
2222
fn default() -> Self {
2323
Self {
2424
base: DocumentBase {
25-
cwl_version: String::from("v1.2"),
25+
cwl_version: Some(String::from("v1.2")),
2626
class: String::from("ExpressionTool"),
2727
id: Option::default(),
2828
label: Option::default(),

crates/cwl/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub mod wf;
4747
/// let document: CWLDocument = serde_yaml::from_str(yaml).unwrap();
4848
/// assert!(matches!(document, CWLDocument::CommandLineTool(_)));
4949
/// ```
50-
#[derive(Serialize, Debug, PartialEq)]
50+
#[derive(Serialize, Debug, PartialEq, Clone)]
5151
#[serde(untagged)]
5252
pub enum CWLDocument {
5353
CommandLineTool(CommandLineTool),
@@ -107,7 +107,7 @@ impl<'de> Deserialize<'de> for CWLDocument {
107107
#[serde(rename_all = "camelCase")]
108108
pub struct DocumentBase {
109109
pub class: String,
110-
pub cwl_version: String,
110+
pub cwl_version: Option<String>,
111111
#[serde(skip_serializing_if = "Option::is_none")]
112112
pub id: Option<String>,
113113
#[serde(skip_serializing_if = "Option::is_none")]

crates/cwl/src/wf.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::{
33
inputs::WorkflowStepInput,
44
outputs::WorkflowOutputParameter,
55
};
6-
use crate::DocumentBase;
6+
use crate::{CWLDocument, DocumentBase};
77
use serde::{Deserialize, Serialize};
88
use std::{
99
collections::{HashMap, VecDeque},
@@ -15,7 +15,7 @@ use std::{
1515
/// directed acyclic graph, and independent steps may run concurrently.
1616
///
1717
/// Reference: <https://www.commonwl.org/v1.2/Workflow.html>
18-
#[derive(Serialize, Deserialize, Debug, PartialEq)]
18+
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
1919
#[serde(rename_all = "camelCase")]
2020
pub struct Workflow {
2121
#[serde(flatten)]
@@ -34,7 +34,7 @@ impl Default for Workflow {
3434
label: None,
3535
doc: None,
3636
class: String::from("Workflow"),
37-
cwl_version: String::from("v1.2"),
37+
cwl_version: Some(String::from("v1.2")),
3838
requirements: Default::default(),
3939
hints: Default::default(),
4040
inputs: Default::default(),
@@ -102,7 +102,6 @@ impl Workflow {
102102
step.unwrap().out.iter().any(|output| output == parts[1])
103103
}
104104

105-
106105
/// Returns the `Workflow`'s `WorkflowStep` with id `id`
107106
pub fn get_step(&self, id: &str) -> Option<&WorkflowStep> {
108107
self.steps.iter().find(|s| s.id == *id)
@@ -166,7 +165,7 @@ impl Workflow {
166165
pub struct WorkflowStep {
167166
#[serde(default)]
168167
pub id: String,
169-
pub run: String,
168+
pub run: StringOrDocument,
170169
pub in_: HashMap<String, WorkflowStepInput>,
171170
pub out: Vec<String>,
172171
}
@@ -181,6 +180,19 @@ impl Identifiable for WorkflowStep {
181180
}
182181
}
183182

183+
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
184+
#[serde(untagged)]
185+
pub enum StringOrDocument {
186+
String(String),
187+
Document(Box<CWLDocument>),
188+
}
189+
190+
impl Default for StringOrDocument {
191+
fn default() -> Self {
192+
Self::String(String::default())
193+
}
194+
}
195+
184196
#[cfg(test)]
185197
mod tests {
186198
use super::*;

src/commands/workflow.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ use colored::Colorize;
88
use cwl::{
99
format::format_cwl,
1010
inputs::WorkflowStepInput,
11-
wf::Workflow,
12-
{load_tool, load_workflow},
11+
load_tool, load_workflow,
12+
wf::{StringOrDocument, Workflow},
13+
CWLDocument,
1314
};
1415
use cwl_execution::io::create_and_write_file;
1516
use git2::Repository;
@@ -208,8 +209,13 @@ pub fn get_workflow_status(args: &CreateWorkflowArgs) -> Result<(), Box<dyn Erro
208209
table.add_row(row![b -> "Steps:"]);
209210

210211
for step in &workflow.steps {
211-
let tool = load_tool(path.join(&step.run))?;
212-
212+
let tool = match &step.run {
213+
StringOrDocument::String(run) => load_tool(path.join(run))?,
214+
StringOrDocument::Document(boxed_doc) => match &**boxed_doc {
215+
CWLDocument::CommandLineTool(doc) => doc.clone(),
216+
_ => unreachable!(), //see #95
217+
},
218+
};
213219
let input_status = tool
214220
.inputs
215221
.iter()
@@ -246,7 +252,12 @@ pub fn get_workflow_status(args: &CreateWorkflowArgs) -> Result<(), Box<dyn Erro
246252
})
247253
.collect::<Vec<_>>()
248254
.join("\n");
249-
table.add_row(row![b -> &step.run, &input_status, &output_status]);
255+
let run = if let StringOrDocument::String(run) = &step.run {
256+
run
257+
} else {
258+
&String::from("Inline Document")
259+
};
260+
table.add_row(row![b -> run, &input_status, &output_status]);
250261
}
251262

252263
table.printstd();

src/cwl.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use cwl::{
66
outputs::WorkflowOutputParameter,
77
requirements::Requirement,
88
types::{DefaultValue, Entry, PathItem},
9-
wf::{Workflow, WorkflowStep},
9+
wf::{StringOrDocument, Workflow, WorkflowStep},
1010
};
1111
use log::{info, warn};
1212
use std::{collections::HashMap, error::Error};
@@ -67,7 +67,7 @@ impl Connectable for Workflow {
6767
if !self.has_step(name) {
6868
let workflow_step = WorkflowStep {
6969
id: name.to_string(),
70-
run: format!("../{name}/{name}.cwl"),
70+
run: StringOrDocument::String(format!("../{name}/{name}.cwl")),
7171
in_: HashMap::new(),
7272
out: tool.get_output_ids(),
7373
};
@@ -271,7 +271,7 @@ mod tests {
271271
clt::Command,
272272
inputs::CommandLineBinding,
273273
requirements::{DockerRequirement, InitialWorkDirRequirement},
274-
types::{CWLType, File, Dirent},
274+
types::{CWLType, Dirent, File},
275275
};
276276
use serde_yaml::Value;
277277
use std::path::Path;

0 commit comments

Comments
 (0)