diff options
| -rw-r--r-- | HACKING.md | 2 | ||||
| -rw-r--r-- | e2e-tests/jobs/command-line-tool-with-array-input.yaml | 3 | ||||
| -rw-r--r-- | e2e-tests/tests.yaml | 9 | ||||
| -rw-r--r-- | e2e-tests/tools/command-line-tool-with-array-input.scm | 3 | ||||
| -rw-r--r-- | ravanan/work/command-line-tool.scm | 72 | ||||
| -rw-r--r-- | ravanan/workflow.scm | 15 |
6 files changed, 67 insertions, 37 deletions
diff --git a/HACKING.md b/HACKING.md index 4d8b6fe..7df6d02 100644 --- a/HACKING.md +++ b/HACKING.md @@ -18,8 +18,6 @@ $(guix build -L ../.guix -f ../.guix/e2e-tests.scm) ``` Since ravanan depends on guix, and that guix may be too old, you may need to run this command outside the usual development environment. -## Run specific end-to-end test - When hacking on ravanan, you may be trying to get a specific test to pass, and may want to repeatedly run that specific test alone. You can do this by passing additional cwltest arguments. For example, to only run the `hello-world` test: ``` $(guix build -L ../.guix -f ../.guix/e2e-tests.scm) -s hello-world diff --git a/e2e-tests/jobs/command-line-tool-with-array-input.yaml b/e2e-tests/jobs/command-line-tool-with-array-input.yaml new file mode 100644 index 0000000..a0fc50c --- /dev/null +++ b/e2e-tests/jobs/command-line-tool-with-array-input.yaml @@ -0,0 +1,3 @@ +messages: + - foo + - bar diff --git a/e2e-tests/tests.yaml b/e2e-tests/tests.yaml index d14b93a..6604e39 100644 --- a/e2e-tests/tests.yaml +++ b/e2e-tests/tests.yaml @@ -241,3 +241,12 @@ class: File size: 13 checksum: sha1$47a013e660d408619d894b20806b1d5086aab03b +- id: command-line-tool-with-array-input + doc: CommandLineTool with array input + tool: tools/command-line-tool-with-array-input.cwl + job: jobs/command-line-tool-with-array-input.yaml + output: + output_message: + class: File + size: 8 + checksum: sha1$d53a205a336e07cf9eac45471b3870f9489288ec diff --git a/e2e-tests/tools/command-line-tool-with-array-input.scm b/e2e-tests/tools/command-line-tool-with-array-input.scm new file mode 100644 index 0000000..38a8722 --- /dev/null +++ b/e2e-tests/tools/command-line-tool-with-array-input.scm @@ -0,0 +1,3 @@ +(command #:inputs (messages #:type (array string)) + #:run "echo" messages + #:outputs (output_message #:type stdout)) diff --git a/ravanan/work/command-line-tool.scm b/ravanan/work/command-line-tool.scm index 843e939..95d69f5 100644 --- a/ravanan/work/command-line-tool.scm +++ b/ravanan/work/command-line-tool.scm @@ -351,20 +351,33 @@ the G-expressions are inserted." @code{<command-line-binding>} objects may be strings or G-expressions. The G-expressions may reference @var{inputs} and @var{runtime} variables that must be defined in the context in which the G-expressions are inserted." + (define (value->command-line-binding position prefix value) + (let ((type (object-type value))) + (cond + ((cwl-array-type? type) + (command-line-binding position + prefix + type + (vector-map (cut value->command-line-binding + %nothing + %nothing + <>) + value) + %nothing)) + (else + (command-line-binding position prefix type value %nothing))))) + (define (argument->command-line-binding i argument) - (let ((value (assoc-ref* argument "valueFrom"))) - (command-line-binding (cond - ((assoc-ref argument "position") - => string->number) - (else i)) - (maybe-assoc-ref (just argument) "prefix") - (object-type value) - value - %nothing))) + (value->command-line-binding (cond + ((assoc-ref argument "position") + => string->number) + (else i)) + (maybe-assoc-ref (just argument) "prefix") + (assoc-ref* argument "valueFrom"))) (define (collect-bindings ids+inputs+types+bindings) - (append-map id+input+type-tree+binding->command-line-binding - ids+inputs+types+bindings)) + (map id+input+type-tree+binding->command-line-binding + ids+inputs+types+bindings)) (define id+input+type-tree+binding->command-line-binding (match-lambda @@ -391,26 +404,25 @@ be defined in the context in which the G-expressions are inserted." ;; Recurse over array types. ;; TODO: Implement record and enum types. ((cwl-array-type? matched-type) - (list (command-line-binding - position - prefix - matched-type - (append-map (lambda (i input) - (id+input+type-tree+binding->command-line-binding - (list (append id (list i)) - input - (assoc-ref type-tree "items") - (maybe-assoc-ref (just type-tree) - "inputBinding")))) - (iota (vector-length input)) - (vector->list input)) - (maybe-assoc-ref binding "itemSeparator")))) + (command-line-binding + position + prefix + matched-type + (vector-map-indexed (lambda (i input) + (id+input+type-tree+binding->command-line-binding + (list (append id (list i)) + input + (assoc-ref type-tree "items") + (maybe-assoc-ref (just type-tree) + "inputBinding")))) + input) + (maybe-assoc-ref binding "itemSeparator"))) (else - (list (command-line-binding position - prefix - matched-type - (apply json-ref inputs id) - %nothing))))))))) + (command-line-binding position + prefix + matched-type + (apply json-ref inputs id) + %nothing)))))))) ;; For details of this algorithm, see ยง4.1 Input binding of the CWL ;; 1.2 CommandLineTool specification: diff --git a/ravanan/workflow.scm b/ravanan/workflow.scm index 2fd00d6..0451f68 100644 --- a/ravanan/workflow.scm +++ b/ravanan/workflow.scm @@ -279,11 +279,16 @@ command-line-tool)}." #()) (or (assoc-ref cwl "hints") #())) - (vector-map->list (lambda (input) - (let ((input-id (assoc-ref input "id"))) - (cons input-id - (json-ref step "in" input-id)))) - (assoc-ref run "inputs")) + (vector-filter-map->list (lambda (input) + (let ((input-id (assoc-ref* input "id"))) + (match (assoc input-id + (assoc-ref* step "in")) + ((_ . source) + (cons input-id source)) + ;; Optional inputs may be + ;; missing a source; drop them. + (#f #f)))) + (assoc-ref* run "inputs")) ;; Inputs that either have a default or accept null values are ;; optional. (vector-filter-map->list (lambda (input) |
