Skip to content

Commit 8a41055

Browse files
committed
add expressiontool processing unit support
1 parent d0dc323 commit 8a41055

6 files changed

Lines changed: 197 additions & 0 deletions

File tree

src/CWL/ARCtrl.CWL.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<Compile Include="ParameterReference.fs" />
1818
<Compile Include="ToolDescription.fs" />
1919
<Compile Include="WorkflowDescription.fs" />
20+
<Compile Include="ExpressionToolDescription.fs" />
2021
<Compile Include="CWLProcessingUnit.fs" />
2122
<Compile Include="Decode.fs" />
2223
<Compile Include="Encode.fs" />

src/CWL/CWLProcessingUnit.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ namespace ARCtrl.CWL
33
type CWLProcessingUnit =
44
| CommandLineTool of CWLToolDescription
55
| Workflow of CWLWorkflowDescription
6+
| ExpressionTool of CWLExpressionToolDescription
67

78
[<RequireQualifiedAccess>]
89
module WorkflowStepRunOps =
@@ -13,6 +14,9 @@ module WorkflowStepRunOps =
1314
let fromWorkflow (workflow: CWLWorkflowDescription) : WorkflowStepRun =
1415
RunWorkflow workflow
1516

17+
let fromExpressionTool (expressionTool: CWLExpressionToolDescription) : WorkflowStepRun =
18+
RunExpressionTool expressionTool
19+
1620
let tryGetTool (run: WorkflowStepRun) : CWLToolDescription option =
1721
match run with
1822
| RunCommandLineTool (:? CWLToolDescription as tool) -> Some tool
@@ -22,3 +26,8 @@ module WorkflowStepRunOps =
2226
match run with
2327
| RunWorkflow (:? CWLWorkflowDescription as workflow) -> Some workflow
2428
| _ -> None
29+
30+
let tryGetExpressionTool (run: WorkflowStepRun) : CWLExpressionToolDescription option =
31+
match run with
32+
| RunExpressionTool (:? CWLExpressionToolDescription as expressionTool) -> Some expressionTool
33+
| _ -> None

src/CWL/Decode.fs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@ module Decode =
856856
match decodeCWLProcessingUnitElement normalizedRun with
857857
| CommandLineTool tool -> WorkflowStepRunOps.fromTool tool
858858
| Workflow workflow -> WorkflowStepRunOps.fromWorkflow workflow
859+
| ExpressionTool expressionTool -> WorkflowStepRunOps.fromExpressionTool expressionTool
859860
| _ ->
860861
raise (System.ArgumentException($"Unsupported run value for workflow step: %A{runValue}"))
861862

@@ -994,6 +995,68 @@ module Decode =
994995
description.Metadata <- Some metadata
995996
description
996997

998+
and expressionToolDecoder (yamlCWL: YAMLElement) =
999+
let cwlVersion = versionDecoder yamlCWL
1000+
let outputs = outputsDecoder yamlCWL
1001+
let inputs = inputsDecoder yamlCWL
1002+
let requirements = requirementsDecoder yamlCWL
1003+
let hints = hintsDecoder yamlCWL
1004+
let doc = docDecoder yamlCWL
1005+
let label = labelDecoder yamlCWL
1006+
let expression =
1007+
Decode.object (fun get -> get.Required.Field "expression" decodeStringOrExpression) yamlCWL
1008+
let description =
1009+
CWLExpressionToolDescription(
1010+
outputs,
1011+
expression,
1012+
cwlVersion
1013+
)
1014+
let metadata =
1015+
let md = new DynamicObj ()
1016+
yamlCWL
1017+
|> Decode.object (fun get ->
1018+
overflowDecoder
1019+
md
1020+
(
1021+
get.Overflow.FieldList [
1022+
"inputs";
1023+
"outputs";
1024+
"class";
1025+
"id";
1026+
"label";
1027+
"doc";
1028+
"requirements";
1029+
"hints";
1030+
"cwlVersion";
1031+
"expression";
1032+
]
1033+
)
1034+
) |> ignore
1035+
md
1036+
yamlCWL
1037+
|> Decode.object (fun get ->
1038+
overflowDecoder
1039+
description
1040+
(
1041+
get.MultipleOptional.FieldList [
1042+
"id";
1043+
]
1044+
)
1045+
) |> ignore
1046+
if inputs.IsSome then
1047+
description.Inputs <- inputs
1048+
if requirements.IsSome then
1049+
description.Requirements <- requirements
1050+
if hints.IsSome then
1051+
description.Hints <- hints
1052+
if doc.IsSome then
1053+
description.Doc <- doc
1054+
if label.IsSome then
1055+
description.Label <- label
1056+
if metadata.GetProperties(false) |> Seq.length > 0 then
1057+
description.Metadata <- Some metadata
1058+
description
1059+
9971060
and workflowDecoder (yamlCWL: YAMLElement) =
9981061
let cwlVersion = versionDecoder yamlCWL
9991062
let outputs = outputsDecoder yamlCWL
@@ -1062,6 +1125,7 @@ module Decode =
10621125
match cls with
10631126
| "CommandLineTool" -> CommandLineTool (commandLineToolDecoder yamlCWL)
10641127
| "Workflow" -> Workflow (workflowDecoder yamlCWL)
1128+
| "ExpressionTool" -> ExpressionTool (expressionToolDecoder yamlCWL)
10651129
| _ -> raise (System.ArgumentException($"Invalid or unsupported CWL class: {cls}"))
10661130

