about summary refs log tree commit diff
path: root/tools/magrathea/mg.scm
diff options
context:
space:
mode:
Diffstat (limited to 'tools/magrathea/mg.scm')
-rw-r--r--tools/magrathea/mg.scm63
1 files changed, 37 insertions, 26 deletions
diff --git a/tools/magrathea/mg.scm b/tools/magrathea/mg.scm
index ab8e5bb77e..0418a94f0f 100644
--- a/tools/magrathea/mg.scm
+++ b/tools/magrathea/mg.scm
@@ -21,6 +21,8 @@
 
 (define usage #<<USAGE
 usage: mg <command> [<target>]
+       mg run [<target>] [-- <arguments>]
+       mg shell [<target>] [<command>]
 
 target:
   a target specification with meaning inside of the repository. can
@@ -173,9 +175,8 @@ USAGE
       (begin
         (set! mg--repository-root
               (or (get-environment-variable "MG_ROOT")
-                  (string-chomp
-                   (call-with-input-pipe "git rev-parse --show-toplevel"
-                                         (lambda (p) (read-string #f p))))))
+                  (call-with-input-pipe "git rev-parse --show-toplevel"
+                                        (lambda (p) (read-chomping p)))))
         mg--repository-root)))
 
 ;; determine the current path relative to the root of the repository
@@ -276,39 +277,47 @@ if you meant to pass these arguments to nix, please separate them with
 
     (execute-build parsed)))
 
-(define (execute-shell t)
-  (let ((expr (nix-expr-for t))
-        (user-shell (or (get-environment-variable "SHELL") "bash")))
-    (fprintf (current-error-port) "[mg] entering shell for ~A~%" t)
+(define (execute-shell target #!optional command)
+  (if command
+      (fprintf (current-error-port) "[mg] executing ~A in shell for ~A~%"
+               command
+               target)
+      (fprintf (current-error-port) "[mg] entering shell for ~A~%" target))
+  (let ((expr (nix-expr-for target))
+        (command (or command
+                     (get-environment-variable "SHELL")
+                     "bash")))
     (process-execute "nix-shell"
-                     (list "-E" expr "--command" user-shell))))
+                     (list "-E" expr "--command" command))))
 
 (define (shell args)
   (match args
          [() (execute-shell (empty-target))]
-         [(arg) (execute-shell
-                 (guarantee-success (parse-target arg)))]
-         [other (print "not yet implemented")]))
+         [(target . args) (apply
+                           execute-shell
+                           (guarantee-success (parse-target target))
+                           args)]))
 
 (define (repl args)
   (process-execute "nix" (append (list "repl" "--show-trace" (repository-root)) args)))
 
+(define (read-chomping pipe)
+  (let ((s (read-string #f pipe)))
+    (if (eq? s #!eof) "" (string-chomp s))))
+
 (define (execute-run t #!optional cmd-args)
   (fprintf (current-error-port) "[mg] building target ~A~%" t)
   (let* ((expr (nix-expr-for t))
-         (out (call-with-input-pipe
-               (apply string-append
-                      ;; TODO(sterni): temporary gc root
-                      (intersperse `("nix-build" "-E" ,(qs expr) "--no-out-link")
-                                   " "))
-               (lambda (p)
-                 (string-chomp (let ((s (read-string #f p)))
-                                 (if (eq? s #!eof) "" s)))))))
-
-    ;; TODO(sterni): can we get the exit code of nix-build somehow?
-    (when (= (string-length out) 0)
-      (mg-error (string-append "Couldn't build target " (format "~A" t)))
-      (exit 1))
+         (out
+          (receive (pipe _ pid)
+              ;; TODO(sterni): temporary gc root
+              (process "nix-build" (list "-E" expr "--no-out-link"))
+            (let ((stdout (read-chomping pipe)))
+              (receive (_ _ status)
+                  (process-wait pid)
+                (when (not (eq? status 0))
+                  (mg-error (format "Couldn't build target ~A" t)))
+                stdout)))))
 
     (fprintf (current-error-port) "[mg] running target ~A~%" t)
     (process-execute
@@ -333,9 +342,11 @@ if you meant to pass these arguments to nix, please separate them with
 (define (run args)
   (match args
          [() (execute-run (empty-target))]
+         [("--" . rest) (execute-run (empty-target) rest)]
+         [(target) (execute-run (guarantee-success (parse-target target)))]
+         [(target . ("--" . rest)) (execute-run (guarantee-success (parse-target target)) rest)]
          ;; TODO(sterni): flag for selecting binary name
-         [other (execute-run (guarantee-success (parse-target (car args)))
-                             (cdr args))]))
+         [_ (mg-error "usage: mg run [<target>] [-- <arguments>] (hint: use \"--\" to separate the `mg run [<target>]` invocation from the arguments you're passing to the built executable)")]))
 
 (define (path args)
   (match args