diff options
Diffstat (limited to 'guix')
-rw-r--r-- | guix/import/egg.scm | 9 | ||||
-rw-r--r-- | guix/import/pypi.scm | 8 | ||||
-rw-r--r-- | guix/import/texlive.scm | 20 | ||||
-rw-r--r-- | guix/import/utils.scm | 2 | ||||
-rw-r--r-- | guix/monad-repl.scm | 64 | ||||
-rw-r--r-- | guix/scripts/home.scm | 64 | ||||
-rw-r--r-- | guix/scripts/import/texlive.scm | 25 | ||||
-rw-r--r-- | guix/scripts/package.scm | 33 | ||||
-rw-r--r-- | guix/scripts/shell.scm | 5 | ||||
-rw-r--r-- | guix/scripts/system.scm | 67 | ||||
-rw-r--r-- | guix/upstream.scm | 18 | ||||
-rw-r--r-- | guix/utils.scm | 6 |
12 files changed, 230 insertions, 91 deletions
diff --git a/guix/import/egg.scm b/guix/import/egg.scm index 0b88020554..52196583c4 100644 --- a/guix/import/egg.scm +++ b/guix/import/egg.scm @@ -85,11 +85,6 @@ (define %eggs-home-page (make-parameter "https://wiki.call-cc.org/egg")) -(define (egg-source-url name version) - "Return the URL to the source tarball for version VERSION of the CHICKEN egg -NAME." - `(egg-uri ,name version)) - (define (egg-name->guix-name name) "Return the package name for CHICKEN egg NAME." (string-append package-name-prefix name)) @@ -196,7 +191,7 @@ not work." (let* ((version* (or (assoc-ref egg-content 'version) (find-latest-version name))) (version (if (list? version*) (first version*) version*)) - (source-url (if source #f (egg-source-url name version))) + (source-url (if source #f `(egg-uri ,name version))) (tarball (if source #f (with-store store @@ -342,7 +337,7 @@ not work." "Return an @code{<upstream-source>} for the latest release of PACKAGE." (let* ((egg-name (guix-package->egg-name package)) (version (find-latest-version egg-name)) - (source-url (egg-source-url egg-name version))) + (source-url (egg-uri egg-name version))) (upstream-source (package (package-name package)) (version version) diff --git a/guix/import/pypi.scm b/guix/import/pypi.scm index 392fc9700b..4760fc3dae 100644 --- a/guix/import/pypi.scm +++ b/guix/import/pypi.scm @@ -161,9 +161,11 @@ or #f if there isn't any." (define (python->package-name name) "Given the NAME of a package on PyPI, return a Guix-compliant name for the package." - (if (string-prefix? "python-" name) - (snake-case name) - (string-append "python-" (snake-case name)))) + (cond + ((string-prefix? "python-" name) (snake-case name)) + ((or (string=? "trytond" name) + (string-prefix? "trytond-" name)) (snake-case name)) + (else (string-append "python-" (snake-case name))))) (define (guix-package->pypi-name package) "Given a Python PACKAGE built from pypi.org, return the name of the diff --git a/guix/import/texlive.scm b/guix/import/texlive.scm index c741555928..116bd1f66a 100644 --- a/guix/import/texlive.scm +++ b/guix/import/texlive.scm @@ -246,7 +246,7 @@ of those files are returned that are unexpectedly installed." ;; entries with the same prefix. (lambda (x y) (every equal? x y))))) -(define (tlpdb->package name package-database) +(define (tlpdb->package name version package-database) (and-let* ((data (assoc-ref package-database name)) (dirs (files->directories (map (lambda (dir) @@ -255,7 +255,9 @@ of those files are returned that are unexpectedly installed." (or (assoc-ref data 'runfiles) (list)) (or (assoc-ref data 'srcfiles) (list)))))) (name (guix-name name)) - (version (number->string %texlive-revision)) + ;; TODO: we're ignoring the VERSION argument because that + ;; information is distributed across %texlive-tag and + ;; %texlive-revision. (ref (svn-multi-reference (url (string-append "svn://www.tug.org/texlive/tags/" %texlive-tag "/Master/texmf-dist")) @@ -276,6 +278,9 @@ of those files are returned that are unexpectedly installed." (force-output port) (get-hash)))) ,@(if (assoc-ref data 'srcfiles) '() '(#:trivial? #true)))) + ;; package->definition in (guix import utils) expects to see a + ;; version field. + (version ,version) ,@(or (and=> (assoc-ref data 'depend) (lambda (inputs) `((propagated-inputs @@ -297,13 +302,18 @@ of those files are returned that are unexpectedly installed." (define texlive->guix-package (memoize - (lambda* (name #:key repo version (package-database tlpdb)) + (lambda* (name #:key + repo + (version (number->string %texlive-revision)) + (package-database tlpdb)) "Find the metadata for NAME in the tlpdb and return the `package' s-expression corresponding to that package, or #f on failure." - (tlpdb->package name (package-database))))) + (tlpdb->package name version (package-database))))) -(define (texlive-recursive-import name) +(define* (texlive-recursive-import name #:key repo version) (recursive-import name + #:repo repo + #:version version #:repo->guix-package texlive->guix-package #:guix-name guix-name)) diff --git a/guix/import/utils.scm b/guix/import/utils.scm index 26eebfece5..668b8c8083 100644 --- a/guix/import/utils.scm +++ b/guix/import/utils.scm @@ -341,6 +341,8 @@ APPEND-VERSION?/string is a string, append this string." (match guix-package ((or ('package ('name name) ('version version) . rest) + ('package ('inherit ('simple-texlive-package name . _)) + ('version version) . rest) ('let _ ('package ('name name) ('version version) . rest))) `(define-public ,(string->symbol diff --git a/guix/monad-repl.scm b/guix/monad-repl.scm index aefabdeebb..8a6053edd5 100644 --- a/guix/monad-repl.scm +++ b/guix/monad-repl.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2014, 2015, 2016, 2022 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -21,6 +21,12 @@ #:use-module (guix monads) #:use-module (guix utils) #:use-module (guix packages) + #:use-module (guix status) + #:autoload (guix gexp) (lower-object) + #:use-module ((guix derivations) + #:select (derivation? + derivation->output-paths built-derivations)) + #:use-module (ice-9 match) #:use-module (ice-9 pretty-print) #:use-module (system repl repl) #:use-module (system repl common) @@ -69,16 +75,58 @@ #:guile-for-build guile) 'store-monad))) +(define %build-verbosity + ;; Current build verbosity level. + 1) + +(define* (evaluate/print-with-store mvalue #:key build?) + "Run monadic value MVALUE in the store monad and print its value." + (with-store store + (set-build-options store + #:print-build-trace #t + #:print-extended-build-trace? #t + #:multiplexed-build-output? #t) + (with-status-verbosity %build-verbosity + (let* ((guile (or (%guile-for-build) + (default-guile-derivation store))) + (values (run-with-store store + (if build? + (mlet %store-monad ((obj mvalue)) + (if (derivation? obj) + (mbegin %store-monad + (built-derivations (list obj)) + (return + (match (derivation->output-paths obj) + (((_ . files) ...) files)))) + (return (list obj)))) + (mlet %store-monad ((obj mvalue)) + (return (list obj)))) + #:guile-for-build guile))) + (for-each (lambda (value) + (run-hook before-print-hook value) + (pretty-print value)) + values))))) + (define-meta-command ((run-in-store guix) repl (form)) "run-in-store EXP Run EXP through the store monad." - (with-store store - (let* ((guile (or (%guile-for-build) - (default-guile-derivation store))) - (value (run-with-store store (repl-eval repl form) - #:guile-for-build guile))) - (run-hook before-print-hook value) - (pretty-print value)))) + (evaluate/print-with-store (repl-eval repl form))) + +(define-meta-command ((verbosity guix) repl (level)) + "verbosity LEVEL +Change build verbosity to LEVEL." + (set! %build-verbosity (repl-eval repl level))) + +(define-meta-command ((lower guix) repl (form)) + "lower OBJECT +Lower OBJECT into a derivation or store file and return it." + (evaluate/print-with-store (lower-object (repl-eval repl form)))) + +(define-meta-command ((build guix) repl (form)) + "build OBJECT +Lower OBJECT and build it, returning its output file name(s)." + (evaluate/print-with-store (lower-object (repl-eval repl form)) + #:build? #t)) (define-meta-command ((enter-store-monad guix) repl) "enter-store-monad diff --git a/guix/scripts/home.scm b/guix/scripts/home.scm index 0f5c3388a1..4add7e7c69 100644 --- a/guix/scripts/home.scm +++ b/guix/scripts/home.scm @@ -4,6 +4,7 @@ ;;; Copyright © 2021 Pierre Langlois <pierre.langlois@gmx.com> ;;; Copyright © 2021 Oleg Pykhalov <go.wigust@gmail.com> ;;; Copyright © 2022 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2022 Antero Mejr <antero@mailbox.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -143,6 +144,11 @@ Some ACTIONS support additional ARGS.\n")) use BACKEND for 'extension-graph' and 'shepherd-graph'")) (newline) (display (G_ " + -I, --list-installed[=REGEXP] + for 'describe' or 'list-generations', list installed + packages matching REGEXP")) + (newline) + (display (G_ " -h, --help display this help and exit")) (display (G_ " -V, --version display version information and exit")) @@ -183,6 +189,9 @@ Some ACTIONS support additional ARGS.\n")) (option '("graph-backend") #t #f (lambda (opt name arg result) (alist-cons 'graph-backend arg result))) + (option '(#\I "list-installed") #f #t + (lambda (opt name arg result) + (alist-cons 'list-installed (or arg "") result))) ;; Container options. (option '(#\N "network") #f #f @@ -569,17 +578,20 @@ Run @command{guix home reconfigure ~a/home-configuration.scm} to effectively deploy the home environment described by these files.\n") destination)))) ((describe) - (match (generation-number %guix-home) - (0 - (leave (G_ "no home environment generation, nothing to describe~%"))) - (generation - (display-home-environment-generation generation)))) + (let ((list-installed-regex (assoc-ref opts 'list-installed))) + (match (generation-number %guix-home) + (0 + (leave (G_ "no home environment generation, nothing to describe~%"))) + (generation + (display-home-environment-generation + generation #:list-installed-regex list-installed-regex))))) ((list-generations) - (let ((pattern (match args + (let ((list-installed-regex (assoc-ref opts 'list-installed)) + (pattern (match args (() #f) ((pattern) pattern) (x (leave (G_ "wrong number of arguments~%")))))) - (list-generations pattern))) + (list-generations pattern #:list-installed-regex list-installed-regex))) ((switch-generation) (let ((pattern (match args ((pattern) pattern) @@ -748,9 +760,11 @@ description matches REGEXPS sorted by relevance, and their score." (define* (display-home-environment-generation number - #:optional (profile %guix-home)) - "Display a summary of home-environment generation NUMBER in a -human-readable format." + #:optional (profile %guix-home) + #:key (list-installed-regex #f)) + "Display a summary of home-environment generation NUMBER in a human-readable +format. List packages in that home environment that match +LIST-INSTALLED-REGEX." (define (display-channel channel) (format #t " ~a:~%" (channel-name channel)) (format #t (G_ " repository URL: ~a~%") (channel-url channel)) @@ -782,24 +796,36 @@ human-readable format." (format #t (G_ " configuration file: ~a~%") (if (supports-hyperlinks?) (file-hyperlink config-file) - config-file)))))) - -(define* (list-generations pattern #:optional (profile %guix-home)) - "Display in a human-readable format all the home environment -generations matching PATTERN, a string. When PATTERN is #f, display -all the home environment generations." + config-file))) + (when list-installed-regex + (format #t (G_ " packages:\n")) + (pretty-print-table (list-installed + list-installed-regex + (list (string-append generation "/profile"))) + #:left-pad 4))))) + +(define* (list-generations pattern #:optional (profile %guix-home) + #:key (list-installed-regex #f)) + "Display in a human-readable format all the home environment generations +matching PATTERN, a string. When PATTERN is #f, display all the home +environment generations. List installed packages that match +LIST-INSTALLED-REGEX." (cond ((not (file-exists? profile)) ; XXX: race condition (raise (condition (&profile-not-found-error (profile profile))))) ((not pattern) - (for-each display-home-environment-generation (profile-generations profile))) + (for-each (cut display-home-environment-generation <> + #:list-installed-regex list-installed-regex) + (profile-generations profile))) ((matching-generations pattern profile) => (lambda (numbers) (if (null-list? numbers) (exit 1) - (leave-on-EPIPE - (for-each display-home-environment-generation numbers))))))) + (leave-on-EPIPE (for-each + (cut display-home-environment-generation <> + #:list-installed-regex list-installed-regex) + numbers))))))) ;;; diff --git a/guix/scripts/import/texlive.scm b/guix/scripts/import/texlive.scm index c5dcc07ea1..203386e31c 100644 --- a/guix/scripts/import/texlive.scm +++ b/guix/scripts/import/texlive.scm @@ -22,11 +22,13 @@ #:use-module (guix utils) #:use-module (guix scripts) #:use-module (guix import texlive) + #:use-module (guix import utils) #:use-module (guix scripts import) #:use-module (srfi srfi-1) #:use-module (srfi srfi-11) #:use-module (srfi srfi-37) #:use-module (srfi srfi-41) + #:use-module (srfi srfi-71) #:use-module (ice-9 match) #:use-module (ice-9 format) #:export (guix-import-texlive)) @@ -58,6 +60,9 @@ Import and convert the Texlive package for PACKAGE-NAME.\n")) (option '(#\V "version") #f #f (lambda args (show-version-and-exit "guix import texlive"))) + (option '(#\r "recursive") #f #f + (lambda (opt name arg result) + (alist-cons 'recursive #t result))) %standard-import-options)) @@ -78,12 +83,20 @@ Import and convert the Texlive package for PACKAGE-NAME.\n")) (_ #f)) (reverse opts)))) (match args - ((name) - (let ((sexp (texlive->guix-package name))) - (unless sexp - (leave (G_ "failed to import package '~a'~%") - name)) - sexp)) + ((spec) + (let ((name version (package-name->name+version spec))) + (if (assoc-ref opts 'recursive) + ;; Recursive import + (with-error-handling + (map package->definition + (filter identity (texlive-recursive-import name + #:version version)))) + ;; Single import + (let ((sexp (texlive->guix-package name #:version version))) + (unless sexp + (leave (G_ "failed to download description for package '~a'~%") + name)) + sexp)))) (() (leave (G_ "too few arguments~%"))) ((many ...) diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 99a6cfaa29..7d92598efa 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -11,6 +11,7 @@ ;;; Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com> ;;; Copyright © 2018 Steve Sprang <scs@stevesprang.com> ;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz> +;;; Copyright © 2022 Antero Mejr <antero@mailbox.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -67,6 +68,7 @@ delete-generations delete-matching-generations guix-package + list-installed search-path-environment-variables manifest-entry-version-prefix @@ -773,6 +775,22 @@ doesn't need it." (add-indirect-root store absolute)) +(define (list-installed regexp profiles) + "Write to the current output port the list of packages matching REGEXP in +PROFILES." + (let* ((regexp (and regexp (make-regexp* regexp regexp/icase))) + (manifest (concatenate-manifests + (map profile-manifest profiles))) + (installed (manifest-entries manifest))) + (leave-on-EPIPE + (let ((rows (filter-map + (match-lambda + (($ <manifest-entry> name version output path _) + (and (regexp-exec regexp name) + (list name (or version "?") output path)))) + installed))) + rows)))) + ;;; ;;; Queries and actions. @@ -824,19 +842,8 @@ processed, #f otherwise." #t) (('list-installed regexp) - (let* ((regexp (and regexp (make-regexp* regexp regexp/icase))) - (manifest (concatenate-manifests - (map profile-manifest profiles))) - (installed (manifest-entries manifest))) - (leave-on-EPIPE - (let ((rows (filter-map - (match-lambda - (($ <manifest-entry> name version output path _) - (and (regexp-exec regexp name) - (list name (or version "?") output path)))) - installed))) - ;; Show most recently installed packages last. - (pretty-print-table (reverse rows))))) + ;; Show most recently installed packages last. + (pretty-print-table (reverse (list-installed regexp profiles))) #t) (('list-available regexp) diff --git a/guix/scripts/shell.scm b/guix/scripts/shell.scm index 004ed7af2e..c115a00320 100644 --- a/guix/scripts/shell.scm +++ b/guix/scripts/shell.scm @@ -390,6 +390,11 @@ return #f and #f." ;; If the user already specified a profile, there's nothing more to ;; cache. (values #f #f)) + ((('export-manifest? . #t) . _) + ;; When exporting a manifest, compute it anew so that '-D' packages + ;; lead to 'package-development-manifest' expressions rather than an + ;; expanded list of inputs. + (values #f #f)) ((('system . system) . rest) (loop rest system file specs)) ((_ . rest) (loop rest system file specs))))) diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index b9084a401c..bfde0a88ca 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -50,7 +50,8 @@ #:use-module (guix channels) #:use-module (guix scripts build) #:autoload (guix scripts package) (delete-generations - delete-matching-generations) + delete-matching-generations + list-installed) #:autoload (guix scripts pull) (channel-commit-hyperlink) #:autoload (guix graph) (export-graph node-type graph-backend-name lookup-backend) @@ -480,8 +481,10 @@ list of services." ;;; (define* (display-system-generation number - #:optional (profile %system-profile)) - "Display a summary of system generation NUMBER in a human-readable format." + #:optional (profile %system-profile) + #:key (list-installed-regex #f)) + "Display a summary of system generation NUMBER in a human-readable format. +List packages in that system that match LIST-INSTALLED-REGEX." (define (display-channel channel) (format #t " ~a:~%" (channel-name channel)) (format #t (G_ " repository URL: ~a~%") (channel-url channel)) @@ -544,23 +547,35 @@ list of services." (format #t (G_ " configuration file: ~a~%") (if (supports-hyperlinks?) (file-hyperlink config-file) - config-file)))))) - -(define* (list-generations pattern #:optional (profile %system-profile)) + config-file))) + (when list-installed-regex + (format #t (G_ " packages:\n")) + (pretty-print-table (list-installed + list-installed-regex + (list (string-append generation "/profile"))) + #:left-pad 4))))) + +(define* (list-generations pattern #:optional (profile %system-profile) + #:key (list-installed-regex #f)) "Display in a human-readable format all the system generations matching -PATTERN, a string. When PATTERN is #f, display all the system generations." +PATTERN, a string. When PATTERN is #f, display all the system generations. +List installed packages that match LIST-INSTALLED-REGEX." (cond ((not (file-exists? profile)) ; XXX: race condition (raise (condition (&profile-not-found-error (profile profile))))) ((not pattern) - (for-each display-system-generation (profile-generations profile))) + (for-each (cut display-system-generation <> + #:list-installed-regex list-installed-regex) + (profile-generations profile))) ((matching-generations pattern profile) => (lambda (numbers) (if (null-list? numbers) (exit 1) (leave-on-EPIPE - (for-each display-system-generation numbers))))))) + (for-each (cut display-system-generation <> + #:list-installed-regex list-installed-regex) + numbers))))))) ;;; @@ -1032,6 +1047,11 @@ Some ACTIONS support additional ARGS.\n")) use BACKEND for 'extension-graphs' and 'shepherd-graph'")) (newline) (display (G_ " + -I, --list-installed[=REGEXP] + for 'describe' and 'list-generations', list installed + packages matching REGEXP")) + (newline) + (display (G_ " -h, --help display this help and exit")) (display (G_ " -V, --version display version information and exit")) @@ -1135,6 +1155,9 @@ Some ACTIONS support additional ARGS.\n")) (option '("graph-backend") #t #f (lambda (opt name arg result) (alist-cons 'graph-backend arg result))) + (option '(#\I "list-installed") #f #t + (lambda (opt name arg result) + (alist-cons 'list-installed (or arg "") result))) %standard-build-options)) (define %default-options @@ -1322,25 +1345,29 @@ argument list and OPTS is the option alist." ;; The following commands do not need to use the store, and they do not need ;; an operating system configuration file. ((list-generations) - (let ((pattern (match args + (let ((list-installed-regex (assoc-ref opts 'list-installed)) + (pattern (match args (() #f) ((pattern) pattern) (x (leave (G_ "wrong number of arguments~%")))))) - (list-generations pattern))) + (list-generations pattern #:list-installed-regex list-installed-regex))) ((describe) ;; Describe the running system, which is not necessarily the current ;; generation. /run/current-system might point to ;; /var/guix/profiles/system-N-link, or it might point directly to ;; /gnu/store/…-system. Try both. - (match (generation-number "/run/current-system" %system-profile) - (0 - (match (generation-number %system-profile) - (0 - (leave (G_ "no system generation, nothing to describe~%"))) - (generation - (display-system-generation generation)))) - (generation - (display-system-generation generation)))) + (let ((list-installed-regex (assoc-ref opts 'list-installed))) + (match (generation-number "/run/current-system" %system-profile) + (0 + (match (generation-number %system-profile) + (0 + (leave (G_ "no system generation, nothing to describe~%"))) + (generation + (display-system-generation + generation #:list-installed-regex list-installed-regex)))) + (generation + (display-system-generation + generation #:list-installed-regex list-installed-regex))))) ((search) (apply (resolve-subcommand "search") args)) ((edit) diff --git a/guix/upstream.scm b/guix/upstream.scm index 9b49d1641f..cbfd1aa609 100644 --- a/guix/upstream.scm +++ b/guix/upstream.scm @@ -251,13 +251,17 @@ correspond to the same version." #:warn warn-about-load-error))) (define %updaters - ;; The list of publically-known updaters. - (delay (fold-module-public-variables (lambda (obj result) - (if (upstream-updater? obj) - (cons obj result) - result)) - '() - (importer-modules)))) + ;; The list of publically-known updaters, alphabetically sorted. + (delay + (sort (fold-module-public-variables (lambda (obj result) + (if (upstream-updater? obj) + (cons obj result) + result)) + '() + (importer-modules)) + (lambda (updater1 updater2) + (string<? (symbol->string (upstream-updater-name updater1)) + (symbol->string (upstream-updater-name updater2))))))) ;; Tests need to mock this variable so mark it as "non-declarative". (set! %updaters %updaters) diff --git a/guix/utils.scm b/guix/utils.scm index 745da98a79..329ef62dde 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -1124,11 +1124,11 @@ according to THRESHOLD, then #f is returned." ;;; Prettified output. ;;; -(define* (pretty-print-table rows #:key (max-column-width 20)) +(define* (pretty-print-table rows #:key (max-column-width 20) (left-pad 0)) "Print ROWS in neat columns. All rows should be lists of strings and each row should have the same length. The columns are separated by a tab character, and aligned using spaces. The maximum width of each column is -bound by MAX-COLUMN-WIDTH." +bound by MAX-COLUMN-WIDTH. Each row is prefixed with LEFT-PAD spaces." (let* ((number-of-columns-to-pad (if (null? rows) 0 (1- (length (first rows))))) @@ -1143,7 +1143,7 @@ bound by MAX-COLUMN-WIDTH." (map (cut min <> max-column-width) column-widths))) (fmt (string-append (string-join column-formats "\t") "\t~a"))) - (for-each (cut format #t "~?~%" fmt <>) rows))) + (for-each (cut format #t "~v_~?~%" left-pad fmt <>) rows))) ;;; Local Variables: ;;; eval: (put 'call-with-progress-reporter 'scheme-indent-function 1) |