diff options
Diffstat (limited to 'guix/scripts')
-rw-r--r-- | guix/scripts/describe.scm | 56 | ||||
-rw-r--r-- | guix/scripts/git.scm | 63 | ||||
-rw-r--r-- | guix/scripts/git/authenticate.scm | 179 | ||||
-rw-r--r-- | guix/scripts/graph.scm | 1 | ||||
-rw-r--r-- | guix/scripts/pack.scm | 29 | ||||
-rw-r--r-- | guix/scripts/processes.scm | 11 | ||||
-rw-r--r-- | guix/scripts/pull.scm | 18 | ||||
-rw-r--r-- | guix/scripts/system.scm | 67 | ||||
-rw-r--r-- | guix/scripts/system/reconfigure.scm | 97 | ||||
-rw-r--r-- | guix/scripts/system/search.scm | 1 | ||||
-rw-r--r-- | guix/scripts/time-machine.scm | 4 | ||||
-rw-r--r-- | guix/scripts/weather.scm | 2 |
12 files changed, 455 insertions, 73 deletions
diff --git a/guix/scripts/describe.scm b/guix/scripts/describe.scm index ea982955da..bc868ffbbf 100644 --- a/guix/scripts/describe.scm +++ b/guix/scripts/describe.scm @@ -26,9 +26,11 @@ #:use-module (guix scripts) #:use-module (guix describe) #:use-module (guix profiles) + #:autoload (guix openpgp) (openpgp-format-fingerprint) #:use-module (git) #:use-module (json) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) #:use-module (srfi srfi-37) #:use-module (ice-9 match) #:use-module (ice-9 format) @@ -43,7 +45,8 @@ ;;; ;;; Command-line options. ;;; -(define %available-formats '("human" "channels" "json" "recutils")) +(define %available-formats + '("human" "channels" "channels-sans-intro" "json" "recutils")) (define (list-formats) (display (G_ "The available formats are:\n")) @@ -110,21 +113,50 @@ Display information about the channels currently in use.\n")) (_ (warning (G_ "'GUIX_PACKAGE_PATH' is set but it is not captured~%"))))))) -(define (channel->sexp channel) - `(channel - (name ',(channel-name channel)) - (url ,(channel-url channel)) - (commit ,(channel-commit channel)))) +(define* (channel->sexp channel #:key (include-introduction? #t)) + (let ((intro (and include-introduction? + (channel-introduction channel)))) + `(channel + (name ',(channel-name channel)) + (url ,(channel-url channel)) + (commit ,(channel-commit channel)) + ,@(if intro + `((introduction (make-channel-introduction + ,(channel-introduction-first-signed-commit intro) + (openpgp-fingerprint + ,(openpgp-format-fingerprint + (channel-introduction-first-commit-signer + intro)))))) + '())))) (define (channel->json channel) - (scm->json-string `((name . ,(channel-name channel)) - (url . ,(channel-url channel)) - (commit . ,(channel-commit channel))))) + (scm->json-string + (let ((intro (channel-introduction channel))) + `((name . ,(channel-name channel)) + (url . ,(channel-url channel)) + (commit . ,(channel-commit channel)) + ,@(if intro + `((introduction + . ((commit . ,(channel-introduction-first-signed-commit + intro)) + (signer . ,(openpgp-format-fingerprint + (channel-introduction-first-commit-signer + intro)))))) + '()))))) (define (channel->recutils channel port) + (define intro + (channel-introduction channel)) + (format port "name: ~a~%" (channel-name channel)) (format port "url: ~a~%" (channel-url channel)) - (format port "commit: ~a~%" (channel-commit channel))) + (format port "commit: ~a~%" (channel-commit channel)) + (when intro + (format port "introductioncommit: ~a~%" + (channel-introduction-first-signed-commit intro)) + (format port "introductionsigner: ~a~%" + (openpgp-format-fingerprint + (channel-introduction-first-commit-signer intro))))) (define (display-checkout-info fmt) "Display information about the current checkout according to FMT, a symbol @@ -182,6 +214,10 @@ in the format specified by FMT." (display-profile-content profile number)) ('channels (pretty-print `(list ,@(map channel->sexp channels)))) + ('channels-sans-intro + (pretty-print `(list ,@(map (cut channel->sexp <> + #:include-introduction? #f) + channels)))) ('json (format #t "[~a]~%" (string-join (map channel->json channels) ","))) ('recutils diff --git a/guix/scripts/git.scm b/guix/scripts/git.scm new file mode 100644 index 0000000000..bc829cbe99 --- /dev/null +++ b/guix/scripts/git.scm @@ -0,0 +1,63 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (guix scripts git) + #:use-module (ice-9 match) + #:use-module (guix ui) + #:export (guix-git)) + +(define (show-help) + (display (G_ "Usage: guix git COMMAND ARGS... +Operate on Git repositories.\n")) + (newline) + (display (G_ "The valid values for ACTION are:\n")) + (newline) + (display (G_ "\ + authenticate verify commit signatures and authorizations\n")) + (newline) + (display (G_ " + -h, --help display this help and exit")) + (display (G_ " + -V, --version display version information and exit")) + (newline) + (show-bug-report-information)) + +(define %sub-commands '("authenticate")) + +(define (resolve-sub-command name) + (let ((module (resolve-interface + `(guix scripts git ,(string->symbol name)))) + (proc (string->symbol (string-append "guix-git-" name)))) + (module-ref module proc))) + +(define (guix-git . args) + (with-error-handling + (match args + (() + (format (current-error-port) + (G_ "guix git: missing sub-command~%"))) + ((or ("-h") ("--help")) + (show-help) + (exit 0)) + ((or ("-V") ("--version")) + (show-version-and-exit "guix git")) + ((sub-command args ...) + (if (member sub-command %sub-commands) + (apply (resolve-sub-command sub-command) args) + (format (current-error-port) + (G_ "guix git: invalid sub-command~%"))))))) diff --git a/guix/scripts/git/authenticate.scm b/guix/scripts/git/authenticate.scm new file mode 100644 index 0000000000..5f5d423f28 --- /dev/null +++ b/guix/scripts/git/authenticate.scm @@ -0,0 +1,179 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (guix scripts git authenticate) + #:use-module (git) + #:use-module (guix ui) + #:use-module (guix scripts) + #:use-module (guix git-authenticate) + #:autoload (guix openpgp) (openpgp-format-fingerprint + openpgp-public-key-fingerprint) + #:use-module ((guix channels) #:select (openpgp-fingerprint)) + #:use-module ((guix git) #:select (with-git-error-handling)) + #:use-module (guix progress) + #:use-module (guix base64) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-37) + #:use-module (ice-9 format) + #:use-module (ice-9 match) + #:export (guix-git-authenticate)) + +;;; Commentary: +;;; +;;; Authenticate a Git checkout by reading '.guix-authorizations' files and +;;; following the "authorizations invariant" also used by (guix channels). +;;; +;;; Code: + +(define %options + ;; Specifications of the command-line options. + (list (option '(#\h "help") #f #f + (lambda args + (show-help) + (exit 0))) + (option '(#\V "version") #f #f + (lambda args + (show-version-and-exit "guix git authenticate"))) + + (option '(#\r "repository") #t #f + (lambda (opt name arg result) + (alist-cons 'directory arg result))) + (option '(#\e "end") #t #f + (lambda (opt name arg result) + (alist-cons 'end-commit (string->oid arg) result))) + (option '(#\k "keyring") #t #f + (lambda (opt name arg result) + (alist-cons 'keyring-reference arg result))) + (option '("cache-key") #t #f + (lambda (opt name arg result) + (alist-cons 'cache-key arg result))) + (option '("historical-authorizations") #t #f + (lambda (opt name arg result) + (alist-cons 'historical-authorizations arg + result))) + (option '("stats") #f #f + (lambda (opt name arg result) + (alist-cons 'show-stats? #t result))))) + +(define %default-options + '((directory . ".") + (keyring-reference . "keyring"))) + +(define (show-stats stats) + "Display STATS, an alist containing commit signing stats as returned by +'authenticate-repository'." + (format #t (G_ "Signing statistics:~%")) + (for-each (match-lambda + ((signer . count) + (format #t " ~a ~10d~%" + (openpgp-format-fingerprint + (openpgp-public-key-fingerprint signer)) + count))) + (sort stats + (match-lambda* + (((_ . count1) (_ . count2)) + (> count1 count2)))))) + +(define (show-help) + (display (G_ "Usage: guix git authenticate COMMIT SIGNER [OPTIONS...] +Authenticate the given Git checkout using COMMIT/SIGNER as its introduction.\n")) + (display (G_ " + -r, --repository=DIRECTORY + open the Git repository at DIRECTORY")) + (display (G_ " + -k, --keyring=REFERENCE + load keyring from REFERENCE, a Git branch")) + (display (G_ " + --stats display commit signing statistics upon completion")) + (display (G_ " + --cache-key=KEY cache authenticated commits under KEY")) + (display (G_ " + --historical-authorizations=FILE + read historical authorizations from FILE")) + (newline) + (display (G_ " + -h, --help display this help and exit")) + (display (G_ " + -V, --version display version information and exit")) + (newline) + (show-bug-report-information)) + + +;;; +;;; Entry point. +;;; + +(define (guix-git-authenticate . args) + (define options + (parse-command-line args %options (list %default-options) + #:build-options? #f)) + + (define (command-line-arguments lst) + (reverse (filter-map (match-lambda + (('argument . arg) arg) + (_ #f)) + lst))) + + (define commit-short-id + (compose (cut string-take <> 7) oid->string commit-id)) + + (define (make-reporter start-commit end-commit commits) + (format (current-error-port) + (G_ "Authenticating commits ~a to ~a (~h new \ +commits)...~%") + (commit-short-id start-commit) + (commit-short-id end-commit) + (length commits)) + + (if (isatty? (current-error-port)) + (progress-reporter/bar (length commits)) + progress-reporter/silent)) + + (with-error-handling + (with-git-error-handling + (match (command-line-arguments options) + ((commit signer) + (let* ((directory (assoc-ref options 'directory)) + (show-stats? (assoc-ref options 'show-stats?)) + (keyring (assoc-ref options 'keyring-reference)) + (repository (repository-open directory)) + (end (match (assoc-ref options 'end-commit) + (#f (reference-target + (repository-head repository))) + (oid oid))) + (history (match (assoc-ref options 'historical-authorizations) + (#f '()) + (file (call-with-input-file file + read-authorizations)))) + (cache-key (or (assoc-ref options 'cache-key) + (repository-cache-key repository)))) + (define stats + (authenticate-repository repository (string->oid commit) + (openpgp-fingerprint signer) + #:end end + #:keyring-reference keyring + #:historical-authorizations history + #:cache-key cache-key + #:make-reporter make-reporter)) + + (when (and show-stats? (not (null? stats))) + (show-stats stats)))) + (_ + (leave (G_ "wrong number of arguments; \ +expected COMMIT and SIGNER~%"))))))) diff --git a/guix/scripts/graph.scm b/guix/scripts/graph.scm index 1d5db3b3cb..489931d5bb 100644 --- a/guix/scripts/graph.scm +++ b/guix/scripts/graph.scm @@ -43,6 +43,7 @@ #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) #:use-module (srfi srfi-37) + #:use-module (ice-9 format) #:use-module (ice-9 match) #:export (%package-node-type %reverse-package-node-type diff --git a/guix/scripts/pack.scm b/guix/scripts/pack.scm index e0f9cc1a12..5fb6aaae0c 100644 --- a/guix/scripts/pack.scm +++ b/guix/scripts/pack.scm @@ -149,6 +149,11 @@ dependencies are registered." (define db-file (store-database-file #:state-directory #$output)) + ;; Make sure non-ASCII file names are properly handled. + (setenv "GUIX_LOCPATH" + #+(file-append glibc-utf8-locales "/lib/locale")) + (setlocale LC_ALL "en_US.utf8") + (sql-schema #$schema) (let ((items (append-map read-closure '#$labels))) (with-database db-file db @@ -181,6 +186,15 @@ added to the pack." (file-append (store-database (list profile)) "/db/db.sqlite"))) + (define set-utf8-locale + ;; Arrange to not depend on 'glibc-utf8-locales' when using '--bootstrap'. + (and (or (not (profile? profile)) + (profile-locales? profile)) + #~(begin + (setenv "GUIX_LOCPATH" + #+(file-append glibc-utf8-locales "/lib/locale")) + (setlocale LC_ALL "en_US.utf8")))) + (define build (with-imported-modules (source-module-closure `((guix build utils) @@ -226,6 +240,9 @@ added to the pack." "cf" "/dev/null" "--files-from=/dev/null" "--sort=name"))) + ;; Make sure non-ASCII file names are properly handled. + #+set-utf8-locale + ;; Add 'tar' to the search path. (setenv "PATH" #+(file-append archiver "/bin")) @@ -836,9 +853,10 @@ last resort for relocation." (scandir input)) (for-each build-wrapper - (append (find-files (string-append input "/bin")) - (find-files (string-append input "/sbin")) - (find-files (string-append input "/libexec"))))))) + ;; Note: Trailing slash in case these are symlinks. + (append (find-files (string-append input "/bin/")) + (find-files (string-append input "/sbin/")) + (find-files (string-append input "/libexec/"))))))) (computed-file (string-append (cond ((package? package) @@ -857,7 +875,10 @@ last resort for relocation." (item (apply wrapped-package (manifest-entry-item entry) (manifest-entry-output entry) - args)))) + args)) + (dependencies (map (lambda (entry) + (apply wrapped-manifest-entry entry args)) + (manifest-entry-dependencies entry))))) ;;; diff --git a/guix/scripts/processes.scm b/guix/scripts/processes.scm index a2ab017490..01f7213e8c 100644 --- a/guix/scripts/processes.scm +++ b/guix/scripts/processes.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2018, 2019 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -231,7 +231,8 @@ List the current Guix sessions and their processes.")) cons '())) - (for-each (lambda (session) - (daemon-session->recutils session (current-output-port)) - (newline)) - (daemon-sessions))) + (with-paginated-output-port port + (for-each (lambda (session) + (daemon-session->recutils session port) + (newline port)) + (daemon-sessions)))) diff --git a/guix/scripts/pull.scm b/guix/scripts/pull.scm index f953957161..807daec593 100644 --- a/guix/scripts/pull.scm +++ b/guix/scripts/pull.scm @@ -63,7 +63,6 @@ #:re-export (display-profile-content channel-commit-hyperlink) #:export (channel-list - with-git-error-handling guix-pull)) @@ -464,23 +463,6 @@ true, display what would be built without actually building it." (unless (honor-system-x509-certificates!) (honor-lets-encrypt-certificates! store))) -(define (report-git-error error) - "Report the given Guile-Git error." - ;; Prior to Guile-Git commit b6b2760c2fd6dfaa5c0fedb43eeaff06166b3134, - ;; errors would be represented by integers. - (match error - ((? integer? error) ;old Guile-Git - (leave (G_ "Git error ~a~%") error)) - ((? git-error? error) ;new Guile-Git - (leave (G_ "Git error: ~a~%") (git-error-message error))))) - -(define-syntax-rule (with-git-error-handling body ...) - (catch 'git-error - (lambda () - body ...) - (lambda (key err) - (report-git-error err)))) - ;;; ;;; Profile. diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index d9cf45da23..79bfcd7db2 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -446,17 +446,6 @@ list of services." ;;; Generations. ;;; -(define (sexp->channel sexp) - "Return the channel corresponding to SEXP, an sexp as found in the -\"provenance\" file produced by 'provenance-service-type'." - (match sexp - (('channel ('name name) - ('url url) - ('branch branch) - ('commit commit)) - (channel (name name) (url url) - (branch branch) (commit commit))))) - (define* (display-system-generation number #:optional (profile %system-profile)) "Display a summary of system generation NUMBER in a human-readable format." @@ -480,12 +469,10 @@ list of services." (uuid->string root) root)) (kernel (boot-parameters-kernel params)) - (provenance (catch 'system-error - (lambda () - (call-with-input-file - (string-append generation "/provenance") - read)) - (const #f)))) + (multiboot-modules (boot-parameters-multiboot-modules params))) + (define-values (channels config-file) + (system-provenance generation)) + (display-generation profile number) (format #t (G_ " file name: ~a~%") generation) (format #t (G_ " canonical file name: ~a~%") (readlink* generation)) @@ -509,21 +496,22 @@ list of services." (format #t (G_ " kernel: ~a~%") kernel) - (match provenance - (#f #t) - (('provenance ('version 0) - ('channels channels ...) - ('configuration-file config-file)) - (unless (null? channels) - ;; TRANSLATORS: Here "channel" is the same terminology as used in - ;; "guix describe" and "guix pull --channels". - (format #t (G_ " channels:~%")) - (for-each display-channel (map sexp->channel channels))) - (when config-file - (format #t (G_ " configuration file: ~a~%") - (if (supports-hyperlinks?) - (file-hyperlink config-file) - config-file)))))))) + (match multiboot-modules + (() #f) + (((modules . _) ...) + (format #t (G_ " multiboot: ~a~%") + (string-join modules "\n ")))) + + (unless (null? channels) + ;; TRANSLATORS: Here "channel" is the same terminology as used in + ;; "guix describe" and "guix pull --channels". + (format #t (G_ " channels:~%")) + (for-each display-channel channels)) + (when config-file + (format #t (G_ " configuration file: ~a~%") + (if (supports-hyperlinks?) + (file-hyperlink config-file) + config-file)))))) (define* (list-generations pattern #:optional (profile %system-profile)) "Display in a human-readable format all the system generations matching @@ -748,6 +736,7 @@ and TARGET arguments." (define* (perform-action action os #:key + (validate-reconfigure ensure-forward-reconfigure) save-provenance? skip-safety-checks? install-bootloader? @@ -790,7 +779,8 @@ static checks." (operating-system-bootcfg os menu-entries))) (when (eq? action 'reconfigure) - (maybe-suggest-running-guix-pull)) + (maybe-suggest-running-guix-pull) + (check-forward-update validate-reconfigure)) ;; Check whether the declared file systems exist. This is better than ;; instantiating a broken configuration. Assume that we can only check if @@ -939,6 +929,9 @@ Some ACTIONS support additional ARGS.\n")) -e, --expression=EXPR consider the operating-system EXPR evaluates to instead of reading FILE, when applicable")) (display (G_ " + --allow-downgrades for 'reconfigure', allow downgrades to earlier + channel revisions")) + (display (G_ " --on-error=STRATEGY apply STRATEGY (one of nothing-special, backtrace, or debug) when an error occurs while reading FILE")) @@ -993,6 +986,11 @@ Some ACTIONS support additional ARGS.\n")) (option '(#\d "derivation") #f #f (lambda (opt name arg result) (alist-cons 'derivations-only? #t result))) + (option '("allow-downgrades") #f #f + (lambda (opt name arg result) + (alist-cons 'validate-reconfigure + warn-about-backward-reconfigure + result))) (option '("on-error") #t #f (lambda (opt name arg result) (alist-cons 'on-error (string->symbol arg) @@ -1065,6 +1063,7 @@ Some ACTIONS support additional ARGS.\n")) (graft? . #t) (debug . 0) (verbosity . #f) ;default + (validate-reconfigure . ,ensure-forward-reconfigure) (file-system-type . "ext4") (image-size . guess) (install-bootloader? . #t))) @@ -1150,6 +1149,8 @@ resulting from command-line parsing." #:use-substitutes? (assoc-ref opts 'substitutes?) #:skip-safety-checks? (assoc-ref opts 'skip-safety-checks?) + #:validate-reconfigure + (assoc-ref opts 'validate-reconfigure) #:file-system-type (assoc-ref opts 'file-system-type) #:image-size (assoc-ref opts 'image-size) #:full-boot? (assoc-ref opts 'full-boot?) diff --git a/guix/scripts/system/reconfigure.scm b/guix/scripts/system/reconfigure.scm index 7885c33457..9013e035f7 100644 --- a/guix/scripts/system/reconfigure.scm +++ b/guix/scripts/system/reconfigure.scm @@ -34,9 +34,18 @@ #:use-module (guix monads) #:use-module (guix store) #:use-module ((guix self) #:select (make-config.scm)) + #:autoload (guix describe) (current-profile) + #:use-module (guix channels) + #:autoload (guix git) (update-cached-checkout) + #:use-module (guix i18n) + #:use-module (guix diagnostics) + #:use-module ((guix utils) #:select (&fix-hint)) #:use-module (ice-9 match) #:use-module (srfi srfi-1) #:use-module (srfi srfi-11) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) + #:use-module ((guix config) #:select (%guix-package-name)) #:export (switch-system-program switch-to-system @@ -44,7 +53,11 @@ upgrade-shepherd-services install-bootloader-program - install-bootloader)) + install-bootloader + + check-forward-update + ensure-forward-reconfigure + warn-about-backward-reconfigure)) ;;; Commentary: ;;; @@ -266,3 +279,85 @@ additional configurations specified by MENU-ENTRIES can be selected." bootcfg-file device target)))))) + + +;;; +;;; Downgrade detection. +;;; + +(define (ensure-forward-reconfigure channel start commit relation) + "Raise an error if RELATION is not 'ancestor, meaning that START is not an +ancestor of COMMIT, unless CHANNEL specifies a commit." + (match relation + ('ancestor #t) + ('self #t) + (_ + (raise (make-compound-condition + (condition + (&message (message + (format #f (G_ "\ +aborting reconfiguration because commit ~a of channel '~a' is not a descendant of ~a") + commit (channel-name channel) + start))) + (&fix-hint + (hint (G_ "Use @option{--allow-downgrades} to force +this downgrade."))))))))) + +(define (warn-about-backward-reconfigure channel start commit relation) + "Warn about non-forward updates of CHANNEL from START to COMMIT, without +aborting." + (match relation + ((or 'ancestor 'self) + #t) + ('descendant + (warning (G_ "rolling back channel '~a' from ~a to ~a~%") + (channel-name channel) start commit)) + ('unrelated + (warning (G_ "moving channel '~a' from ~a to unrelated commit ~a~%") + (channel-name channel) start commit)))) + +(define (channel-relations old new) + "Return a list of channel/relation pairs, where each relation is a symbol as +returned by 'commit-relation' denoting how commits of channels in OLD relate +to commits of channels in NEW." + (filter-map (lambda (old) + (let ((new (find (lambda (channel) + (eq? (channel-name channel) + (channel-name old))) + new))) + (and new + (let-values (((checkout commit relation) + (update-cached-checkout + (channel-url new) + #:ref + `(commit . ,(channel-commit new)) + #:starting-commit + (channel-commit old) + #:check-out? #f))) + (list new + (channel-commit old) (channel-commit new) + relation))))) + old)) + +(define* (check-forward-update #:optional + (validate-reconfigure ensure-forward-reconfigure)) + "Call VALIDATE-RECONFIGURE passing it, for each channel, the channel, the +currently-deployed commit (as returned by 'guix system describe') and the +target commit (as returned by 'guix describe')." + ;; TODO: Make that functionality available to 'guix deploy'. + (define new + (or (and=> (current-profile) profile-channels) + '())) + + (define old + (system-provenance "/run/current-system")) + + (when (null? old) + (warning (G_ "cannot determine provenance for /run/current-system~%"))) + (when (and (null? new) (not (getenv "GUIX_UNINSTALLED"))) + (warning (G_ "cannot determine provenance of ~a~%") %guix-package-name)) + + (for-each (match-lambda + ((channel old new relation) + (validate-reconfigure channel old new relation))) + (channel-relations old new))) diff --git a/guix/scripts/system/search.scm b/guix/scripts/system/search.scm index d2eac06cca..bf49ea2341 100644 --- a/guix/scripts/system/search.scm +++ b/guix/scripts/system/search.scm @@ -26,6 +26,7 @@ #:use-module (srfi srfi-11) #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) + #:use-module (ice-9 format) #:use-module (ice-9 regex) #:use-module (ice-9 match) #:export (service-type->recutils diff --git a/guix/scripts/time-machine.scm b/guix/scripts/time-machine.scm index f9bcec651a..441673b780 100644 --- a/guix/scripts/time-machine.scm +++ b/guix/scripts/time-machine.scm @@ -24,10 +24,12 @@ #:use-module (guix channels) #:use-module (guix store) #:use-module (guix status) + #:use-module ((guix git) + #:select (with-git-error-handling)) #:use-module ((guix utils) #:select (%current-system)) #:use-module ((guix scripts pull) - #:select (with-git-error-handling channel-list)) + #:select (channel-list)) #:use-module ((guix scripts build) #:select (%standard-build-options show-build-options-help diff --git a/guix/scripts/weather.scm b/guix/scripts/weather.scm index 475d989357..3035ff6ca8 100644 --- a/guix/scripts/weather.scm +++ b/guix/scripts/weather.scm @@ -190,7 +190,7 @@ Return the coverage ratio, an exact number between 0 and 1." narinfos)) (time (+ (time-second time) (/ (time-nanosecond time) 1e9)))) - (format #t (G_ " ~2,1f% substitutes available (~h out of ~h)~%") + (format #t (G_ " ~,1f% substitutes available (~h out of ~h)~%") (* 100. (/ obtained requested 1.)) obtained requested) (let ((total (/ (reduce + 0 sizes) MiB))) |