summary refs log tree commit diff
diff options
context:
space:
mode:
authorArun Isaac2023-11-23 17:49:45 +0000
committerArun Isaac2023-11-23 19:02:58 +0000
commit9f601fc3f131e82e1ee5791783d330bddde468d2 (patch)
tree1a5cfe580722168270634a5d51f0f41df1033962
parent00c911b1bd5aca3800e0263240968ad8f3fbefde (diff)
downloadccwl-9f601fc3f131e82e1ee5791783d330bddde468d2.tar.gz
ccwl-9f601fc3f131e82e1ee5791783d330bddde468d2.tar.lz
ccwl-9f601fc3f131e82e1ee5791783d330bddde468d2.zip
ccwl: Implement item separators for array inputs.
* ccwl/ccwl.scm (<input>)[separator]: New field.
* ccwl/ccwl.scm (run-arg-position, run-args): Support array input
specifiers.
(run-arg-separator): New function.
(command): Set separator on input objects.
* ccwl/cwl.scm (input->cwl-scm): Serialize itemSeparator.
* tests/ccwl.scm ("commands with non-string #:separator parameters
must raise a &ccwl-violation condition"): New test.
* doc/ccwl.skb (Cookbook)[Array input item separators]: New section.
* doc/array-input-item-separators.scm: New file.
-rw-r--r--ccwl/ccwl.scm47
-rw-r--r--ccwl/cwl.scm3
-rw-r--r--doc/array-input-item-separators.scm2
-rw-r--r--doc/ccwl.skb11
-rw-r--r--tests/ccwl.scm7
5 files changed, 63 insertions, 7 deletions
diff --git a/ccwl/ccwl.scm b/ccwl/ccwl.scm
index e602f0b..d00609d 100644
--- a/ccwl/ccwl.scm
+++ b/ccwl/ccwl.scm
@@ -65,6 +65,7 @@
             input-default
             input-position
             input-prefix
+            input-separator
             input-stage?
             input-other
             output?
@@ -93,6 +94,7 @@
   (default input-default set-input-default)
   (position input-position set-input-position)
   (prefix input-prefix set-input-prefix)
+  (separator input-separator set-input-separator)
   (stage? input-stage?)
   (other input-other))
 
