aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ravanan/command-line-tool.scm24
1 files changed, 23 insertions, 1 deletions
diff --git a/ravanan/command-line-tool.scm b/ravanan/command-line-tool.scm
index 8d1f8ef..1723d96 100644
--- a/ravanan/command-line-tool.scm
+++ b/ravanan/command-line-tool.scm
@@ -533,6 +533,28 @@ The returned G-expression will reference an @code{inputs-directory} variable."
(list id (copy-input-files input))))
inputs)))
+(define (canonicalize-json tree)
+ "Canonicalize JSON @var{tree} by recursively sorting objects in lexicographic
+order of keys."
+ ;; We need to canonicalize JSON trees before inserting them into
+ ;; G-expressions. If we don't, we would have degenerate G-expressions that
+ ;; produce exactly the same result.
+ (cond
+ ;; Sort objects by lexicographic order of keys, and recurse.
+ ((list? tree)
+ (sort (map (match-lambda
+ ((key . value)
+ (cons key (canonicalize-json value))))
+ tree)
+ (match-lambda*
+ (((key1 . _) (key2 . _))
+ (string< key1 key2)))))
+ ;; Do not rearrange arrays. Just recurse.
+ ((vector? tree)
+ (vector-map canonicalize-json tree))
+ ;; Atoms
+ (else tree)))
+
(define (build-command-line-tool-script name manifest cwl inputs
scratch store guix-daemon-socket)
"Build and return script to run @code{CommandLineTool} class workflow @var{cwl}
@@ -883,7 +905,7 @@ directory of the workflow."
(call-with-temporary-directory
(lambda (inputs-directory)
- (let ((inputs #$(copy-input-files-gexp inputs))
+ (let ((inputs #$(copy-input-files-gexp (canonicalize-json inputs)))
(runtime `(("cores" . ,(total-processor-count)))))
;; Set environment defined by workflow.