From 34058597c826b64ceed786bf964322080e8849ab Mon Sep 17 00:00:00 2001
From: Francois-Rene Rideau <tunes@google.com>
Date: Fri, 28 Feb 2014 14:11:45 -0500
Subject: [PATCH] 2.0.0: modify the :OUTPUT and :ERROR-OUTPUT defaults for RUN
 to T. Have RUN/NIL for the no-output variant, RUN/INTERACTIVE for the
 interactive variant.

---
 README             | 18 ++++++++++++++----
 inferior-shell.asd | 24 ++++++++++++------------
 pkgdcl.lisp        |  2 +-
 run.lisp           | 29 ++++++++++++++++++++++-------
 4 files changed, 49 insertions(+), 24 deletions(-)

diff --git a/README b/README
index ce231ed..b85a3b5 100644
--- a/README
+++ b/README
@@ -81,6 +81,7 @@ PRINT-PROCESS-SPEC SPEC &OPTIONAL OUTPUT
 
 *CURRENT-HOST-NAMES*
   a variable, a list of strings, the aliases for the localhost.
+  You may need to initialize it if the defaults don't suffice.
 
 CURRENT-HOST-NAME-P X
   a function, returns true if X is a string member of *CURRENT-HOST-NAMES*
@@ -105,11 +106,12 @@ RUN CMD &KEY ON-ERROR TIME SHOW HOST OUTPUT
   on which to run the command using ssh if
   it's not an alias for localhost as recognized by CURRENT-HOST-NAME-P
   (be sure to have passphraseless  login using ssh-agent).
-  The INPUT, OUTPUT and ERROR-OUTPUT arguments are as for UIOP:RUN-PROGRAM.
+  The INPUT, OUTPUT and ERROR-OUTPUT arguments are as for UIOP:RUN-PROGRAM,
+  except that they default to NIL, T, T respectively instead of NIL, NIL, NIL.
   In particular, OUTPUT is as per UIOP:SLURP-OUTPUT-STREAM one of
-  NIL (default) for no output (redirect to /dev/null),
+  NIL for no output (redirect to /dev/null),
   a stream for itself,
-  T for the current *standard-output*,
+  T (default) for the current *standard-output*,
   :INTERACTIVE for inheriting the parent process's stdout,
   :LINES for returning one result per line,
   :STRING for returning the output as one big string,
@@ -122,14 +124,22 @@ RUN CMD &KEY ON-ERROR TIME SHOW HOST OUTPUT
   On Unix, simple commands on localhost are executed directly, but
   remote commands and pipes are executed by spawning a shell.
 
+RUN/NIL CMD &KEY ON-ERROR TIME SHOW HOST
+  RUN/NIL is a shorthand for RUN with :INPUT :OUTPUT :ERROR-OUTPUT bound to NIL.
+
 RUN/S CMD &KEY ON-ERROR TIME SHOW HOST
-  RUN/S is a shorthand for RUN :OUTPUT 'STRING,
+  RUN/S is a shorthand for RUN with :OUTPUT bound to :STRING,
   returning as a string what the inferior command sent to its standard output.
 
 RUN/SS CMD &KEY ON-ERROR TIME SHOW HOST
   RUN/S is a shorthand for RUN :OUTPUT :STRING/STRIPPED,
   just like a shell's `cmd` or $(cmd) would do.
 
+RUN/INTERACTIVE CMD &KEY ON-ERROR TIME SHOW HOST
+  RUN/INTERACTIVE is a shorthand for RUN with :INPUT :OUTPUT :ERROR-OUTPUT
+  all boud to :INTERACTIVE, so you may run commands that interact with users,
+  inheritting the stdin, stdout and stderr of the current process.
+
 RUN/LINES CMD &KEY ON-ERROR TIME SHOW HOST
   run/lines is a shorthand for RUN :OUTPUT :LINES,
   returning as a list of one string per line (stripped of line-ending)
diff --git a/inferior-shell.asd b/inferior-shell.asd
index 5389f9a..4047202 100644
--- a/inferior-shell.asd
+++ b/inferior-shell.asd
@@ -1,12 +1,13 @@
 ;;; -*- Lisp -*-
 
