Commit 38f26d9f3aae17e52819d8244d1606ab64edd73b

Thomas de Grivel 2014-11-03T10:27:49

Improve shell logging and debug messages.

diff --git a/shell/sb-shell.lisp b/shell/sb-shell.lisp
index f380bfa..d999510 100644
--- a/shell/sb-shell.lisp
+++ b/shell/sb-shell.lisp
@@ -1,7 +1,7 @@
 ;;
 ;;  adams  -  Remote system administration tools
 ;;
-;;  Copyright 2013 Thomas de Grivel <billitch@gmail.com>
+;;  Copyright 2013,2014 Thomas de Grivel <thomas@lowh.net>
 ;;
 ;;  Permission to use, copy, modify, and distribute this software for any
 ;;  purpose with or without fee is hereby granted, provided that the above
@@ -68,9 +68,8 @@
 	(sb-ext:process-close process)))))
 
 (defmethod shell-in :after (data (shell sb-shell))
-  (when (find 'sb-shell *debug*)
-    (format *debug-io* "~A" data)
-    (force-output *debug-io*))
+  (when (debug-p :sb-shell)
+    (debug-out "~A" data))
   (force-output (sb-ext:process-input (shell-process shell))))
 
 (defmethod shell-in ((data string)
@@ -80,16 +79,13 @@
 (defmethod shell-out/line ((shell sb-shell))
   (let ((out (read-line (sb-ext:process-output (shell-process shell)) nil nil)))
     (when (and out (debug-p :sb-shell))
-      (format *debug-io* "~A~%" out)
-      (force-output *debug-io*))
+      (debug-out "~A~%" out))
     out))
 
 (defmethod shell-err ((shell sb-shell))
  (let ((err (read-string (sb-ext:process-error (shell-process shell)))))
-   (when (or (find 'shell *debug*)
-	     (find 'sb-shell *debug*))
-     (format *debug-io* "~A" err)
-     (force-output *debug-io*))
+   (when (debug-p (or :sb-shell))
+     (debug-out "~A" err))
    err))
 
 (defmethod shell-err/line ((shell sb-shell))
diff --git a/shell/shell.lisp b/shell/shell.lisp
index b268bca..8245745 100644
--- a/shell/shell.lisp
+++ b/shell/shell.lisp
@@ -1,7 +1,7 @@
 ;;
 ;;  adams  -  Remote system administration tools
 ;;
-;;  Copyright 2013 Thomas de Grivel <billitch@gmail.com>
+;;  Copyright 2013,2014 Thomas de Grivel <thomas@lowh.net>
 ;;
 ;;  Permission to use, copy, modify, and distribute this software for any
 ;;  purpose with or without fee is hereby granted, provided that the above
@@ -18,19 +18,19 @@
 
 (in-package :adams)
 
-(defvar *debug* '(:shell))
 (defvar *default-shell-command* "/bin/sh")
 (defparameter *shell-signal-errors* nil)
 
+(setf (debug-p :shell) t)
+
 ;;  String functions
 
 (defun read-string (stream)
   (with-output-to-string (out)
-    (do ((c #1=(when (listen stream)
-		 (read-char stream))
-	    #1#))
-	((null c))
-      (write-char c out))))
+    (loop for c = (when (listen stream)
+		    (read-char stream))
+       while c
+       do (write-char c out))))
 
 (defun make-random-bytes (length)
   (let ((seq (make-array length :element-type '(unsigned-byte 8))))
@@ -44,6 +44,11 @@
 						 :uri t)
 	  0 length))
 
+(defun debug-out (fmt &rest args)
+  (let ((out *debug-io*))
+    (apply #'format out fmt args)
+    (force-output out)))
+
 ;;  Errors
 
 (define-condition shell-error (error)
@@ -92,7 +97,10 @@ Error: ~S"
 	    :reader shell-command)
    (delimiter :type string
 	      :reader shell-delimiter
-	      :initform (make-delimiter))))
+	      :initform (make-delimiter))
+   (log-stream :initarg :log-stream
+	       :initform t
+	       :reader shell-log-stream)))
 
 (defgeneric shell-pid (shell))
 (defgeneric shell-new-delimiter (shell))
@@ -103,6 +111,20 @@ Error: ~S"
 (defgeneric shell-status (shell))
 (defgeneric shell-close (shell))
 (defgeneric shell-closed-p (shell))
+(defgeneric shell-run-command (command shell))
+(defgeneric shell-log (shell fmt &rest args))
+(defgeneric shell-log-p (shell))
+
+(defmethod shell-log-p ((shell shell))
+  (when (shell-log-stream shell)
+    t))
+
+(defmethod shell-log ((shell shell) (fmt string) &rest args)
+  (let ((log (shell-log-stream shell)))
+    (when log
+      (format log "~D" (shell-pid shell))
+      (apply #'format log fmt args)
+      (force-output log))))
 
 (defmethod shell-status ((shell shell))
   (let* ((delim (make-delimiter))
@@ -116,31 +138,28 @@ Error: ~S"
 			    (and (< len (length line))
 				 (string= delim line :end2 len)))
 			(when line
-			  (when (find 'shell *debug*)
-			    (format *debug-io* "$ ")
-			    (force-output *debug-io*))
+			  (when (debug-p :shell*)
+			    (debug-out "$ "))
 			  (parse-integer line :start len)))
 		     (when prev
-		       (when (find 'shell *debug*)
-			 (format *debug-io* "~A~%" prev)
-			 (force-output *debug-io*))
+		       (when (debug-p :shell*)
+			 (debug-out "~A~%" prev))
 		       (setf (cdr lines-tail) (cons prev nil)
 			     lines-tail (cdr lines-tail)))))
 	   (out (cdr lines-head))
 	   (err (shell-err/line shell)))
-      (when (find :shell *debug*)
+      (when (shell-log-p shell)
 	(dolist (line out)
-	  (format t "~D│ ~A~%" (shell-pid shell) line))
+	  (shell-log shell "│ ~A~%" line))
 	(dolist (line err)
-	  (format t "~D┃ ~A~&" (shell-pid shell) line)))
+	  (shell-log shell "┃ ~A~&" line))
+	(shell-log shell   " ⇒ ~D~%" status))
       (values status out err))))
 
 ;;  Run command
 
-(defgeneric shell-run-command (command shell))
-
 (defmethod shell-run-command ((command string) (shell shell))
-  (when (find :shell *debug*)
+  (when (debug-p :shell)
     (format t "~D╭ $ ~A~%" (shell-pid shell) command))
   (shell-in command shell)
   (shell-status shell))