gnu: emacs-org: Update to 9.4.
[jackhill/guix/guix.git] / guix / status.scm
index c3c2192..f40d5d5 100644 (file)
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -20,7 +20,7 @@
 (define-module (guix status)
   #:use-module (guix records)
   #:use-module (guix i18n)
-  #:use-module ((guix ui) #:select (colorize-string))
+  #:use-module (guix colors)
   #:use-module (guix progress)
   #:autoload   (guix build syscalls) (terminal-columns)
   #:use-module ((guix build download)
@@ -339,60 +339,25 @@ build-log\" traces."
   (and (current-store-protocol-version)
        (>= (current-store-protocol-version) #x163)))
 
-(define isatty?*
-  (mlambdaq (port)
-    (isatty? port)))
-
 (define spin!
   (let ((steps (circular-list "\\" "|" "/" "-")))
-    (lambda (port)
-      "Display a spinner on PORT."
+    (lambda (phase port)
+      "Display a spinner on PORT.  If PHASE is true, display it as a hint of
+the current build phase."
       (when (isatty?* port)
         (match steps
           ((first . rest)
            (set! steps rest)
            (display "\r\x1b[K" port)
            (display first port)
+           (when phase
+             (display " " port)
+             ;; TRANSLATORS: The word "phase" here denotes a "build phase";
+             ;; "~a" is a placeholder for the untranslated name of the current
+             ;; build phase--e.g., 'configure' or 'build'.
+             (format port (G_ "'~a' phase") phase))
            (force-output port)))))))
 
-(define (color-output? port)
-  "Return true if we should write colored output to PORT."
-  (and (not (getenv "INSIDE_EMACS"))
-       (not (getenv "NO_COLOR"))
-       (isatty?* port)))
-
-(define-syntax color-rules
-  (syntax-rules ()
-    "Return a procedure that colorizes the string it is passed according to
-the given rules.  Each rule has the form:
-
-  (REGEXP COLOR1 COLOR2 ...)
-
-where COLOR1 specifies how to colorize the first submatch of REGEXP, and so
-on."
-    ((_ (regexp colors ...) rest ...)
-     (let ((next (color-rules rest ...))
-           (rx   (make-regexp regexp)))
-       (lambda (str)
-         (if (string-index str #\nul)
-             str
-             (match (regexp-exec rx str)
-               (#f (next str))
-               (m  (let loop ((n 1)
-                              (c '(colors ...))
-                              (result '()))
-                     (match c
-                       (()
-                        (string-concatenate-reverse result))
-                       ((first . tail)
-                        (loop (+ n 1) tail
-                              (cons (colorize-string (match:substring m n)
-                                                     first)
-                                    result)))))))))))
-    ((_)
-     (lambda (str)
-       str))))
-
 (define colorize-log-line
   ;; Take a string and return a possibly colorized string according to the
   ;; rules below.
@@ -445,25 +410,31 @@ produce colorful output.  When PRINT-LOG? is true, display the build log in
 addition to build events."
   (define info
     (if colorize?
-        (cut colorize-string <> 'BOLD)
+        (cute colorize-string <> (color BOLD))
         identity))
 
   (define success
     (if colorize?
-        (cut colorize-string <> 'GREEN 'BOLD)
+        (cute colorize-string <> (color GREEN BOLD))
         identity))
 
   (define failure
     (if colorize?
-        (cut colorize-string <> 'RED 'BOLD)
+        (cute colorize-string <> (color RED BOLD))
         identity))
 
-  (define (report-build-progress %)
+  (define (report-build-progress phase %)
     (let ((% (min (max % 0) 100)))                ;sanitize
       (erase-current-line port)
-      (format port "~3d% " (inexact->exact (round %)))
-      (display (progress-bar % (- (current-terminal-columns) 5))
-               port)
+      (let* ((prefix (format #f "~3d% ~@['~a' ~]"
+                            (inexact->exact (round %))
+                            (case phase
+                              ((build) #f)        ;not useful to display it
+                              (else phase))))
+             (length (string-length prefix)))
+        (display prefix port)
+        (display (progress-bar % (- (current-terminal-columns) length))
+                 port))
       (force-output port)))
 
   (define print-log-line
@@ -477,22 +448,23 @@ addition to build events."
           (match (build-status-building status)
             ((build)                              ;single job
              (match (build-completion build)
-               ((? number? %) (report-build-progress %))
-               (_ (spin! port))))
+               ((? number? %)
+                (report-build-progress (build-phase build) %))
+               (_
+                (spin! (build-phase build) port))))
             (_
-             (spin! port))))))
+             (spin! #f port))))))
 
   (define erase-current-line*
-    (if (isatty?* port)
-        (lambda (port)
+    (if (and (not print-log?) (isatty?* port))
+        (lambda ()
           (erase-current-line port)
           (force-output port))
         (const #t)))
 
-  (unless print-log?
-    (erase-current-line* port))             ;clear the spinner or progress bar
   (match event
     (('build-started drv . _)
+     (erase-current-line*)
      (let ((properties (derivation-properties
                         (read-derivation-from-file drv))))
        (match (assq-ref properties 'type)
@@ -500,10 +472,18 @@ addition to build events."
            (let ((count (match (assq-ref properties 'graft)
                           (#f  0)
                           (lst (or (assq-ref lst 'count) 0)))))
-             (format port (info (N_ "applying ~a graft for ~a..."
-                                    "applying ~a grafts for ~a..."
+             (format port (info (N_ "applying ~a graft for ~a ..."
+                                    "applying ~a grafts for ~a ..."
                                     count))
                      count drv)))
+         ('profile
+          (let ((count (match (assq-ref properties 'profile)
+                         (#f  0)
+                         (lst (or (assq-ref lst 'count) 0)))))
+            (format port (info (N_ "building profile with ~a package..."
+                                   "building profile with ~a packages..."
+                                   count))
+                    count)))
          ('profile-hook
           (let ((hook-type (assq-ref properties 'hook)))
             (or (and=> (hook-message hook-type)
@@ -515,6 +495,7 @@ addition to build events."
           (format port (info (G_ "building ~a...")) drv))))
      (newline port))
     (('build-succeeded drv . _)
+     (erase-current-line*)                      ;erase spinner or progress bar
      (when (or print-log? (not (extended-build-trace-supported?)))
        (format port (success (G_ "successfully built ~a")) drv)
        (newline port))
@@ -527,6 +508,7 @@ addition to build events."
                     (length ongoing))
                 (map build-derivation ongoing)))))
     (('build-failed drv . _)
+     (erase-current-line*)                      ;erase spinner or progress bar
      (format port (failure (G_ "build of ~a failed")) drv)
      (newline port)
      (match (derivation-log-file drv)
@@ -537,11 +519,13 @@ addition to build events."
         (format port (info (G_ "View build log at '~a'.")) log)))
      (newline port))
     (('substituter-started item _ ...)
+     (erase-current-line*)
      (when (or print-log? (not (extended-build-trace-supported?)))
        (format port (info (G_ "substituting ~a...")) item)
        (newline port)))
     (('download-started item uri _ ...)
-     (format port (info (G_ "downloading from ~a...")) uri)
+     (erase-current-line*)
+     (format port (info (G_ "downloading from ~a ...")) uri)
      (newline port))
     (('download-progress item uri
                          (= string->number size)