10671131
let stepArrayDecoder = stepArrayDecoderWithVersion "v1.2"
@@ -1078,6 +1142,11 @@ module Decode =
10781142
let yamlCWL = readSanitizedYaml cwl
10791143
workflowDecoder yamlCWL
10801144

1145+
/// Decode a CWL file string written in the YAML format into a CWLExpressionToolDescription
1146+
let decodeExpressionTool (cwl: string) =
1147+
let yamlCWL = readSanitizedYaml cwl
1148+
expressionToolDecoder yamlCWL
1149+
10811150
let decodeCWLProcessingUnit (cwl:string) =
10821151
let yamlCWL = readSanitizedYaml cwl
10831152
decodeCWLProcessingUnitElement yamlCWL

src/CWL/Encode.fs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,11 @@ module Encode =
478478
| Some workflow -> encodeWorkflowDescriptionElement workflow
479479
| None ->
480480
raise (System.ArgumentException($"RunWorkflow must contain CWLWorkflowDescription but got %A{workflowObj}"))
481+
| RunExpressionTool expressionToolObj ->
482+
match WorkflowStepRunOps.tryGetExpressionTool run with
483+
| Some expressionTool -> encodeExpressionToolDescriptionElement expressionTool
484+
| None ->
485+
raise (System.ArgumentException($"RunExpressionTool must contain CWLExpressionToolDescription but got %A{expressionToolObj}"))
481486

482487
and encodeToolDescriptionElement (td: CWLToolDescription) : YAMLElement =
483488
let basePairs =
@@ -525,6 +530,49 @@ module Encode =
525530
| None -> withOutputs
526531
yMap withMetadata
527532

