From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id ONJZHv4xA2BtXQAA0tVLHw (envelope-from ) for ; Sat, 16 Jan 2021 18:35:42 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0 with LMTPS id OOcvGv4xA2DSfAAA1q6Kng (envelope-from ) for ; Sat, 16 Jan 2021 18:35:42 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id C6E2E9401C0 for ; Sat, 16 Jan 2021 18:35:41 +0000 (UTC) Received: from localhost ([::1]:40600 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l0qQG-0004bR-Qa for larch@yhetil.org; Sat, 16 Jan 2021 13:35:40 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51132) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l0qPe-0004IC-SU for guix-patches@gnu.org; Sat, 16 Jan 2021 13:35:02 -0500 Received: from debbugs.gnu.org ([209.51.188.43]:60729) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1l0qPe-0006Nt-LI for guix-patches@gnu.org; Sat, 16 Jan 2021 13:35:02 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1l0qPe-0002Wx-Is for guix-patches@gnu.org; Sat, 16 Jan 2021 13:35:02 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#45919] [PATCH 3/8] guix package: Add '--export-manifest'. Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 16 Jan 2021 18:35:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 45919 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 45919@debbugs.gnu.org Received: via spool by 45919-submit@debbugs.gnu.org id=B45919.16108220709632 (code B ref 45919); Sat, 16 Jan 2021 18:35:02 +0000 Received: (at 45919) by debbugs.gnu.org; 16 Jan 2021 18:34:30 +0000 Received: from localhost ([127.0.0.1]:44029 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l0qP8-0002VH-6W for submit@debbugs.gnu.org; Sat, 16 Jan 2021 13:34:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57908) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l0qP4-0002UE-1A for 45919@debbugs.gnu.org; Sat, 16 Jan 2021 13:34:26 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]:57160) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l0qOy-0006BQ-Qk; Sat, 16 Jan 2021 13:34:20 -0500 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=36420 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1l0qOy-0000li-C2; Sat, 16 Jan 2021 13:34:20 -0500 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Date: Sat, 16 Jan 2021 19:34:04 +0100 Message-Id: <20210116183409.31229-3-ludo@gnu.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210116183409.31229-1-ludo@gnu.org> References: <20210116183409.31229-1-ludo@gnu.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Migadu-Flow: FLOW_IN X-Migadu-Spam-Score: -1.85 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=pass (policy=none) header.from=gnu.org; spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Migadu-Queue-Id: C6E2E9401C0 X-Spam-Score: -1.85 X-Migadu-Scanner: scn1.migadu.com X-TUID: 0hrUjw5Pb+J6 * guix/scripts/package.scm (export-manifest): New procedure. (show-help, %options): Add '--export-manifest'. (process-query): Honor it. * guix/build/profiles.scm (build-profile): Mention it. * tests/guix-package.sh: Test it. * doc/guix.texi (Invoking guix package): Document it. --- doc/guix.texi | 21 +++++++++++++++ guix/build/profiles.scm | 6 +++-- guix/scripts/package.scm | 57 +++++++++++++++++++++++++++++++++++++++- tests/guix-package.sh | 10 ++++++- 4 files changed, 90 insertions(+), 4 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index cea7f8a8cf..e524464e9f 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -3269,6 +3269,9 @@ objects, like this: '("emacs" "guile@@2.2" "guile@@2.2:debug")) @end lisp +@xref{export-manifest, @option{--export-manifest}}, to learn how to +obtain a manifest file from an existing profile. + @item --roll-back @cindex rolling back @cindex undoing transactions @@ -3571,6 +3574,24 @@ zeroth generation is never deleted. Note that deleting generations prevents rolling back to them. Consequently, this command must be used with care. +@cindex manifest, exporting +@anchor{export-manifest} +@item --export-manifest +Write to standard output a manifest suitable for @option{--manifest} +corresponding to the chosen profile(s). + +This option is meant to help you migrate from the ``imperative'' +operating mode---running @command{guix install}, @command{guix upgrade}, +etc.---to the declarative mode that @option{--manifest} offers. + +Be aware that the resulting manifest @emph{approximates} what your +profile actually contains; for instance, depending on how your profile +was created, it can refer to packages or package versions that are not +exactly what you specified. + +Keep in mind that a manifest is purely symbolic: it only contains +package names and possibly versions, and their meaning varies over time. + @end table Finally, since @command{guix package} may actually start build diff --git a/guix/build/profiles.scm b/guix/build/profiles.scm index 67ee9b665a..b42f498a80 100644 --- a/guix/build/profiles.scm +++ b/guix/build/profiles.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015, 2017, 2018, 2019, 2020 Ludovic Courtès +;;; Copyright © 2015, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -169,7 +169,9 @@ SEARCH-PATHS." (lambda (p) (display "\ ;; This file was automatically generated and is for internal use only. -;; It cannot be passed to the '--manifest' option.\n\n" +;; It cannot be passed to the '--manifest' option. +;; Run 'guix package --export-manifest' if to export a file suitable +;; for '--manifest'.\n\n" p) (pretty-print manifest p))) diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 6faf2adb7a..2b52016c67 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès ;;; Copyright © 2013 Nikita Karetnikov ;;; Copyright © 2013, 2015 Mark H Weaver ;;; Copyright © 2014, 2016 Alex Kost @@ -48,6 +48,7 @@ #:select (directory-exists? mkdir-p)) #:use-module (ice-9 format) #:use-module (ice-9 match) + #:autoload (ice-9 pretty-print) (pretty-print) #:use-module (ice-9 regex) #:use-module (ice-9 vlist) #:use-module (srfi srfi-1) @@ -320,6 +321,48 @@ GUIX_PROFILE=\"~a\" Alternately, see @command{guix package --search-paths -p ~s}.") profile profile))))) + +;;; +;;; Export a manifest. +;;; + +(define* (export-manifest manifest + #:optional (port (current-output-port))) + "Write to PORT a manifest corresponding to MANIFEST." + (define (version-spec entry) + (let ((name (manifest-entry-name entry))) + (match (map package-version (find-packages-by-name name)) + ((_) + ;; A single version of NAME is available, so do not specify the + ;; version number, even if the available version doesn't match ENTRY. + "") + (versions + ;; If ENTRY uses the latest version, don't specify any version. + ;; Otherwise return the shortest unique version prefix. Note that + ;; this is based on the currently available packages, which could + ;; differ from the packages available in the revision that was used + ;; to build MANIFEST. + (let ((current (manifest-entry-version entry))) + (if (every (cut version>? current <>) + (delete current versions)) + "" + (version-unique-prefix (manifest-entry-version entry) + versions))))))) + + (match (manifest->code manifest + #:entry-package-version version-spec) + (('begin exp ...) + (format port (G_ "\ +;; This \"manifest\" file can be passed to 'guix package -m' to reproduce +;; the content of your profile. This is \"symbolic\": it only specifies +;; package names. To reproduce the exact same profile, you also need to +;; capture the channels being used, as returned by \"guix describe\". +;; See the \"Replicating Guix\" section in the manual.\n")) + (for-each (lambda (exp) + (newline port) + (pretty-print exp port)) + exp)))) + ;;; ;;; Command-line options. @@ -373,6 +416,8 @@ Install, remove, or upgrade packages in a single transaction.\n")) (display (G_ " -S, --switch-generation=PATTERN switch to a generation matching PATTERN")) + (display (G_ " + --export-manifest print a manifest for the chosen profile")) (display (G_ " -p, --profile=PROFILE use PROFILE instead of the user's default profile")) (display (G_ " @@ -507,6 +552,10 @@ kind of search path~%") (values (cons `(query search-paths ,kind) result) #f)))) + (option '("export-manifest") #f #f + (lambda (opt name arg result arg-handler) + (values (cons `(query export-manifest) result) + #f))) (option '(#\p "profile") #t #f (lambda (opt name arg result arg-handler) (values (alist-cons 'profile (canonicalize-profile arg) @@ -827,6 +876,12 @@ processed, #f otherwise." (format #t "~{~a~%~}" settings) #t)) + (('export-manifest) + (let* ((manifest (concatenate-manifests + (map profile-manifest profiles)))) + (export-manifest manifest (current-output-port)) + #t)) + (_ #f)))) diff --git a/tests/guix-package.sh b/tests/guix-package.sh index 3e5fa71d20..7eaad6823f 100644 --- a/tests/guix-package.sh +++ b/tests/guix-package.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès +# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès # Copyright © 2013 Nikita Karetnikov # # This file is part of GNU Guix. @@ -395,6 +395,14 @@ EOF guix package --bootstrap -m "$module_dir/manifest.scm" guix package -I | grep guile test `guix package -I | wc -l` -eq 1 + +# Export a manifest, instantiate it, and make sure we get the same profile. +profile_directory="$(readlink -f "$default_profile")" +guix package --export-manifest > "$tmpfile" +guix package --rollback --bootstrap +guix package --bootstrap -m "$tmpfile" +test "$(readlink -f "$default_profile")" = "$profile_directory" + guix package --rollback --bootstrap # Applying two manifests. -- 2.30.0