about summary refs log tree commit diff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/magrathea/mg.scm69
1 files changed, 56 insertions, 13 deletions
diff --git a/tools/magrathea/mg.scm b/tools/magrathea/mg.scm
index a453da2ccd28..cbbcfc69dd57 100644
--- a/tools/magrathea/mg.scm
+++ b/tools/magrathea/mg.scm
@@ -215,22 +215,65 @@ USAGE
          [('error . message) (mg-error message)]
          [_ value]))
 
-(define (execute-build t)
-  (let ((expr (nix-expr-for t)))
-    (fprintf (current-error-port) "[mg] building target ~A~%" t)
-    (process-execute "nix-build" (list "-E" expr "--show-trace"))))
-
-(define (build args)
+(define-record build-args target passthru unknown)
+(define (execute-build args)
+  (let ((expr (nix-expr-for (build-args-target args))))
+    (fprintf (current-error-port) "[mg] building target ~A~%" (build-args-target args))
+    (process-execute "nix-build" (append (list "-E" expr "--show-trace")
+                                         (or (build-args-passthru args) '())))))
+
+;; split the arguments used for builds into target/unknown args/nix
+;; args, where the latter occur after '--'
+(define (parse-build-args acc args)
   (match args
-         ;; simplest case: plain mg build with no target spec -> build
-         ;; the current folder's main target.
-         [() (execute-build (empty-target))]
+         ;; no arguments remaining, return accumulator as is
+         [() acc]
+
+         ;; next argument is '--' separator, split off passthru and
+         ;; return
+         [("--" . passthru)
+          (begin
+            (build-args-passthru-set! acc passthru)
+            acc)]
+
+         [(arg . rest)
+          ;; set target if not already known (and if the first
+          ;; argument does not look like an accidental unknown
+          ;; parameter)
+          (if (and (not (build-args-target acc))
+                   (not (substring=? "-" arg)))
+              (begin
+                (build-args-target-set! acc (guarantee-success (parse-target arg)))
+                (parse-build-args acc rest))
+
+              ;; otherwise, collect unknown arguments
+              (begin
+                (build-args-unknown-set! acc (append (or (build-args-unknown acc) '())
+                                                     (list arg)))
+                (parse-build-args acc rest)))]))
+
+;; parse the passed build args, applying sanity checks and defaulting
+;; the target if necessary, then execute the build
+(define (build args)
+  (let ((parsed (parse-build-args (make-build-args #f #f #f) args)))
+    ;; fail if there are unknown arguments present
+    (when (build-args-unknown parsed)
+      (let ((unknown (string-intersperse (build-args-unknown parsed))))
+        (mg-error (sprintf "unknown arguments: ~a
 
-         ;; single argument should be a target spec
-         [(arg) (execute-build
-                 (guarantee-success (parse-target arg)))]
+if you meant to pass these arguments to nix, please separate them with
+'--' like so:
 
-         [other (print "not yet implemented")]))
+  mg build ~a -- ~a"
+                        unknown
+                        (or (build-args-target parsed) "")
+                        unknown))))
+
+    ;; default the target to the current folder's main target
+    (unless (build-args-target parsed)
+      (build-args-target-set! parsed (empty-target)))
+
+    (execute-build parsed)))
 
 (define (execute-shell t)
   (let ((expr (nix-expr-for t))