me
/
guix
Archived
1
0
Fork 0

scripts: Use 'define-command' and have 'guix help' use that.

This changes 'guix help' to print a short synopsis for each command and
to group commands by category.

* guix/scripts.scm (synopsis, category): New variables.
(define-command-categories, define-command): New macros.
(%command-categories): New variable.
* guix/ui.scm (<command>): New record type.
(source-file-command): New procedure.
(command-files): Return absolute file names.
(commands): Return a list of <command> records.
(show-guix-help)[display-commands, category-predicate]: New procedures.
Display commands grouped in three categories.
* guix/scripts/archive.scm (guix-archive): Use 'define-command'.
* guix/scripts/authenticate.scm (guix-authenticate): Likewise.
* guix/scripts/build.scm (guix-build): Likewise.
* guix/scripts/challenge.scm (guix-challenge): Likewise.
* guix/scripts/container.scm (guix-container): Likewise.
* guix/scripts/copy.scm (guix-copy): Likewise.
* guix/scripts/deploy.scm (guix-deploy): Likewise.
* guix/scripts/describe.scm (guix-describe): Likewise.
* guix/scripts/download.scm (guix-download): Likewise.
* guix/scripts/edit.scm (guix-edit): Likewise.
* guix/scripts/environment.scm (guix-environment): Likewise.
* guix/scripts/gc.scm (guix-gc): Likewise.
* guix/scripts/git.scm (guix-git): Likewise.
* guix/scripts/graph.scm (guix-graph): Likewise.
* guix/scripts/hash.scm (guix-hash): Likewise.
* guix/scripts/import.scm (guix-import): Likewise.
* guix/scripts/install.scm (guix-install): Likewise.
* guix/scripts/lint.scm (guix-lint): Likewise.
* guix/scripts/offload.scm (guix-offload): Likewise.
* guix/scripts/pack.scm (guix-pack): Likewise.
* guix/scripts/package.scm (guix-package): Likewise.
* guix/scripts/perform-download.scm (guix-perform-download): Likewise.
* guix/scripts/processes.scm (guix-processes): Likewise.
* guix/scripts/publish.scm (guix-publish): Likewise.
* guix/scripts/pull.scm (guix-pull): Likewise.
* guix/scripts/refresh.scm (guix-refresh): Likewise.
* guix/scripts/remove.scm (guix-remove): Likewise.
* guix/scripts/repl.scm (guix-repl): Likewise.
* guix/scripts/search.scm (guix-search): Likewise.
* guix/scripts/show.scm (guix-show): Likewise.
* guix/scripts/size.scm (guix-size): Likewise.
* guix/scripts/substitute.scm (guix-substitute): Likewise.
* guix/scripts/system.scm (guix-system): Likewise.
* guix/scripts/time-machine.scm (guix-time-machine): Likewise.
* guix/scripts/upgrade.scm (guix-upgrade): Likewise.
* guix/scripts/weather.scm (guix-weather): Likewise.
master
Ludovic Courtès 2020-09-01 22:13:11 +02:00
parent 991fdb0d64
commit 3794ce93be
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
38 changed files with 281 additions and 63 deletions

View File