533+
and encodeExpressionToolDescriptionElement (et: CWLExpressionToolDescription) : YAMLElement =
534+
let basePairs =
535+
[ "cwlVersion", Encode.string et.CWLVersion
536+
"class", Encode.string "ExpressionTool" ]
537+
|> appendOptPair (et.Label |> Option.map encodeLabel)
538+
|> appendOptPair (et.Doc |> Option.map encodeDoc)
539+
let withHints =
540+
match et.Hints with
541+
| Some h when h.Count > 0 ->
542+
basePairs @ [ "hints", (h |> Seq.map encodeRequirement |> List.ofSeq |> YAMLElement.Sequence) ]
543+
| _ -> basePairs
544+
let withRequirements =
545+
match et.Requirements with
546+
| Some r when r.Count > 0 ->
547+
withHints @ [ "requirements", (r |> Seq.map encodeRequirement |> List.ofSeq |> YAMLElement.Sequence) ]
548+
| _ -> withHints
549+
let withInputs =
550+
match et.Inputs with
551+
| Some i when i.Count > 0 ->
552+
withRequirements @ [ "inputs", (i |> Seq.map encodeCWLInput |> Seq.toList |> yMap) ]
553+
| _ -> withRequirements
554+
let withOutputs =
555+
withInputs @ [ "outputs", (et.Outputs |> Seq.map encodeCWLOutput |> Seq.toList |> yMap) ]
556+
let withExpression =
557+
withOutputs @ [ "expression", Encode.string et.Expression ]
558+
let withMetadata =
559+
match et.Metadata with
560+
| Some md ->
561+
md.GetProperties(false)
562+
|> Seq.fold (fun acc kvp ->
563+
let encodedValue =
564+
match kvp.Value with
565+
| :? string as s -> Encode.string s
566+
| :? bool as b -> yBool b
567+
| :? int as i -> Encode.int i
568+
| :? float as f -> Encode.float f
569+
| :? YAMLElement as y -> y
570+
| _ -> Encode.string (string kvp.Value)
571+
acc @ [ kvp.Key, encodedValue ]
572+
) withExpression
573+
| None -> withExpression
574+
yMap withMetadata
575+
528576
and encodeWorkflowDescriptionElement (wd: CWLWorkflowDescription) : YAMLElement =
529577
let basePairs =
530578
[ "cwlVersion", Encode.string wd.CWLVersion
@@ -653,11 +701,16 @@ module Encode =
653701
encodeWorkflowDescriptionElement wd
654702
|> renderTopLevelElement ["cwlVersion"; "class"; "label"; "doc"] ["hints"; "requirements"; "inputs"; "steps"; "outputs"]
655703

704+
let encodeExpressionToolDescription (et:CWLExpressionToolDescription) : string =
705+
encodeExpressionToolDescriptionElement et
706+
|> renderTopLevelElement ["cwlVersion"; "class"; "label"; "doc"] ["hints"; "requirements"; "inputs"; "outputs"; "expression"]
707+
656708

657709
let encodeProcessingUnit (pu : CWLProcessingUnit) :string =
658710
match pu with
659711
| CommandLineTool td -> encodeToolDescription td
660712
| Workflow wd -> encodeWorkflowDescription wd
713+
| ExpressionTool et -> encodeExpressionToolDescription et
661714

662715
/// Encode a CWLType to a single-line YAML string using flow/inline style
663716
/// This produces YAML that doesn't contain newlines and can be embedded in JSON
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
namespace ARCtrl.CWL
2+
3+
open DynamicObj
4+
open Fable.Core
5+
6+
[<AttachMembers>]
7+
type CWLExpressionToolDescription (
8+
outputs: ResizeArray<CWLOutput>,
9+
expression: string,
10+
?cwlVersion: string,
11+
?requirements: ResizeArray<Requirement>,
12+
?hints: ResizeArray<Requirement>,
13+
?inputs: ResizeArray<CWLInput>,
14+
?metadata: DynamicObj,
15+
?label: string,
16+
?doc: string
17+
) =
18+
inherit DynamicObj ()
19+
20+
let mutable _cwlVersion: string = cwlVersion |> Option.defaultValue "v1.2"
21+
let mutable _outputs: ResizeArray<CWLOutput> = outputs
22+
let mutable _expression: string = expression
23+
let mutable _requirements: ResizeArray<Requirement> option = requirements
24+
let mutable _hints: ResizeArray<Requirement> option = hints
25+
let mutable _inputs: ResizeArray<CWLInput> option = inputs
26+
let mutable _metadata: DynamicObj option = metadata
27+
let mutable _label: string option = label
28+
let mutable _doc: string option = doc
29+
30+
member this.CWLVersion
31+
with get() = _cwlVersion
32+
and set(version) = _cwlVersion <- version
33+
34+
member this.Outputs
35+
with get() = _outputs
36+
and set(outputs) = _outputs <- outputs
37+
38+
member this.Expression
39+
with get() = _expression
40+
and set(expression) = _expression <- expression
41+
42+
member this.Requirements
43+
with get() = _requirements
44+
and set(requirements) = _requirements <- requirements
45+
46+
member this.Hints
47+
with get() = _hints
48+
and set(hints) = _hints <- hints
49+
50+
member this.Inputs
51+
with get() = _inputs
52+
and set(inputs) = _inputs <- inputs
53+
54+
member this.Metadata
55+
with get() = _metadata
56+
and set(metadata) = _metadata <- metadata
57+
58+
member this.Label
59+
with get() = _label
60+
and set(label) = _label <- label
61+
62+
member this.Doc
63+
with get() = _doc
64+
and set(doc) = _doc <- doc

src/CWL/WorkflowSteps.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ type WorkflowStepRun =
115115
| RunString of string
116116
| RunCommandLineTool of obj
117117
| RunWorkflow of obj
118+
| RunExpressionTool of obj
118119

119120
[<AttachMembers>]
120121
type WorkflowStep (

0 commit comments

Comments
 (0)