-
Notifications
You must be signed in to change notification settings - Fork 7
/
root.go
140 lines (131 loc) · 3.07 KB
/
root.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package cwl
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"github.com/otiai10/yaml2json"
"github.com/robertkrimen/otto"
)
// NewCWL ...
func NewCWL() *Root {
root := new(Root)
root.BaseCommands = BaseCommands{}
root.Hints = Hints{}
root.Inputs = Inputs{}
// root.ProvidedInputs = ProvidedInputs{}
return root
}
// Root ...
type Root struct {
Version string
Class string
Hints Hints
Doc string
Graphs Graphs
BaseCommands BaseCommands
Arguments Arguments
Namespaces Namespaces
Schemas Schemas
Stdin string
Stdout string
Stderr string
Inputs Inputs `json:"inputs"`
// ProvidedInputs ProvidedInputs `json:"-"`
Outputs Outputs
Requirements Requirements
Steps Steps
ID string // ID only appears if this Root is a step in "steps"
Expression string // appears only if Class is "ExpressionTool"
// Path
Path string `json:"-"`
// InputsVM
InputsVM *otto.Otto
}
// UnmarshalMap decode map[string]interface{} to *Root.
func (root *Root) UnmarshalMap(docs map[string]interface{}) error {
for key, val := range docs {
switch key {
case "cwlVersion":
root.Version = val.(string)
case "class":
root.Class = val.(string)
case "hints":
root.Hints = root.Hints.New(val)
case "doc":
root.Doc = val.(string)
case "baseCommand":
root.BaseCommands = root.BaseCommands.New(val)
case "arguments":
root.Arguments = root.Arguments.New(val)
case "$namespaces":
root.Namespaces = root.Namespaces.New(val)
case "$schemas":
root.Schemas = root.Schemas.New(val)
case "$graph":
root.Graphs = root.Graphs.New(val)
case "stdin":
root.Stdin = val.(string)
case "stdout":
root.Stdout = val.(string)
case "stderr":
root.Stderr = val.(string)
case "inputs":
root.Inputs = root.Inputs.New(val)
case "outputs":
root.Outputs = root.Outputs.New(val)
case "requirements":
root.Requirements = root.Requirements.New(val)
case "steps":
root.Steps = root.Steps.New(val)
case "id":
root.ID = val.(string)
case "expression":
root.Expression = val.(string)
}
}
return nil
}
// UnmarshalJSON ...
func (root *Root) UnmarshalJSON(b []byte) error {
docs := map[string]interface{}{}
if err := json.Unmarshal(b, &docs); err != nil {
return err
}
return root.UnmarshalMap(docs)
}
// Decode decodes specified file to this root
func (root *Root) Decode(r io.Reader) (err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("Parse error: %v", e)
}
}()
buf, err := ioutil.ReadAll(r)
if err != nil {
return err
}
buf, err = yaml2json.Y2J(bytes.NewReader(buf))
if err != nil {
return err
}
if err = json.Unmarshal(buf, root); err != nil {
return err
}
return nil
}
// AsStep constructs Root as a step of "steps" from interface.
func (root *Root) AsStep(i interface{}) *Root {
dest := new(Root)
switch x := i.(type) {
case string:
dest.ID = x
case map[string]interface{}:
err := dest.UnmarshalMap(x)
if err != nil {
panic(fmt.Sprintf("Failed to parse step as CWL.Root: %v", err))
}
}
return dest
}