unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH] build: Improve information density and appearance of download progress output.
@ 2015-09-05 18:48 Steve Sprang
  2015-09-05 19:03 ` Thompson, David
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Steve Sprang @ 2015-09-05 18:48 UTC (permalink / raw)
  To: guix-devel


[-- Attachment #1.1: Type: text/plain, Size: 621 bytes --]

This patch adds Arch/pacman style output when invoking 'guix download'.

Previous output:
$ guix download ftp://ftp.gnu.org/gnu/guile/guile-2.0.11.tar.gz
starting download of `/tmp/guix-file.IgqbP2' from `
ftp://ftp.gnu.org/gnu/guile/guile-2.0.11.tar.gz'...
ftp://ftp.gnu.org/.../guile-2.0.11.tar.gz     29.6% of 7339.9 KiB (781.
KiB/s)

Patched output:
$ guix download ftp://ftp.gnu.org/gnu/guile/guile-2.0.11.tar.gz
starting download of `/tmp/guix-file.ULgbny' from `
ftp://ftp.gnu.org/gnu/guile/guile-2.0.11.tar.gz'...
 guile-2.0.11.tar.gz  7.2MiB               1.1MiB/s 00:00:02
[#######             ]  36.6%

-Steve

[-- Attachment #1.2: Type: text/html, Size: 1087 bytes --]

[-- Attachment #2: progress-bar.patch --]
[-- Type: text/x-patch, Size: 6241 bytes --]

From 21f9829fab68e4660b19b651154f3c873b4d595e Mon Sep 17 00:00:00 2001
From: Steve Sprang <scs@stevesprang.com>
Date: Sat, 5 Sep 2015 11:32:39 -0700
Subject: [PATCH] build: Improve information density and appearance of download
 progress output.

* guix/build/download.scm (seconds->string): New function.
  (byte-count->string): New function.
  (progress-bar): New function.
  (throughput->string): Remove function.
  (progress-proc): Display base file name, elapsed time, and progress bar.
---
 guix/build/download.scm | 79 +++++++++++++++++++++++++++++++++++++------------
 1 file changed, 60 insertions(+), 19 deletions(-)

diff --git a/guix/build/download.scm b/guix/build/download.scm
index ae59b01..e954963 100644
--- a/guix/build/download.scm
+++ b/guix/build/download.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2015 Steve Sprang <scs@stevesprang.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -54,17 +55,46 @@ object, as an inexact number."
   (+ (time-second duration)
      (/ (time-nanosecond duration) 1e9)))
 
-(define (throughput->string throughput)
-  "Given THROUGHPUT, measured in bytes per second, return a string
-representing it in a human-readable way."
-  (if (> throughput 3e6)
-      (format #f "~,2f MiB/s" (/ throughput (expt 2. 20)))
-      (format #f "~,0f KiB/s" (/ throughput 1024.0))))
+(define (seconds->string duration)
+  "Given DURATION in seconds, return a string representing it in 'hh:mm:ss'
+format."
+  (if (not (number? duration))
+      "00:00:00"
+      (let* ((total-seconds (inexact->exact (round duration)))
+             (extra-seconds (modulo total-seconds 3600))
+             (hours         (quotient total-seconds 3600))
+             (mins          (quotient extra-seconds 60))
+             (secs          (modulo extra-seconds 60)))
+        (format #f "~2,'0d:~2,'0d:~2,'0d" hours mins secs))))
+
+(define (byte-count->string size)
+  "Given SIZE in bytes, return a string representing it in a human-readable
+way."
+  (let ((KiB 1024.)
+        (MiB (expt 1024. 2))
+        (GiB (expt 1024. 3))
+        (TiB (expt 1024. 4)))
+    (cond
+     ((< size KiB) (format #f "~dB" (inexact->exact size)))
+     ((< size MiB) (format #f "~dKiB" (inexact->exact (round (/ size KiB)))))
+     ((< size GiB) (format #f "~,1fMiB" (/ size MiB)))
+     ((< size TiB) (format #f "~,2fGiB" (/ size GiB)))
+     (else         (format #f "~,3fTiB" (/ size TiB))))))
+
+(define* (progress-bar % #:optional (bar-width 20))
+  "Return % as a string representing an ASCII-art progress bar.  The total
+width of the bar is BAR-WIDTH."
+  (let* ((fraction (/ % 100))
+         (filled   (inexact->exact (floor (* fraction bar-width))))
+         (empty    (- bar-width filled)))
+    (format #f "[~a~a]"
+            (make-string filled #\#)
+            (make-string empty #\space))))
 
 (define* (progress-proc file size #:optional (log-port (current-output-port)))
-  "Return a procedure to show the progress of FILE's download, which is
-SIZE byte long.  The returned procedure is suitable for use as an
-argument to `dump-port'.  The progress report is written to LOG-PORT."
+  "Return a procedure to show the progress of FILE's download, which is SIZE
+bytes long.  The returned procedure is suitable for use as an argument to
+`dump-port'.  The progress report is written to LOG-PORT."
   ;; XXX: Because of <http://bugs.gnu.org/19939> this procedure is often not
   ;; called as frequently as we'd like too; this is especially bad with Nginx
   ;; on hydra.gnu.org, which returns whole nars as a single chunk.
@@ -83,14 +113,24 @@ argument to `dump-port'.  The progress report is written to LOG-PORT."
       (if (number? size)
           (lambda (transferred cont)
             (with-elapsed-time elapsed
-              (let ((%          (* 100.0 (/ transferred size)))
-                    (throughput (if elapsed
-                                    (/ transferred elapsed)
-                                    0)))
+              (let* ((%          (* 100.0 (/ transferred size)))
+                     (throughput (if elapsed
+                                     (/ transferred elapsed)
+                                     0))
+                     (left       (format #f " ~a  ~a"
+                                         (basename file)
+                                         (byte-count->string size)))
+                     (right      (format #f "~a/s ~a ~a~6,1f%"
+                                         (byte-count->string throughput)
+                                         (seconds->string elapsed)
+                                         (progress-bar %) %))
+                     ;; TODO: Make this adapt to the actual terminal width.
+                     (cols       90)
+                     (num-spaces (max 1 (- cols (+ (string-length left)
+                                                   (string-length right)))))
+                     (gap        (make-string num-spaces #\space)))
                 (display #\cr log-port)
-                (format log-port "~a\t~5,1f% of ~,1f KiB (~a)"
-                        file % (/ size 1024.0)
-                        (throughput->string throughput))
+                (format log-port "~a~a~a" left gap right)
                 (flush-output-port log-port)
                 (cont))))
           (lambda (transferred cont)
@@ -99,9 +139,10 @@ argument to `dump-port'.  The progress report is written to LOG-PORT."
                                     (/ transferred elapsed)
                                     0)))
                 (display #\cr log-port)
-                (format log-port "~a\t~6,1f KiB transferred (~a)"
-                        file (/ transferred 1024.0)
-                        (throughput->string throughput))
+                (format log-port "~a\t~a transferred (~a/s)"
+                        file
+                        (byte-count->string transferred)
+                        (byte-count->string throughput))
                 (flush-output-port log-port)
                 (cont))))))))
 
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] build: Improve information density and appearance of download progress output.
  2015-09-05 18:48 [PATCH] build: Improve information density and appearance of download progress output Steve Sprang
@ 2015-09-05 19:03 ` Thompson, David
  2015-09-05 20:41 ` Taylan Ulrich Bayırlı/Kammer
  2015-09-08 19:57 ` Ludovic Courtès
  2 siblings, 0 replies; 4+ messages in thread
From: Thompson, David @ 2015-09-05 19:03 UTC (permalink / raw)
  To: Steve Sprang; +Cc: guix-devel

On Sat, Sep 5, 2015 at 2:48 PM, Steve Sprang <steve.sprang@gmail.com> wrote:
> This patch adds Arch/pacman style output when invoking 'guix download'.

I like it!

- Dave

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] build: Improve information density and appearance of download progress output.
  2015-09-05 18:48 [PATCH] build: Improve information density and appearance of download progress output Steve Sprang
  2015-09-05 19:03 ` Thompson, David
@ 2015-09-05 20:41 ` Taylan Ulrich Bayırlı/Kammer
  2015-09-08 19:57 ` Ludovic Courtès
  2 siblings, 0 replies; 4+ messages in thread
From: Taylan Ulrich Bayırlı/Kammer @ 2015-09-05 20:41 UTC (permalink / raw)
  To: Steve Sprang; +Cc: guix-devel

Steve Sprang <steve.sprang@gmail.com> writes:

> This patch adds Arch/pacman style output when invoking 'guix
> download'.
>
> Previous output:
> $ guix download ftp://ftp.gnu.org/gnu/guile/guile-2.0.11.tar.gz
> starting download of `/tmp/guix-file.IgqbP2' from
> `ftp://ftp.gnu.org/gnu/guile/guile-2.0.11.tar.gz'...
> ftp://ftp.gnu.org/.../guile-2.0.11.tar.gz 29.6% of 7339.9 KiB (781.
> KiB/s)
>
> Patched output:
> $ guix download ftp://ftp.gnu.org/gnu/guile/guile-2.0.11.tar.gz
> starting download of `/tmp/guix-file.ULgbny' from
> `ftp://ftp.gnu.org/gnu/guile/guile-2.0.11.tar.gz'...
> guile-2.0.11.tar.gz 7.2MiB 1.1MiB/s 00:00:02 [####### ] 36.6%
>
> -Steve

Neat.  Please make sure it's compatible with dumb (non-)terminals like
M-x shell in Emacs though.

Taylan

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] build: Improve information density and appearance of download progress output.
  2015-09-05 18:48 [PATCH] build: Improve information density and appearance of download progress output Steve Sprang
  2015-09-05 19:03 ` Thompson, David
  2015-09-05 20:41 ` Taylan Ulrich Bayırlı/Kammer
@ 2015-09-08 19:57 ` Ludovic Courtès
  2 siblings, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2015-09-08 19:57 UTC (permalink / raw)
  To: Steve Sprang; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 669 bytes --]

Steve Sprang <steve.sprang@gmail.com> skribis:

> From 21f9829fab68e4660b19b651154f3c873b4d595e Mon Sep 17 00:00:00 2001
> From: Steve Sprang <scs@stevesprang.com>
> Date: Sat, 5 Sep 2015 11:32:39 -0700
> Subject: [PATCH] build: Improve information density and appearance of download
>  progress output.
>
> * guix/build/download.scm (seconds->string): New function.
>   (byte-count->string): New function.
>   (progress-bar): New function.
>   (throughput->string): Remove function.
>   (progress-proc): Display base file name, elapsed time, and progress bar.

Neat!  I took the freedom to apply it with this change (let me know if
you think this was inappropriate):


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 1005 bytes --]

diff --git a/guix/build/download.scm b/guix/build/download.scm
index e954963..6e85174 100644
--- a/guix/build/download.scm
+++ b/guix/build/download.scm
@@ -125,12 +125,12 @@ bytes long.  The returned procedure is suitable for use as an argument to
                                          (seconds->string elapsed)
                                          (progress-bar %) %))
                      ;; TODO: Make this adapt to the actual terminal width.
-                     (cols       90)
+                     (cols       80)
                      (num-spaces (max 1 (- cols (+ (string-length left)
                                                    (string-length right)))))
                      (gap        (make-string num-spaces #\space)))
-                (display #\cr log-port)
                 (format log-port "~a~a~a" left gap right)
+                (display #\cr log-port)
                 (flush-output-port log-port)
                 (cont))))
           (lambda (transferred cont)

[-- Attachment #3: Type: text/plain, Size: 623 bytes --]


Emitting the carriage return right before flushing the port is necessary
to avoid flickering when running commands such as:

  guix build -S coreutils --no-substitutes

because the daemon sends input to ‘guix build’ only upon CR/LF (see
‘LocalStore::getLineFromSubstituter’), and in turn the client flushes
only upon CR/LF (see ‘process-stderr’ in (guix store).)

Regarding the column number, we could use the TIOCGWINSZ ioctl via (guix
build syscalls), though that would only work for ‘guix download’ and not
for downloads performed by the daemon on behalf of clients.

Thanks!

Ludo’.

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-09-08 20:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-05 18:48 [PATCH] build: Improve information density and appearance of download progress output Steve Sprang
2015-09-05 19:03 ` Thompson, David
2015-09-05 20:41 ` Taylan Ulrich Bayırlı/Kammer
2015-09-08 19:57 ` Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).