@@ -325,11 +327,19 @@ compared using @code{equal?}."
 RUN-ARGS. If such an input is not present in RUN-ARGS, return #f."
   (list-index (lambda (run-arg)
                 (let ((run-arg-input
-                       (syntax-case run-arg ()
+                       (syntax-case run-arg (array)
+                         ;; input
                          (input (identifier? #'input)
                           (syntax->datum #'input))
+                         ;; prefixed input
                          ((_ input) (identifier? #'input)
                           (syntax->datum #'input))
+                         ;; array input specifier
+                         ((array input _ ...) (identifier? #'input)
+                          (syntax->datum #'input))
+                         ;; prefixed array input specifier
+                         ((_ (array input _ ...)) (identifier? #'input)
+                          (syntax->datum #'input))
                          (_ #f))))
                   (and run-arg-input
                        (eq? run-arg-input input-id))))
@@ -342,12 +352,31 @@ input, return #f."
     ((prefix _) #'prefix)
     (_ #f)))
 
+(define (run-arg-separator run-arg)
+  "Return the item separator specified in @var{run-arg} syntax."
+  (syntax-case run-arg (array)
+    ;; array input specifier
+    ((array _ args ...)
+     (apply (syntax-lambda** (#:key separator)
+              (if (and separator
+                       (not (string? (syntax->datum separator))))
+                (raise-exception
+                 (condition (ccwl-violation separator)
+                            (formatted-message "Invalid #:separator parameter ~a. #:separator parameter must be a string."
+                                               (syntax->datum separator))))
+                separator))
+            #'(args ...)))
+    ;; prefixed array input specifier
+    ((_ (array input args ...))
+     (run-arg-separator #'(array input args ...)))
+    (_ #f)))
+
 (define (run-args run defined-input-identifiers)
   "Return a list of run arguments specified in @var{run}
 syntax. @var{defined-input-identifiers} is the list of input
 identifiers defined in the commands."
   (define (syntax->run-arg x)
-    (syntax-case x ()
+    (syntax-case x (array)
       ;; Replace input symbol with quoted symbol.
       (input (identifier? #'input)
              ;; Ensure that specified input is defined in #:inputs of
@@ -363,6 +392,9 @@ identifiers defined in the commands."
       ;; Leave string as is.
       (string-arg (string? (syntax->datum #'string-arg))
                   (list #'string-arg))
+      ;; Extract input symbol from array input specifier.
+      ((array input _ ...) (identifier? #'input)
+       (syntax->run-arg #'input))
       ;; Flatten prefixed string arguments. They have no
       ;; special meaning.
       ((prefix string-arg) (and (string? (syntax->datum #'prefix))
@@ -431,11 +463,14 @@ identifiers defined in the commands."
                                             (position (run-arg-position id run))
                                             (run-arg (and position
                                                           (list-ref run position))))
-                                       #`(set-input-prefix
-                                          (set-input-position #,(input input-spec)
-                                                              #,position)
+                                       #`(set-input-separator
+                                          (set-input-prefix
+                                           (set-input-position #,(input input-spec)
+                                                               #,position)
+                                           #,(and run-arg
+                                                  (run-arg-prefix run-arg)))
                                           #,(and run-arg
-                                                 (run-arg-prefix run-arg)))))
+                                                 (run-arg-separator run-arg)))))
                                    inputs))
                      (list #,@(map output outputs))
                      (list #,@(run-args run (map input-spec-id inputs)))
diff --git a/ccwl/cwl.scm b/ccwl/cwl.scm
index 53e6548..b4a6025 100644
--- a/ccwl/cwl.scm
+++ b/ccwl/cwl.scm
@@ -142,7 +142,8 @@ CWL YAML specification."
              ;; no effect. So, leave this be.
              (inputBinding . ,(filter-alist
                                `((position . ,(input-position input))
-                                 (prefix . ,(input-prefix input)))))))
+                                 (prefix . ,(input-prefix input))
+                                 (itemSeparator . ,(input-separator input)))))))
           '())
     ,@(input-other input)))
 
diff --git a/doc/array-input-item-separators.scm b/doc/array-input-item-separators.scm
new file mode 100644
index 0000000..8cb5900
--- /dev/null
+++ b/doc/array-input-item-separators.scm
@@ -0,0 +1,2 @@
+(command #:inputs (messages #:type (array string))
+         #:run "echo" (array messages #:separator ","))
diff --git a/doc/ccwl.skb b/doc/ccwl.skb
index bcbb0e1..726b405 100644
--- a/doc/ccwl.skb
+++ b/doc/ccwl.skb
@@ -349,6 +349,17 @@ inputs to be staged. Here is a rather concocted example.]
          (scheme-source "doc/array-types.scm"))
       (p [Nested array types are also supported.]
          (scheme-source "doc/nested-array-types.scm")))
+    (section :title [Array input item separators]
+      :ident "section-array-input-item-separators"
+      (p [Occasionally, it is required to serialize array type inputs
+by separating them with a specific item separator. This can be
+achieved by explicitly specifying a separator in the ,(code [#:run])
+argument of ,(code [command]). For example, to use comma as the item
+separator, you could do]
+         (scheme-source "doc/array-input-item-separators.scm")
+         [If ,(code "[foo, bar, aal, vel]") is passed in as ,(code
+[messages]), then the command invoked is ,(samp "echo
+foo,bar,aal,vel").]))
     (section :title [Scatter/gather]
              :ident "section-scatter-gather"
       (p [ccwl supports CWL's dotproduct scatter/gather feature using
diff --git a/tests/ccwl.scm b/tests/ccwl.scm
index e876912..d3e1a96 100644
--- a/tests/ccwl.scm
+++ b/tests/ccwl.scm
@@ -308,4 +308,11 @@
    '(workflow ((foo #:type string))
       (rename #:bar foobar))))
 
+(test-condition "commands with non-string #:separator parameters must raise a &ccwl-violation condition"
+  (ccwl-violation-with-message?
+   "Invalid #:separator parameter ~a. #:separator parameter must be a string.")
+  (macroexpand
+   '(command #:inputs (messages #:type (array string))
+             #:run "echo" (array messages #:separator foo))))
+
 (test-end "ccwl")