summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArun Isaac2023-10-15 12:13:58 +0100
committerArun Isaac2023-10-15 12:41:39 +0100
commitcb66af826596b7bfba0fa45f8eb25fcf1613bc13 (patch)
tree15631d090f37869319f3f30bd875a3af6f1a7237
parent3063c33634d4a25ba99a2c884dd8bf04e519f914 (diff)
downloadccwl-cb66af826596b7bfba0fa45f8eb25fcf1613bc13.tar.gz
ccwl-cb66af826596b7bfba0fa45f8eb25fcf1613bc13.tar.lz
ccwl-cb66af826596b7bfba0fa45f8eb25fcf1613bc13.zip
ccwl: Make #:stderr and #:stdout first class parameters.
#:stderr and #:stdout, especially #:stdout, are commonly required. They ought to be first class parameters and not tucked away into #:other. * ccwl/ccwl.scm (<command>)[stderr, stdout]: New fields. * ccwl/ccwl.scm (command): Accept #:stderr and #:stdout as first class parameters. * ccwl/cwl.scm (command->cwl-scm): Serialize stderr and stdout fields. * doc/capture-stdout.scm (print), doc/decompress-compile-run.scm (run), doc/checksum.scm (md5sum, sha1sum, sha256sum), doc/spell-check.scm (find-misspellings): Capture stdout in file. * doc/checksum.scm, doc/decompress-compile-run.scm: * doc/ccwl.skb (Tutorial)[Capturing the standard output stream of a command]: Document #:stdout first class parameter. * doc/ccwl.skb (Tutorial)[Workflow with multiple steps]: Capture stdout in explicitly named files. * tests/ccwl.scm ("commands with non-string #:stderr parameters must raise a &ccwl-violation condition", "commands with non-string #:stdout parameters must raise a &ccwl-violation condition"): New tests.
-rw-r--r--ccwl/ccwl.scm20
-rw-r--r--ccwl/cwl.scm6
-rw-r--r--doc/capture-stdout.scm3
-rw-r--r--doc/ccwl.skb18
-rw-r--r--doc/checksum.scm9
-rw-r--r--doc/decompress-compile-run.scm3
-rw-r--r--doc/spell-check.scm3
-rw-r--r--tests/ccwl.scm24
8 files changed, 68 insertions, 18 deletions
diff --git a/ccwl/ccwl.scm b/ccwl/ccwl.scm
index f64830c..05cb6e6 100644
--- a/ccwl/ccwl.scm
+++ b/ccwl/ccwl.scm
@@ -42,6 +42,8 @@
command-outputs
command-args
command-stdin
+ command-stderr
+ command-stdout
command-other
cwl-workflow?
cwl-workflow
@@ -186,12 +188,14 @@
(_ (error "Invalid output:" (syntax->datum output-spec)))))
(define-immutable-record-type <command>
- (make-command inputs outputs args stdin other)
+ (make-command inputs outputs args stdin stderr stdout other)
command?
(inputs command-inputs set-command-inputs)
(outputs command-outputs)
(args command-args)
(stdin command-stdin)
+ (stderr command-stderr)
+ (stdout command-stdout)
(other command-other))
(define-immutable-record-type <cwl-workflow>
@@ -300,7 +304,7 @@ RUN-ARGS. If such an input is not present in RUN-ARGS, return #f."
(condition (ccwl-violation extra)
(formatted-message "Unexpected extra positional argument ~a in command definition"
(syntax->datum extra))))))))
- (apply (syntax-lambda** (#:key stdin #:key* inputs outputs run other)
+ (apply (syntax-lambda** (#:key stdin stderr stdout #:key* inputs outputs run other)
(when (null? run)
(raise-exception
(condition (ccwl-violation x)
@@ -332,6 +336,18 @@ RUN-ARGS. If such an input is not present in RUN-ARGS, return #f."
(syntax->datum x)))))
run))
#,(and stdin #`'#,stdin)
+ #,(if (and stderr
+ (not (string? (syntax->datum stderr))))
+ (raise-exception
+ (condition (ccwl-violation stderr)
+ (formatted-message "#:stderr parameter must be a string")))
+ stderr)
+ #,(if (and stdout
+ (not (string? (syntax->datum stdout))))
+ (raise-exception
+ (condition (ccwl-violation stdout)
+ (formatted-message "#:stdout parameter must be a string")))
+ stdout)
(list #,@other)))
#'(args ...)))))))
diff --git a/ccwl/cwl.scm b/ccwl/cwl.scm
index 4c4fef0..30a6cb9 100644
--- a/ccwl/cwl.scm
+++ b/ccwl/cwl.scm
@@ -146,4 +146,10 @@ CWL YAML specification."
(symbol->string
(command-stdin command))
".path)")))
+ '())
+ ,@(if (command-stderr command)
+ `((stderr . ,(command-stderr command)))
+ '())
+ ,@(if (command-stdout command)
+ `((stdout . ,(command-stdout command)))
'())))
diff --git a/doc/capture-stdout.scm b/doc/capture-stdout.scm
index b9b6774..9eb19ca 100644
--- a/doc/capture-stdout.scm
+++ b/doc/capture-stdout.scm
@@ -1,7 +1,8 @@
(define print
(command #:inputs (message #:type string)
#:run "echo" message
- #:outputs (printed-message #:type stdout)))
+ #:outputs (printed-message #:type stdout)
+ #:stdout "printed-message-output.txt"))
(workflow ((message #:type string))
(print #:message message))
diff --git a/doc/ccwl.skb b/doc/ccwl.skb
index e910452..39116ee 100644
--- a/doc/ccwl.skb
+++ b/doc/ccwl.skb
@@ -1,5 +1,5 @@
;;; ccwl --- Concise Common Workflow Language
-;;; Copyright © 2021 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2021, 2023 Arun Isaac <arunisaac@systemreboot.net>
;;;
;;; This file is part of ccwl.
;;;
@@ -116,8 +116,9 @@ as follows. The expected output is also shown.])
(p [Let us return to the ,(emph "Hello World") example in the
previous section. But now, let us capture the standard output of the
,(code "print") command in an output object. The ccwl code is the same
-as earlier with only the addition of an ,(code "stdout") type output
-object to the command definition.])
+as earlier with the addition of an ,(code "stdout") type output object
+and an ,(code "#:stdout") parameter specifying the name of the file to
+capture standard output in.])
(scheme-source "doc/capture-stdout.scm")
@@ -126,7 +127,7 @@ object to the command definition.])
,(file "capture-stdout.cwl"), and run it using ,(code "cwltool"). We
might expect something like the output below. Notice how the standard
output of the ,(code "print") command has been captured in the file
-,(file "51fe79d15e7790a9ded795304220d7a44aa84b48").])
+,(file "printed-message-output.txt").])
(prog :line #f (source :file "doc/capture-stdout.out")))
@@ -220,8 +221,7 @@ following output.])
(prog :line #f (source :file "doc/decompress-compile-run.out"))
(p [The steps run in succession, and the stdout of the
-compiled executable is in
-,(file "c32c587f7afbdf87cf991c14a43edecf09cd93bf"). Success!]))
+compiled executable is in ,(file "run-output.txt"). Success!]))
(subsection :title [tee]
(p [Next, the tee topology. The following workflow computes
@@ -245,10 +245,8 @@ following output.])
(prog :line #f (source :file "doc/checksum.out"))
- (p [The MD5, SHA1 and SHA256 checksums are in the files
-,(file "112be1054505027982e64d56b0879049c12737c6"),
-,(file "d2f19c786fcd3feb329004c8747803fba581a02d") and
-,(file "0d2eaa5619c14b43326101200d0f27b0d8a1a4b1") respectively.])))
+ (p [The MD5, SHA1 and SHA256 checksums are in the files ,(file
+"md5"), ,(file "sha1") and ,(file "sha256") respectively.])))
(section :title [Let's write a spell check workflow]
(p [Finally, let's put together a complex workflow to understand
diff --git a/doc/checksum.scm b/doc/checksum.scm
index 297ac14..9474964 100644
--- a/doc/checksum.scm
+++ b/doc/checksum.scm
@@ -1,17 +1,20 @@
(define md5sum
(command #:inputs (file #:type File)
#:run "md5sum" file
- #:outputs (md5 #:type stdout)))
+ #:outputs (md5 #:type stdout)
+ #:stdout "md5"))
(define sha1sum
(command #:inputs (file #:type File)
#:run "sha1sum" file
- #:outputs (sha1 #:type stdout)))
+ #:outputs (sha1 #:type stdout)
+ #:stdout "sha1"))
(define sha256sum
(command #:inputs (file #:type File)
#:run "sha256sum" file
- #:outputs (sha256 #:type stdout)))
+ #:outputs (sha256 #:type stdout)
+ #:stdout "sha256"))
(workflow ((file #:type File))
(tee (md5sum #:file file)
diff --git a/doc/decompress-compile-run.scm b/doc/decompress-compile-run.scm
index 00ad392..3513fd6 100644
--- a/doc/decompress-compile-run.scm
+++ b/doc/decompress-compile-run.scm
@@ -13,7 +13,8 @@
(define run
(command #:inputs executable
#:run executable
- #:outputs (stdout #:type stdout)))
+ #:outputs (stdout #:type stdout)
+ #:stdout "run-output.txt"))
(workflow ((compressed-source #:type File))
(pipe (decompress #:compressed compressed-source)
diff --git a/doc/spell-check.scm b/doc/spell-check.scm
index 1f05154..d5ccebb 100644
--- a/doc/spell-check.scm
+++ b/doc/spell-check.scm
@@ -19,7 +19,8 @@
(define find-misspellings
(command #:inputs words dictionary
#:run "comm" "-23" words dictionary
- #:outputs (misspellings #:type stdout)))
+ #:outputs (misspellings #:type stdout)
+ #:stdout "misspelt-words"))
(workflow (text-file dictionary)
(pipe (tee (pipe (split-words #:text text-file)
diff --git a/tests/ccwl.scm b/tests/ccwl.scm
index 76bcecd..e7a0cb7 100644
--- a/tests/ccwl.scm
+++ b/tests/ccwl.scm
@@ -197,4 +197,28 @@
(print (print2) #:message message2)))
#f)))
+(test-assert "commands with non-string #:stderr parameters must raise a &ccwl-violation condition"
+ (guard (exception
+ (else (and (ccwl-violation? exception)
+ (string=? (formatted-message-format exception)
+ "#:stderr parameter must be a string"))))
+ (begin (macroexpand
+ '(command #:inputs (message #:type string)
+ #:run "echo" message
+ #:outputs (printed #:type stderr)
+ #:stderr captured-stderr))
+ #f)))
+
+(test-assert "commands with non-string #:stdout parameters must raise a &ccwl-violation condition"
+ (guard (exception
+ (else (and (ccwl-violation? exception)
+ (string=? (formatted-message-format exception)
+ "#:stdout parameter must be a string"))))
+ (begin (macroexpand
+ '(command #:inputs (message #:type string)
+ #:run "echo" message
+ #:outputs (printed #:type stdout)
+ #:stdout captured-stdout))
+ #f)))
+
(test-end "ccwl")