@ -34,7 +34,12 @@
#:use-module (srfi srfi-19) #:use-module (srfi srfi-19)
#:use-module (srfi srfi-37) #:use-module (srfi srfi-37)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:export (args-fold* #:export (synopsis
category
define-command
%command-categories
args-fold*
parse-command-line parse-command-line
maybe-build maybe-build
build-package build-package
@ -50,6 +55,61 @@
;;; ;;;
;;; Code: ;;; Code:
;; Syntactic keywords.
(define synopsis 'command-synopsis)
(define category 'command-category)
(define-syntax define-command-categories
(syntax-rules (G_)
"Define command categories."
((_ name assert-valid (identifiers (G_ synopses)) ...)
(begin
(define-public identifiers
;; Define and export syntactic keywords.
(list 'syntactic-keyword-for-command-category))
...
(define-syntax assert-valid
;; Validate at expansion time that we're passed a valid category.
(syntax-rules (identifiers ...)
((_ identifiers) #t)
...))
(define name
;; Alist mapping category name to synopsis.
`((identifiers . synopses) ...))))))
;; Command categories.
(define-command-categories %command-categories
assert-valid-command-category
(main (G_ "main commands"))
(development (G_ "software development commands"))
(packaging (G_ "packaging commands"))
(plumbing (G_ "plumbing commands"))
(internal (G_ "internal commands")))
(define-syntax define-command
(syntax-rules (category synopsis)
"Define the given command as a procedure along with its synopsis and,
optionally, its category. The synopsis becomes the docstring of the
procedure, but both the category and synopsis are meant to be read (parsed) by
'guix help'."
;; The (synopsis ...) form is here so that xgettext sees those strings as
;; translatable.
((_ (name . args)
(synopsis doc) body ...)
(define (name . args)
doc
body ...))
((_ (name . args)
(category cat) (synopsis doc)
body ...)
(begin
(assert-valid-command-category cat)
(define (name . args)
doc
body ...)))))
(define (args-fold* args options unrecognized-option-proc operand-proc . seeds) (define (args-fold* args options unrecognized-option-proc operand-proc . seeds)
"A wrapper on top of `args-fold' that does proper user-facing error "A wrapper on top of `args-fold' that does proper user-facing error
reporting." reporting."

View File

@ -355,7 +355,10 @@ output port."
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-archive . args) (define-command (guix-archive . args)
(category plumbing)
(synopsis "manipulate, export, and import normalized archives (nars)")
(define (lines port) (define (lines port)
;; Return lines read from PORT. ;; Return lines read from PORT.
(let loop ((line (read-line port)) (let loop ((line (read-line port))

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2020 Ludovic Courtès <ludo@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -18,6 +18,7 @@
(define-module (guix scripts authenticate) (define-module (guix scripts authenticate)
#:use-module (guix config) #:use-module (guix config)
#:use-module (guix scripts)
#:use-module (guix base16) #:use-module (guix base16)
#:use-module (gcrypt pk-crypto) #:use-module (gcrypt pk-crypto)
#:use-module (guix pki) #:use-module (guix pki)
@ -90,7 +91,10 @@ to stdout upon success."
;;; unmodified currently. ;;; unmodified currently.
;;; ;;;
(define (guix-authenticate . args) (define-command (guix-authenticate . args)
(category internal)
(synopsis "sign or verify signatures on normalized archives (nars)")
;; Signature sexps written to stdout may contain binary data, so force ;; Signature sexps written to stdout may contain binary data, so force
;; ISO-8859-1 encoding so that things are not mangled. See ;; ISO-8859-1 encoding so that things are not mangled. See
;; <http://bugs.gnu.org/17312> for details. ;; <http://bugs.gnu.org/17312> for details.

View File

@ -945,7 +945,10 @@ needed."
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-build . args) (define-command (guix-build . args)
(category packaging)
(synopsis "build packages or derivations without installing them")
(define opts (define opts
(parse-command-line args %options (parse-command-line args %options
(list %default-options))) (list %default-options)))

View File

@ -475,7 +475,10 @@ Challenge the substitutes for PACKAGE... provided by one or more servers.\n"))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-challenge . args) (define-command (guix-challenge . args)
(category packaging)
(synopsis "challenge substitute servers, comparing their binaries")
(with-error-handling (with-error-handling
(let* ((opts (parse-command-line args %options (list %default-options) (let* ((opts (parse-command-line args %options (list %default-options)
#:build-options? #f)) #:build-options? #f))

View File

@ -20,6 +20,7 @@
(define-module (guix scripts container) (define-module (guix scripts container)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:use-module (guix ui) #:use-module (guix ui)
#:use-module (guix scripts)
#:export (guix-container)) #:export (guix-container))
(define (show-help) (define (show-help)
@ -46,7 +47,10 @@ Build and manipulate Linux containers.\n"))
(proc (string->symbol (string-append "guix-container-" name)))) (proc (string->symbol (string-append "guix-container-" name))))
(module-ref module proc))) (module-ref module proc)))
(define (guix-container . args) (define-command (guix-container . args)
(category development)
(synopsis "run code in containers created by 'guix environment -C'")
(with-error-handling (with-error-handling
(match args (match args
(() (()

View File

@ -170,7 +170,10 @@ Copy ITEMS to or from the specified host over SSH.\n"))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-copy . args) (define-command (guix-copy . args)
(category plumbing)
(synopsis "copy store items remotely over SSH")
(with-error-handling (with-error-handling
(let* ((opts (parse-command-line args %options (list %default-options))) (let* ((opts (parse-command-line args %options (list %default-options)))
(source (assoc-ref opts 'source)) (source (assoc-ref opts 'source))

View File

@ -136,7 +136,8 @@ Perform the deployment specified by FILE.\n"))
(machine-display-name machine)))) (machine-display-name machine))))
(define (guix-deploy . args) (define-command (guix-deploy . args)
(synopsis "deploy operating systems on a set of machines")
(define (handle-argument arg result) (define (handle-argument arg result)
(alist-cons 'file arg result)) (alist-cons 'file arg result))

View File

@ -304,7 +304,8 @@ text. The hyperlink links to a web view of COMMIT, when available."
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-describe . args) (define-command (guix-describe . args)
(synopsis "describe the channel revisions currently used")
(let* ((opts (args-fold* args %options (let* ((opts (args-fold* args %options
(lambda (opt name arg result) (lambda (opt name arg result)
(leave (G_ "~A: unrecognized option~%") (leave (G_ "~A: unrecognized option~%")

View File

@ -156,7 +156,10 @@ and 'base16' ('hex' and 'hexadecimal' can be used as well).\n"))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-download . args) (define-command (guix-download . args)
(category packaging)
(synopsis "download a file to the store and print its hash")
(define (parse-options) (define (parse-options)
;; Return the alist of option values. ;; Return the alist of option values.
(args-fold* args %options (args-fold* args %options

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015, 2016, 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2015, 2016, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2015 Mathieu Lirzin <mthl@gnu.org> ;;; Copyright © 2015 Mathieu Lirzin <mthl@gnu.org>
;;; Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com> ;;; Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com>
;;; ;;;
@ -78,7 +78,10 @@ line."
(search-path* %load-path (location-file location)))) (search-path* %load-path (location-file location))))
(define (guix-edit . args) (define-command (guix-edit . args)
(category packaging)
(synopsis "view and edit package definitions")
(define (parse-arguments) (define (parse-arguments)
;; Return the list of package names. ;; Return the list of package names.
(args-fold* args %options (args-fold* args %options

View File

@ -678,7 +678,10 @@ message if any test fails."
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-environment . args) (define-command (guix-environment . args)
(category development)
(synopsis "spawn one-off software environments")
(with-error-handling (with-error-handling
(let* ((opts (parse-args args)) (let* ((opts (parse-args args))
(pure? (assoc-ref opts 'pure)) (pure? (assoc-ref opts 'pure))

View File

@ -220,7 +220,9 @@ is deprecated; use '-D'~%"))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-gc . args) (define-command (guix-gc . args)
(synopsis "invoke the garbage collector")
(define (parse-options) (define (parse-options)
;; Return the alist of option values. ;; Return the alist of option values.
(parse-command-line args %options (list %default-options) (parse-command-line args %options (list %default-options)

View File

@ -19,6 +19,7 @@
(define-module (guix scripts git) (define-module (guix scripts git)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:use-module (guix ui) #:use-module (guix ui)
#:use-module (guix scripts)
#:export (guix-git)) #:export (guix-git))
(define (show-help) (define (show-help)
@ -45,7 +46,10 @@ Operate on Git repositories.\n"))
(proc (string->symbol (string-append "guix-git-" name)))) (proc (string->symbol (string-append "guix-git-" name))))
(module-ref module proc))) (module-ref module proc)))
(define (guix-git . args) (define-command (guix-git . args)
(category plumbing)
(synopsis "operate on Git repositories")
(with-error-handling (with-error-handling
(match args (match args
(() (()

View File

@ -565,7 +565,10 @@ Emit a representation of the dependency graph of PACKAGE...\n"))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-graph . args) (define-command (guix-graph . args)
(category packaging)
(synopsis "view and query package dependency graphs")
(with-error-handling (with-error-handling
(define opts (define opts
(parse-command-line args %options (parse-command-line args %options

View File

@ -116,7 +116,10 @@ and 'base16' ('hex' and 'hexadecimal' can be used as well).\n"))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-hash . args) (define-command (guix-hash . args)
(category packaging)
(synopsis "compute the cryptographic hash of a file")
(define (parse-options) (define (parse-options)
;; Return the alist of option values. ;; Return the alist of option values.
(parse-command-line args %options (list %default-options) (parse-command-line args %options (list %default-options)

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2012, 2013, 2014, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2014 David Thompson <davet@gnu.org> ;;; Copyright © 2014 David Thompson <davet@gnu.org>
;;; Copyright © 2018 Kyle Meyer <kyle@kyleam.com> ;;; Copyright © 2018 Kyle Meyer <kyle@kyleam.com>
;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net> ;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
@ -21,6 +21,7 @@
(define-module (guix scripts import) (define-module (guix scripts import)
#:use-module (guix ui) #:use-module (guix ui)
#:use-module (guix scripts)
#:use-module (guix utils) #:use-module (guix utils)
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-11) #:use-module (srfi srfi-11)
@ -98,7 +99,10 @@ Run IMPORTER with ARGS.\n"))
(newline) (newline)
(show-bug-report-information)) (show-bug-report-information))
(define (guix-import . args) (define-command (guix-import . args)
(category packaging)
(synopsis "import a package definition from an external repository")
(match args (match args
(() (()
(format (current-error-port) (format (current-error-port)

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -66,7 +66,9 @@ This is an alias for 'guix package -i'.\n"))
%transformation-options %transformation-options
%standard-build-options))) %standard-build-options)))
(define (guix-install . args) (define-command (guix-install . args)
(synopsis "install packages")
(define (handle-argument arg result arg-handler) (define (handle-argument arg result arg-handler)
;; Treat all non-option arguments as package specs. ;; Treat all non-option arguments as package specs.
(values (alist-cons 'install arg result) (values (alist-cons 'install arg result)

View File

@ -157,7 +157,10 @@ run the checkers on all packages.\n"))
;;; Entry Point ;;; Entry Point
;;; ;;;
(define (guix-lint . args) (define-command (guix-lint . args)
(category packaging)
(synopsis "validate package definitions")
(define (parse-options) (define (parse-options)
;; Return the alist of option values. ;; Return the alist of option values.
(parse-command-line args %options (list %default-options) (parse-command-line args %options (list %default-options)

View File

@ -39,6 +39,7 @@
#:select (fcntl-flock set-thread-name)) #:select (fcntl-flock set-thread-name))
#:use-module ((guix build utils) #:select (which mkdir-p)) #:use-module ((guix build utils) #:select (which mkdir-p))
#:use-module (guix ui) #:use-module (guix ui)
#:use-module (guix scripts)
#:use-module (guix diagnostics) #:use-module (guix diagnostics)
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-11) #:use-module (srfi srfi-11)
@ -725,7 +726,10 @@ machine."
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-offload . args) (define-command (guix-offload . args)
(category plumbing)
(synopsis "set up and operate build offloading")
(define request-line-rx (define request-line-rx
;; The request format. See 'tryBuildHook' method in build.cc. ;; The request format. See 'tryBuildHook' method in build.cc.
(make-regexp "([01]) ([a-z0-9_-]+) (/[[:graph:]]+.drv) ([[:graph:]]*)")) (make-regexp "([01]) ([a-z0-9_-]+) (/[[:graph:]]+.drv) ([[:graph:]]*)"))

View File

@ -1089,7 +1089,10 @@ Create a bundle of PACKAGE.\n"))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-pack . args) (define-command (guix-pack . args)
(category development)
(synopsis "create application bundles")
(define opts (define opts
(parse-command-line args %options (list %default-options))) (parse-command-line args %options (list %default-options)))

View File

@ -941,7 +941,9 @@ processed, #f otherwise."
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-package . args) (define-command (guix-package . args)
(synopsis "manage packages and profiles")
(define (handle-argument arg result arg-handler) (define (handle-argument arg result arg-handler)
;; Process non-option argument ARG by calling back ARG-HANDLER. ;; Process non-option argument ARG by calling back ARG-HANDLER.
(if arg-handler (if arg-handler

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2016, 2017, 2018, 2020 Ludovic Courtès <ludo@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -18,6 +18,7 @@
(define-module (guix scripts perform-download) (define-module (guix scripts perform-download)
#:use-module (guix ui) #:use-module (guix ui)
#:use-module (guix scripts)
#:use-module (guix derivations) #:use-module (guix derivations)
#:use-module ((guix store) #:select (derivation-path? store-path?)) #:use-module ((guix store) #:select (derivation-path? store-path?))
#:use-module (guix build download) #:use-module (guix build download)
@ -91,14 +92,15 @@ actual output is different from that when we're doing a 'bmCheck' or
(leave (G_ "refusing to run with elevated privileges (UID ~a)~%") (leave (G_ "refusing to run with elevated privileges (UID ~a)~%")
(getuid)))) (getuid))))
(define (guix-perform-download . args) (define-command (guix-perform-download . args)
"Perform the download described by the given fixed-output derivation. (category internal)
(synopsis "perform download described by fixed-output derivations")
This is an \"out-of-band\" download in that this code is executed directly by ;; This is an "out-of-band" download in that this code is executed directly
the daemon and not explicitly described as an input of the derivation. This ;; by the daemon and not explicitly described as an input of the derivation.
allows us to sidestep bootstrapping problems, such downloading the source code ;; This allows us to sidestep bootstrapping problems, such as downloading
of GnuTLS over HTTPS, before we have built GnuTLS. See ;; the source code of GnuTLS over HTTPS before we have built GnuTLS. See
<http://bugs.gnu.org/22774>." ;; <https://bugs.gnu.org/22774>.
(define print-build-trace? (define print-build-trace?
(match (getenv "_NIX_OPTIONS") (match (getenv "_NIX_OPTIONS")

View File

@ -223,7 +223,9 @@ List the current Guix sessions and their processes."))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-processes . args) (define-command (guix-processes . args)
(category plumbing)
(synopsis "list currently running sessions")
(define options (define options
(args-fold* args %options (args-fold* args %options
(lambda (opt name arg result) (lambda (opt name arg result)

View File

@ -1013,7 +1013,10 @@ methods, return the applicable compression."
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-publish . args) (define-command (guix-publish . args)
(category packaging)
(synopsis "publish build results over HTTP")
(with-error-handling (with-error-handling
(let* ((opts (args-fold* args %options (let* ((opts (args-fold* args %options
(lambda (opt name arg result) (lambda (opt name arg result)

View File

@ -751,7 +751,9 @@ Use '~/.config/guix/channels.scm' instead."))
channels))) channels)))
(define (guix-pull . args) (define-command (guix-pull . args)
(synopsis "pull the latest revision of Guix")
(with-error-handling (with-error-handling
(with-git-error-handling (with-git-error-handling
(let* ((opts (parse-command-line args %options (let* ((opts (parse-command-line args %options

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org> ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org> ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
;;; Copyright © 2015 Alex Kost <alezost@gmail.com> ;;; Copyright © 2015 Alex Kost <alezost@gmail.com>
@ -496,7 +496,10 @@ all are dependent packages: ~{~a~^ ~}~%")
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-refresh . args) (define-command (guix-refresh . args)
(category packaging)
(synopsis "update existing package definitions")
(define (parse-options) (define (parse-options)
;; Return the alist of option values. ;; Return the alist of option values.
(parse-command-line args %options (list %default-options) (parse-command-line args %options (list %default-options)

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -63,7 +63,9 @@ This is an alias for 'guix package -r'.\n"))
%standard-build-options))) %standard-build-options)))
(define (guix-remove . args) (define-command (guix-remove . args)
(synopsis "remove installed packages")
(define (handle-argument arg result arg-handler) (define (handle-argument arg result arg-handler)
;; Treat all non-option arguments as package specs. ;; Treat all non-option arguments as package specs.
(values (alist-cons 'remove arg result) (values (alist-cons 'remove arg result)

View File

@ -137,7 +137,10 @@ call THUNK."
(loop))))))) (loop)))))))
(define (guix-repl . args) (define-command (guix-repl . args)
(category plumbing)
(synopsis "read-eval-print loop (REPL) for interactive programming")
(define opts (define opts
(args-fold* args %options (args-fold* args %options
(lambda (opt name arg result) (lambda (opt name arg result)

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -57,7 +57,9 @@ This is an alias for 'guix package -s'.\n"))
(member "load-path" (option-names option))) (member "load-path" (option-names option)))
%standard-build-options))) %standard-build-options)))
(define (guix-search . args) (define-command (guix-search . args)
(synopsis "search for packages")
(define (handle-argument arg result) (define (handle-argument arg result)
;; Treat all non-option arguments as regexps. ;; Treat all non-option arguments as regexps.
(cons `(query search ,(or arg "")) (cons `(query search ,(or arg ""))

View File

@ -57,7 +57,9 @@ This is an alias for 'guix package --show='.\n"))
(member "load-path" (option-names option))) (member "load-path" (option-names option)))
%standard-build-options))) %standard-build-options)))
(define (guix-show . args) (define-command (guix-show . args)
(synopsis "show information about packages")
(define (handle-argument arg result) (define (handle-argument arg result)
;; Treat all non-option arguments as regexps. ;; Treat all non-option arguments as regexps.
(cons `(query show ,arg) (cons `(query show ,arg)

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2019 Simon Tournier <zimon.toutoune@gmail.com> ;;; Copyright © 2019 Simon Tournier <zimon.toutoune@gmail.com>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
@ -298,7 +298,10 @@ Report the size of the PACKAGE or STORE-ITEM, with its dependencies.\n"))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-size . args) (define-command (guix-size . args)
(category packaging)
(synopsis "profile the on-disk size of packages")
(with-error-handling (with-error-handling
(let* ((opts (parse-command-line args %options (list %default-options) (let* ((opts (parse-command-line args %options (list %default-options)
#:build-options? #f)) #:build-options? #f))

View File

@ -20,6 +20,7 @@
(define-module (guix scripts substitute) (define-module (guix scripts substitute)
#:use-module (guix ui) #:use-module (guix ui)
#:use-module (guix scripts)
#:use-module (guix store) #:use-module (guix store)
#:use-module (guix utils) #:use-module (guix utils)
#:use-module (guix combinators) #:use-module (guix combinators)
@ -1095,8 +1096,10 @@ default value."
(unless (string->uri uri) (unless (string->uri uri)
(leave (G_ "~a: invalid URI~%") uri))) (leave (G_ "~a: invalid URI~%") uri)))
(define (guix-substitute . args) (define-command (guix-substitute . args)
"Implement the build daemon's substituter protocol." (category internal)
(synopsis "implement the build daemon's substituter protocol")
(define print-build-trace? (define print-build-trace?
(match (or (find-daemon-option "untrusted-print-extended-build-trace") (match (or (find-daemon-option "untrusted-print-extended-build-trace")
(find-daemon-option "print-extended-build-trace")) (find-daemon-option "print-extended-build-trace"))

View File

@ -1253,7 +1253,9 @@ argument list and OPTS is the option alist."
;; need an operating system configuration file. ;; need an operating system configuration file.
(else (process-action command args opts)))) (else (process-action command args opts))))
(define (guix-system . args) (define-command (guix-system . args)
(synopsis "build and deploy full operating systems")
(define (parse-sub-command arg result) (define (parse-sub-command arg result)
;; Parse sub-command ARG and augment RESULT accordingly. ;; Parse sub-command ARG and augment RESULT accordingly.
(if (assoc-ref result 'action) (if (assoc-ref result 'action)

View File

@ -128,7 +128,9 @@ Execute COMMAND ARGS... in an older version of Guix.\n"))
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-time-machine . args) (define-command (guix-time-machine . args)
(synopsis "run commands from a different revision")
(with-error-handling (with-error-handling
(with-git-error-handling (with-git-error-handling
(let* ((opts (parse-args args)) (let* ((opts (parse-args args))

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net> ;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
@ -67,7 +67,9 @@ This is an alias for 'guix package -u'.\n"))
%transformation-options %transformation-options
%standard-build-options))) %standard-build-options)))
(define (guix-upgrade . args) (define-command (guix-upgrade . args)
(synopsis "upgrade packages to their latest version")
(define (handle-argument arg result arg-handler) (define (handle-argument arg result arg-handler)
;; Accept at most one non-option argument, and treat it as an upgrade ;; Accept at most one non-option argument, and treat it as an upgrade
;; regexp. ;; regexp.

View File

@ -495,7 +495,9 @@ SERVER. Display information for packages with at least THRESHOLD dependents."
;;; Entry point. ;;; Entry point.
;;; ;;;
(define (guix-weather . args) (define-command (guix-weather . args)
(synopsis "report on the availability of pre-built package binaries")
(define (package-list opts) (define (package-list opts)
;; Return the package list specified by OPTS. ;; Return the package list specified by OPTS.
(let ((files (filter-map (match-lambda (let ((files (filter-map (match-lambda

View File

@ -60,6 +60,7 @@
;; Avoid "overrides core binding" warning. ;; Avoid "overrides core binding" warning.
delete)) delete))
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-9 gnu)
#:use-module (srfi srfi-11) #:use-module (srfi srfi-11)
#:use-module (srfi srfi-19) #:use-module (srfi srfi-19)
#:use-module (srfi srfi-26) #:use-module (srfi srfi-26)
@ -1993,6 +1994,44 @@ optionally contain a version number and an output name, as in these examples:
(G_ "Try `guix --help' for more information.~%")) (G_ "Try `guix --help' for more information.~%"))
(exit 1)) (exit 1))
;; Representation of a 'guix' command.
(define-immutable-record-type <command>
(command name synopsis category)
command?
(name command-name)
(synopsis command-synopsis)
(category command-category))
(define (source-file-command file)
"Read FILE, a Scheme source file, and return either a <command> object based
on the 'define-command' top-level form found therein, or #f if FILE does not
contain a 'define-command' form."
(define command-name
(match (string-split file #\/)
((_ ... "guix" "scripts" name)
(list (file-sans-extension name)))
((_ ... "guix" "scripts" first second)
(list first (file-sans-extension second)))))
;; The strategy here is to parse FILE. This is much cheaper than a
;; technique based on run-time introspection where we'd load FILE and all
;; the modules it depends on.
(call-with-input-file file
(lambda (port)
(let loop ()
(match (read port)
(('define-command _ ('synopsis synopsis)
_ ...)
(command command-name synopsis 'main))
(('define-command _
('category category) ('synopsis synopsis)
_ ...)
(command command-name synopsis category))
((? eof-object?)
#f)
(_
(loop)))))))
(define (command-files) (define (command-files)
"Return the list of source files that define Guix sub-commands." "Return the list of source files that define Guix sub-commands."
(define directory (define directory
@ -2004,28 +2043,51 @@ optionally contain a version number and an output name, as in these examples:
(cut string-suffix? ".scm" <>)) (cut string-suffix? ".scm" <>))
(if directory (if directory
(scandir directory dot-scm?) (map (cut string-append directory "/" <>)
(scandir directory dot-scm?))
'())) '()))
(define (commands) (define (commands)
"Return the list of Guix command names." "Return the list of commands, alphabetically sorted."
(map (compose (cut string-drop-right <> 4) (filter-map source-file-command (command-files)))
basename)
(command-files)))
(define (show-guix-help) (define (show-guix-help)
(define (internal? command) (define (internal? command)
(member command '("substitute" "authenticate" "offload" (member command '("substitute" "authenticate" "offload"
"perform-download"))) "perform-download")))
(define (display-commands commands)
(let* ((names (map (lambda (command)
(string-join (command-name command)))
commands))
(max-width (reduce max 0 (map string-length names))))
(for-each (lambda (name command)
(format #t " ~a ~a~%"
(string-pad-right name max-width)
(G_ (command-synopsis command))))
names
commands)))
(define (category-predicate category)
(lambda (command)
(eq? category (command-category command))))
(format #t (G_ "Usage: guix COMMAND ARGS... (format #t (G_ "Usage: guix COMMAND ARGS...
Run COMMAND with ARGS.\n")) Run COMMAND with ARGS.\n"))
(newline) (newline)
(format #t (G_ "COMMAND must be one of the sub-commands listed below:\n")) (format #t (G_ "COMMAND must be one of the sub-commands listed below:\n"))
(newline)
;; TODO: Display a synopsis of each command. (let ((commands (commands))
(format #t "~{ ~a~%~}" (sort (remove internal? (commands)) (categories (module-ref (resolve-interface '(guix scripts))
string<?)) '%command-categories)))
(for-each (match-lambda
(('internal . _)
#t) ;hide internal commands
((category . synopsis)
(format #t "~% ~a~%" (G_ synopsis))
(display-commands (filter (category-predicate category)
commands))))
categories))
(show-bug-report-information)) (show-bug-report-information))
(define (run-guix-command command . args) (define (run-guix-command command . args)