-(defsystem :inferior-shell
-  :defsystem-depends-on (:asdf #-asdf3 :uiop)
-  :depends-on ((:version #+asdf3 :asdf #-asdf3 :uiop "3.0.3")
-               #+sbcl :sb-posix
-               :alexandria :optima
-               :fare-utils :fare-quasiquote-extras :fare-mop)
+(defsystem "inferior-shell"
   :description "spawn local or remote processes and shell pipes"
+  :version "2.0.0"
+  :defsystem-depends-on (:asdf #-asdf3 "uiop")
+  :depends-on ((:version #+asdf3 "asdf" #-asdf3 "uiop" "3.0.3")
+               #+sbcl "sb-posix"
+               "alexandria" "optima"
+               "fare-utils" "fare-quasiquote-extras" "fare-mop")
   :around-compile "asdf-driver:call-with-safe-io-syntax"
   :components
   ((:file "pkgdcl")
@@ -19,12 +20,11 @@
    #+asdf3
    (:file "run-sbcl" :depends-on ("process-spec" "macros" "run-generic")
           :if-feature (:and :sbcl :sb-thread :unix)))
-  :in-order-to ((test-op (load-op inferior-shell/test)))
-  :perform (test-op :after (o s)
-              ;; ASDF2: can't use uiop:symbol-call
-              (funcall (find-symbol (string :test-suite) :inferior-shell-test))))
+  :in-order-to ((test-op (load-op "inferior-shell/test")))
+  :perform (test-op :after (o s) ;; symbol-call will only work if loaded with ASDF3
+              (symbol-call :inferior-shell-test :test-suite)))
 
-(defsystem :inferior-shell/test
-  :depends-on (:inferior-shell :hu.dwim.stefil)
+(defsystem "inferior-shell/test"
+  :depends-on ("inferior-shell" "hu.dwim.stefil")
   :description "testing inferior-shell"
   :components ((:file "test")))
diff --git a/pkgdcl.lisp b/pkgdcl.lisp
index a4143a2..e0246ca 100644
--- a/pkgdcl.lisp
+++ b/pkgdcl.lisp
@@ -4,7 +4,7 @@
   (:mix :fare-utils :uiop :alexandria)
   (:use :cl :optima :named-readtables :fare-mop)
   (:export
-   #:run #:run/s #:run/ss #:run/lines
+   #:run #:run/nil #:run/s #:run/ss #:run/interactive #:run/lines
    #:simple-command-line-token #:token-string
    #:process-spec #:command-spec #:pipe-spec
    #:or-spec #:and-spec #:progn-spec #:fork-spec
diff --git a/run.lisp b/run.lisp
index 627df2a..379de18 100644
--- a/run.lisp
+++ b/run.lisp
@@ -51,29 +51,44 @@
     (function
      (apply 'run-process-spec (funcall host spec) :host nil keys))))
 
-(defun run (cmd &rest keys
-            &key time show host (on-error (list "Command ~S failed~@[ on ~A~]" cmd host)) &allow-other-keys)
+(defun run/nil (cmd &rest keys
+              &key time show host
+                (on-error (list "Command ~S failed~@[ on ~A~]" cmd host))
+              &allow-other-keys)
+  "run command CMD"
   (labels ((process-time ()
              (if time (time (process-command)) (process-command)))
            (process-command ()
              (handler-bind
                  ((subprocess-error #'(lambda (c) (error-behavior on-error c))))
-               (apply 'run-process-spec cmd
-                      :ignore-error-status nil :host host keys))))
+               (apply 'run-process-spec cmd :ignore-error-status nil :host host keys))))
     (when show
       (format *trace-output* "; ~A~%" (print-process-spec cmd)))
     (process-time)))
 
+(defun run (cmd &rest keys
+            &key on-error time show host (output t op) (error-output t eop) &allow-other-keys)
+  "run command CMD"
+  (apply 'run/nil `(,@(unless op `(:output ,output))
+                  ,@(unless eop `(:error-output ,erroroutput))
+                  ,@keys)))
+
 (defun run/s (cmd &rest keys &key on-error time show host)
   "run command CMD, return its standard output results as a string."
   (declare (ignore on-error time show host))
-  (apply 'run cmd :output 'string keys))
+  (apply 'run/nil cmd :output 'string keys))
 
 (defun run/ss (cmd &rest keys &key on-error time show host)
   "Like run/s, but strips the line ending off the result string;
 very much like `cmd` or $(cmd) at the shell"
   (declare (ignore on-error time show host))
-  (apply 'run cmd :output :string/stripped keys))
+  (apply 'run/nil cmd :output :string/stripped keys))
+
+(defun run/interactive (cmd &rest keys &key on-error time show host)
+  "run command CMD interactively."
+  (declare (ignore on-error time show host))
+  (apply 'run/nil cmd :input :interactive :output :interactive :error-output :interactive keys))
+
 
 (defun slurp-stream-string/stripped (input-stream)
   (stripln (slurp-stream-string input-stream)))
@@ -85,4 +100,4 @@ very much like `cmd` or $(cmd) at the shell"
 (defun run/lines (cmd &rest keys &key on-error time show host)
   "Like run/s, but return a list of lines rather than one string"
   (declare (ignore on-error time show host))
-  (apply 'run cmd :output :lines keys))
+  (apply 'run/nil cmd :output :lines keys))
-- 
GitLab