ui: Improve pager selection logic when less is not installed.
* guix/ui.scm (find-available-pager): New procedure. (call-with-paginated-output-port): Use it. * guix/utils.scm (call-with-environment-variables): Allow clearing of specified environment variables. * tests/ui.scm (make-empty-file, assert-equals-find-available-pager): New procedures. ("find-available-pager, GUIX_PAGER takes precedence") ("find-available-pager, PAGER takes precedence") ("find-available-pager, 'less' takes precedence") ("find-available-pager, 'more' takes precedence") ("find-available-pager, no pager"): New tests. Co-authored-by: Ludovic Courtès <ludo@gnu.org>
parent
a88de093fb
commit
c8803d89fe
14
guix/ui.scm
14
guix/ui.scm
|
@ -17,6 +17,7 @@
|
||||||
;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
|
;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
|
||||||
;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
||||||
;;; Copyright © 2018 Steve Sprang <scs@stevesprang.com>
|
;;; Copyright © 2018 Steve Sprang <scs@stevesprang.com>
|
||||||
|
;;; Copyright © 2022 Taiju HIGASHI <higashi@taiju.info>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -1672,11 +1673,18 @@ return the underlying port. Otherwise return #f."
|
||||||
(_
|
(_
|
||||||
#f)))
|
#f)))
|
||||||
|
|
||||||
|
(define (find-available-pager)
|
||||||
|
"Return the program name of an available pager or the empty string if none is
|
||||||
|
available."
|
||||||
|
(or (getenv "GUIX_PAGER")
|
||||||
|
(getenv "PAGER")
|
||||||
|
(which "less")
|
||||||
|
(which "more")
|
||||||
|
""))
|
||||||
|
|
||||||
(define* (call-with-paginated-output-port proc
|
(define* (call-with-paginated-output-port proc
|
||||||
#:key (less-options "FrX"))
|
#:key (less-options "FrX"))
|
||||||
(let ((pager-command-line (or (getenv "GUIX_PAGER")
|
(let ((pager-command-line (find-available-pager)))
|
||||||
(getenv "PAGER")
|
|
||||||
"less")))
|
|
||||||
;; Setting PAGER to the empty string conventionally disables paging.
|
;; Setting PAGER to the empty string conventionally disables paging.
|
||||||
(if (and (not (string-null? pager-command-line))
|
(if (and (not (string-null? pager-command-line))
|
||||||
(isatty?* (current-output-port)))
|
(isatty?* (current-output-port)))
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
;;; Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
|
;;; Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
|
||||||
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
|
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
|
||||||
;;; Copyright © 2018 Steve Sprang <scs@stevesprang.com>
|
;;; Copyright © 2018 Steve Sprang <scs@stevesprang.com>
|
||||||
|
;;; Copyright © 2022 Taiju HIGASHI <higashi@taiju.info>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -158,6 +159,8 @@
|
||||||
(dynamic-wind
|
(dynamic-wind
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(for-each (match-lambda
|
(for-each (match-lambda
|
||||||
|
((variable #false)
|
||||||
|
(unsetenv variable))
|
||||||
((variable value)
|
((variable value)
|
||||||
(setenv variable value)))
|
(setenv variable value)))
|
||||||
variables))
|
variables))
|
||||||
|
|
68
tests/ui.scm
68
tests/ui.scm
|
@ -1,5 +1,6 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
||||||
|
;;; Copyright © 2022 Taiju HIGASHI <higashi@taiju.info>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
#:use-module (guix derivations)
|
#:use-module (guix derivations)
|
||||||
#:use-module ((gnu packages) #:select (specification->package))
|
#:use-module ((gnu packages) #:select (specification->package))
|
||||||
#:use-module (guix tests)
|
#:use-module (guix tests)
|
||||||
|
#:use-module (guix utils)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-11)
|
#:use-module (srfi srfi-11)
|
||||||
#:use-module (srfi srfi-19)
|
#:use-module (srfi srfi-19)
|
||||||
|
@ -292,4 +294,70 @@ Second line" 24))
|
||||||
(>0 (package-relevance libb2
|
(>0 (package-relevance libb2
|
||||||
(map rx '("crypto" "library")))))))
|
(map rx '("crypto" "library")))))))
|
||||||
|
|
||||||
|
(define (make-empty-file directory file)
|
||||||
|
;; Create FILE in DIRECTORY.
|
||||||
|
(close-port (open-output-file (in-vicinity directory file))))
|
||||||
|
|
||||||
|
(define (assert-equals-find-available-pager expected)
|
||||||
|
;; Use 'with-paginated-output-port' and return true if it invoked EXPECTED.
|
||||||
|
(define used-command "")
|
||||||
|
(mock ((ice-9 popen) open-pipe*
|
||||||
|
(lambda (mode command . args)
|
||||||
|
(unless (string-null? used-command)
|
||||||
|
(error "open-pipe* should only be called once"))
|
||||||
|
(set! used-command command)
|
||||||
|
(%make-void-port "")))
|
||||||
|
(mock ((ice-9 popen) close-pipe (const 'ok))
|
||||||
|
(mock ((guix colors) isatty?* (const #t))
|
||||||
|
(with-paginated-output-port port 'ok)
|
||||||
|
(string=? expected used-command)))))
|
||||||
|
|
||||||
|
|
||||||
|
(test-assert "find-available-pager, GUIX_PAGER takes precedence"
|
||||||
|
(call-with-temporary-directory
|
||||||
|
(lambda (dir)
|
||||||
|
(with-environment-variables `(("PATH" ,dir)
|
||||||
|
("GUIX_PAGER" "guix-pager")
|
||||||
|
("PAGER" "pager"))
|
||||||
|
(make-empty-file dir "less")
|
||||||
|
(make-empty-file dir "more")
|
||||||
|
(assert-equals-find-available-pager "guix-pager")))))
|
||||||
|
|
||||||
|
(test-assert "find-available-pager, PAGER takes precedence"
|
||||||
|
(call-with-temporary-directory
|
||||||
|
(lambda (dir)
|
||||||
|
(with-environment-variables `(("PATH" ,dir)
|
||||||
|
("GUIX_PAGER" #false)
|
||||||
|
("PAGER" "pager"))
|
||||||
|
(make-empty-file dir "less")
|
||||||
|
(make-empty-file dir "more")
|
||||||
|
(assert-equals-find-available-pager "pager")))))
|
||||||
|
|
||||||
|
(test-assert "find-available-pager, 'less' takes precedence"
|
||||||
|
(call-with-temporary-directory
|
||||||
|
(lambda (dir)
|
||||||
|
(with-environment-variables `(("PATH" ,dir)
|
||||||
|
("GUIX_PAGER" #false)
|
||||||
|
("PAGER" #false))
|
||||||
|
(make-empty-file dir "less")
|
||||||
|
(make-empty-file dir "more")
|
||||||
|
(assert-equals-find-available-pager (in-vicinity dir "less"))))))
|
||||||
|
|
||||||
|
(test-assert "find-available-pager, 'more' takes precedence"
|
||||||
|
(call-with-temporary-directory
|
||||||
|
(lambda (dir)
|
||||||
|
(with-environment-variables `(("PATH" ,dir)
|
||||||
|
("GUIX_PAGER" #false)
|
||||||
|
("PAGER" #false))
|
||||||
|
(make-empty-file dir "more")
|
||||||
|
(assert-equals-find-available-pager (in-vicinity dir "more"))))))
|
||||||
|
|
||||||
|
(test-assert "find-available-pager, no pager"
|
||||||
|
(call-with-temporary-directory
|
||||||
|
(lambda (dir)
|
||||||
|
(with-environment-variables `(("PATH" ,dir)
|
||||||
|
("GUIX_PAGER" #false)
|
||||||
|
("PAGER" #false))
|
||||||
|
(assert-equals-find-available-pager "")))))
|
||||||
|
|
||||||
(test-end "ui")
|
(test-end "ui")
|
||||||
|
|
Reference in New Issue