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 4DZGAg4yA2CyYQAA0tVLHw (envelope-from ) for ; Sat, 16 Jan 2021 18:35:58 +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 sJq3OQ0yA2BvdQAA1q6Kng (envelope-from ) for ; Sat, 16 Jan 2021 18:35:57 +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 A4A939401C0 for ; Sat, 16 Jan 2021 18:35:57 +0000 (UTC) Received: from localhost ([::1]:41468 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l0qQW-0004zn-MT for larch@yhetil.org; Sat, 16 Jan 2021 13:35:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51146) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l0qPg-0004LK-Vi for guix-patches@gnu.org; Sat, 16 Jan 2021 13:35:05 -0500 Received: from debbugs.gnu.org ([209.51.188.43]:60734) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1l0qPg-0006PA-Mz for guix-patches@gnu.org; Sat, 16 Jan 2021 13:35:04 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1l0qPg-0002XY-L8 for guix-patches@gnu.org; Sat, 16 Jan 2021 13:35:04 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#45919] [PATCH 8/8] guix package: Add '--export-channels'. 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:04 +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.16108220799682 (code B ref 45919); Sat, 16 Jan 2021 18:35:04 +0000 Received: (at 45919) by debbugs.gnu.org; 16 Jan 2021 18:34:39 +0000 Received: from localhost ([127.0.0.1]:44040 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l0qPG-0002W4-OE for submit@debbugs.gnu.org; Sat, 16 Jan 2021 13:34:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57954) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l0qP8-0002UT-MH for 45919@debbugs.gnu.org; Sat, 16 Jan 2021 13:34:31 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]:57166) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l0qP2-0006Cu-Vl; Sat, 16 Jan 2021 13:34:25 -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 1l0qP2-0000li-Gd; Sat, 16 Jan 2021 13:34:24 -0500 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Date: Sat, 16 Jan 2021 19:34:09 +0100 Message-Id: <20210116183409.31229-8-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: A4A939401C0 X-Spam-Score: -1.85 X-Migadu-Scanner: scn1.migadu.com X-TUID: 5Mdc8NuRydtq * guix/channels.scm (sexp->channel): Export. * guix/describe.scm: Use (guix channels). (manifest-entry-provenance): New procedure. * guix/scripts/package.scm (channel=?, export-channels): New procedures. (show-help, %options): Add '--export-channels'. (process-query): Honor it. * build-aux/build-self.scm (build-program)[select?]: Exclude (guix channels) to account for the (guix describe) change above. * doc/guix.texi (Invoking guix package): Document it. --- build-aux/build-self.scm | 3 ++ doc/guix.texi | 24 ++++++++++++++++ guix/channels.scm | 1 + guix/describe.scm | 34 ++++++++++++++++++++-- guix/scripts/package.scm | 61 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 2 deletions(-) diff --git a/build-aux/build-self.scm b/build-aux/build-self.scm index 4b6e2bfae5..d5bc5fb46e 100644 --- a/build-aux/build-self.scm +++ b/build-aux/build-self.scm @@ -245,8 +245,11 @@ interface (FFI) of Guile.") "Return a program that computes the derivation to build Guix from SOURCE." (define select? ;; Select every module but (guix config) and non-Guix modules. + ;; Also exclude (guix channels): it is autoloaded by (guix describe), but + ;; only for peripheral functionality. (match-lambda (('guix 'config) #f) + (('guix 'channels) #f) (('guix _ ...) #t) (('gnu _ ...) #t) (_ #f))) diff --git a/doc/guix.texi b/doc/guix.texi index e524464e9f..cfb2f8a296 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -3591,7 +3591,31 @@ 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. +If you wish to ``pin'' channels to the revisions that were used to build +the profile(s), see @option{--export-channels} below. +@cindex pinning, channel revisions of a profile +@item --export-channels +Write to standard output the list of channels used by the chosen +profile(s), in a format suitable for @command{guix pull --channels} or +@command{guix time-machine --channels} (@pxref{Channels}). + +Together with @option{--export-manifest}, this option provides +information allowing you to replicate the current profile +(@pxref{Replicating Guix}). + +However, note that the output of this command @emph{approximates} what +was actually used to build this profile. In particular, a single +profile might have been built from several different revisions of the +same channel. In that case, @option{--export-manifest} chooses the last +one and writes the list of other revisions in a comment. If you really +need to pick packages from different channel revisions, you can use +inferiors in your manifest to do so (@pxref{Inferiors}). + +Together with @option{--export-manifest}, this is a good starting point +if you are willing to migrate from the ``imperative'' model to the fully +declarative model consisting of a manifest file along with a channels +file pinning the exact channel revision(s) you want. @end table Finally, since @command{guix package} may actually start build diff --git a/guix/channels.scm b/guix/channels.scm index cdef77637d..e7e1eb6fd0 100644 --- a/guix/channels.scm +++ b/guix/channels.scm @@ -92,6 +92,7 @@ profile-channels manifest-entry-channel + sexp->channel channel->code channel-news-entry? diff --git a/guix/describe.scm b/guix/describe.scm index 05bf99eb58..ac89fc0d7c 100644 --- a/guix/describe.scm +++ b/guix/describe.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2018, 2019, 2020 Ludovic Courtès +;;; Copyright © 2018, 2019, 2020, 2021 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -23,6 +23,7 @@ #:use-module ((guix utils) #:select (location-file)) #:use-module ((guix store) #:select (%store-prefix store-path?)) #:use-module ((guix config) #:select (%state-directory)) + #:autoload (guix channels) (sexp->channel) #:use-module (srfi srfi-1) #:use-module (ice-9 match) #:export (current-profile @@ -31,7 +32,8 @@ package-path-entries package-provenance - manifest-entry-with-provenance)) + manifest-entry-with-provenance + manifest-entry-provenance)) ;;; Commentary: ;;; @@ -166,3 +168,31 @@ there." (#f properties) (sexp `((provenance ,@sexp) ,@properties))))))))) + +(define (manifest-entry-provenance entry) + "Return the list of channels ENTRY comes from. Return the empty list if +that information is missing." + (match (assq-ref (manifest-entry-properties entry) 'provenance) + ((main extras ...) + ;; XXX: Until recently, channel sexps lacked the channel name. For + ;; entries created by 'manifest-entry-with-provenance', the first sexp + ;; is known to be the 'guix channel, and for the other ones, invent a + ;; fallback name (it's OK as the name is just a "pet name"). + (match (sexp->channel main 'guix) + (#f '()) + (channel + (let loop ((extras extras) + (counter 1) + (channels (list channel))) + (match extras + (() + (reverse channels)) + ((head . tail) + (let* ((name (string->symbol + (format #f "channel~a" counter))) + (extra (sexp->channel head name))) + (if extra + (loop tail (+ 1 counter) (cons extra channels)) + (loop tail counter channels))))))))) + (_ + '()))) diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 2b52016c67..8234a1703d 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -43,6 +43,7 @@ #:use-module (guix scripts build) #:use-module (guix transformations) #:use-module (guix describe) + #:autoload (guix channels) (channel-name channel-commit channel->code) #:autoload (guix store roots) (gc-roots user-owned?) #:use-module ((guix build utils) #:select (directory-exists? mkdir-p)) @@ -363,6 +364,54 @@ Alternately, see @command{guix package --search-paths -p ~s}.") (pretty-print exp port)) exp)))) +(define (channel=? a b) + (and (channel-commit a) (channel-commit b) + (string=? (channel-commit a) (channel-commit b)))) + +(define* (export-channels manifest + #:optional (port (current-output-port))) + (define channels + (delete-duplicates + (append-map manifest-entry-provenance (manifest-entries manifest)) + channel=?)) + + (define channel-names + (delete-duplicates (map channel-name channels))) + + (define table + (fold (lambda (channel table) + (vhash-consq (channel-name channel) channel table)) + vlist-null + channels)) + + (when (null? channels) + (leave (G_ "no provenance information for this profile~%"))) + + (format port (G_ "\ +;; This channel file can be passed to 'guix pull -C' or to +;; 'guix time-machine -C' to obtain the Guix revision that was +;; used to populate this profile.\n")) + (newline port) + (display "(list\n" port) + (for-each (lambda (name) + (define indent " ") + (match (vhash-foldq* cons '() name table) + ((channel extra ...) + (unless (null? extra) + (display indent port) + (format port (G_ "\ +;; Note: these other commits were also used to install \ +some of the packages in this profile:~%")) + (for-each (lambda (channel) + (format port "~a;; ~s~%" + indent (channel-commit channel))) + extra)) + (pretty-print (channel->code channel) port + #:per-line-prefix indent)))) + channel-names) + (display ")\n" port) + #t) + ;;; ;;; Command-line options. @@ -418,6 +467,8 @@ Install, remove, or upgrade packages in a single transaction.\n")) switch to a generation matching PATTERN")) (display (G_ " --export-manifest print a manifest for the chosen profile")) + (display (G_ " + --export-channels print channels for the chosen profile")) (display (G_ " -p, --profile=PROFILE use PROFILE instead of the user's default profile")) (display (G_ " @@ -556,6 +607,10 @@ kind of search path~%") (lambda (opt name arg result arg-handler) (values (cons `(query export-manifest) result) #f))) + (option '("export-channels") #f #f + (lambda (opt name arg result arg-handler) + (values (cons `(query export-channels) result) + #f))) (option '(#\p "profile") #t #f (lambda (opt name arg result arg-handler) (values (alist-cons 'profile (canonicalize-profile arg) @@ -882,6 +937,12 @@ processed, #f otherwise." (export-manifest manifest (current-output-port)) #t)) + (('export-channels) + (let ((manifest (concatenate-manifests + (map profile-manifest profiles)))) + (export-channels manifest (current-output-port)) + #t)) + (_ #f)))) -- 2.30.0