unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: "Ludovic Courtès" <ludo@gnu.org>
To: 49169@debbugs.gnu.org
Cc: "Ludovic Courtès" <ludo@gnu.org>
Subject: [bug#49169] [PATCH 05/11] packages: Add 'modify-inputs'.
Date: Tue, 22 Jun 2021 11:08:24 +0200	[thread overview]
Message-ID: <20210622090830.15561-5-ludo@gnu.org> (raw)
In-Reply-To: <20210622090830.15561-1-ludo@gnu.org>

* guix/packages.scm (inputs-sans-labels, replace-input): New procedures.
(prepend, replace, modify-inputs): New macros.
* doc/guix.texi (Defining Package Variants): Document 'modify-inputs'.
---
 doc/guix.texi     | 38 ++++++++++++++++++++------
 guix/packages.scm | 68 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 8 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index aeb0b2160a..b16a2c48a8 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -7105,20 +7105,42 @@ optional dependency, you can define a variant that removes that
 dependency like so:
 
 @lisp
-(use-modules (gnu packages gdb)    ;for 'gdb'
-             (srfi srfi-1))        ;for 'alist-delete'
+(use-modules (gnu packages gdb))   ;for 'gdb'
 
 (define gdb-sans-guile
   (package
     (inherit gdb)
-    (inputs (alist-delete "guile"
-                          (package-inputs gdb)))))
+    (inputs (modify-inputs (package-inputs gdb)
+              (delete "guile")))))
 @end lisp
 
-The @code{alist-delete} call above removes the tuple from the
-@code{inputs} field that has @code{"guile"} as its first element
-(@pxref{SRFI-1 Association Lists,,, guile, GNU Guile Reference
-Manual}).
+The @code{modify-inputs} form above removes the @code{"guile"} package
+from the @code{inputs} field of @code{gdb}.  The @code{modify-inputs}
+macro is a helper that can prove useful anytime you want to remove, add,
+or replace package inputs.
+
+@deffn {Scheme Syntax} modify-inputs @var{inputs} @var{clauses}
+Modify the given package inputs, as returned by @code{package-inputs} & co.,
+according to the given clauses.  The example below removes the GMP and ACL
+inputs of Coreutils and adds libcap to the back of the input list:
+
+@lisp
+(modify-inputs (package-inputs coreutils)
+  (delete "gmp" "acl")
+  (append libcap))
+@end lisp
+
+The example below replaces the @code{guile} package from the inputs of
+@code{guile-redis} with @code{guile-2.2}:
+
+@lisp
+(modify-inputs (package-inputs guile-redis)
+  (replace "guile" guile-2.2))
+@end lisp
+
+The last type of clause is @code{prepend}, to add inputs to the front of
+the list.
+@end deffn
 
 In some cases, you may find it useful to write functions
 (``procedures'', in Scheme parlance) that return a package based on some
diff --git a/guix/packages.scm b/guix/packages.scm
index c845026827..4ac1624ce2 100644
--- a/guix/packages.scm
+++ b/guix/packages.scm
@@ -55,6 +55,7 @@
   #:re-export (%current-system
                %current-target-system
                search-path-specification)         ;for convenience
+  #:re-export-and-replace (delete)                ;used as syntactic keyword
   #:export (content-hash
             content-hash?
             content-hash-algorithm
@@ -113,6 +114,10 @@
             lookup-package-propagated-input
             lookup-package-direct-input
 
+            prepend                               ;syntactic keyword
+            replace                               ;syntactic keyword
+            modify-inputs
+
             package-direct-sources
             package-transitive-sources
             package-direct-inputs
@@ -923,6 +928,69 @@ otherwise."
 otherwise."
   (lookup-input (package-direct-inputs package) name))
 
+(define (inputs-sans-labels inputs)
+  "Return INPUTS stripped of any input labels."
+  (map (match-lambda
+         ((label obj) obj)
+         ((label obj output) `(,obj ,output)))
+       inputs))
+
+(define (replace-input name replacement inputs)
+  "Replace input NAME by REPLACEMENT within INPUTS."
+  (map (lambda (input)
+         (match input
+           (((? string? label) . _)
+            (if (string=? label name)
+                (match replacement        ;does REPLACEMENT specify an output?
+                  ((_ _) (cons label replacement))
+                  (_     (list label replacement)))
+                input))))
+       inputs))
+
+(define-syntax prepend
+  (lambda (s)
+    (syntax-violation 'prepend
+                      "'prepend' may only be used within 'modify-inputs'"
+                      s)))
+
+(define-syntax replace
+  (lambda (s)
+    (syntax-violation 'replace
+                      "'replace' may only be used within 'modify-inputs'"
+                      s)))
+
+(define-syntax modify-inputs
+  (syntax-rules (delete prepend append replace)
+    "Modify the given package inputs, as returned by 'package-inputs' & co.,
+according to the given clauses.  The example below removes the GMP and ACL
+inputs of Coreutils and adds libcap:
+
+  (modify-inputs (package-inputs coreutils)
+    (delete \"gmp\" \"acl\")
+    (append libcap))
+
+Other types of clauses include 'prepend' and 'replace'."
+    ;; Note: This macro hides the fact that INPUTS, as returned by
+    ;; 'package-inputs' & co., is actually an alist with labels.  Eventually,
+    ;; it will operate on list of inputs without labels.
+    ((_ inputs (delete name) clauses ...)
+     (modify-inputs (alist-delete name inputs)
+                    clauses ...))
+    ((_ inputs (delete names ...) clauses ...)
+     (modify-inputs (fold alist-delete inputs (list names ...))
+                    clauses ...))
+    ((_ inputs (prepend lst ...) clauses ...)
+     (modify-inputs (append (list lst ...) (inputs-sans-labels inputs))
+                    clauses ...))
+    ((_ inputs (append lst ...) clauses ...)
+     (modify-inputs (append (inputs-sans-labels inputs) (list lst ...))
+                    clauses ...))
+    ((_ inputs (replace name replacement) clauses ...)
+     (modify-inputs (replace-input name replacement inputs)
+                    clauses ...))
+    ((_ inputs)
+     inputs)))
+
 (define (package-direct-sources package)
   "Return all source origins associated with PACKAGE; including origins in
 PACKAGE's inputs."
-- 
2.32.0





  parent reply	other threads:[~2021-06-22  9:09 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-22  9:02 [bug#49169] [PATCH 00/11] Removing input labels from package definitions Ludovic Courtès
2021-06-22  9:08 ` [bug#49169] [PATCH 01/11] records: Support field sanitizers Ludovic Courtès
2021-06-22  9:08   ` [bug#49169] [PATCH 02/11] packages: Allow inputs to be plain package lists Ludovic Courtès
2021-06-22  9:08   ` [bug#49169] [PATCH 03/11] lint: Add 'input-labels' checker Ludovic Courtès
2021-06-22  9:08   ` [bug#49169] [PATCH 04/11] packages: Add 'lookup-package-input' & co Ludovic Courtès
2021-06-22  9:08   ` Ludovic Courtès [this message]
2021-06-22  9:08   ` [bug#49169] [PATCH 06/11] gnu: Change inputs of core packages to plain lists Ludovic Courtès
2021-06-22  9:08   ` [bug#49169] [PATCH 07/11] utils: 'edit-expression' no longer leaks file ports Ludovic Courtès
2021-06-22  9:08   ` [bug#49169] [PATCH 08/11] utils: Add 'go-to-location' with source location caching Ludovic Courtès
2021-06-22  9:08   ` [bug#49169] [PATCH 09/11] utils: 'edit-expression' modifies the file only if necessary Ludovic Courtès
2021-06-22  9:08   ` [bug#49169] [PATCH 10/11] utils: 'edit-expression' copies part of the original source map Ludovic Courtès
2021-06-22  9:08   ` [bug#49169] [PATCH 11/11] Add 'guix style' Ludovic Courtès
2021-06-22  9:09 ` [bug#49169] [PATCH 00/11] Removing input labels from package definitions Ludovic Courtès
2021-06-27 18:37   ` Christopher Baines
2021-06-28  9:54     ` Ludovic Courtès
2021-06-27 11:00 ` Ludovic Courtès
2021-06-30 20:48 ` [bug#49169] [PATCH v2 00/16] " Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 01/16] records: Support field sanitizers Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 02/16] packages: Allow inputs to be plain package lists Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 03/16] lint: Add 'input-labels' checker Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 04/16] packages: Add 'lookup-package-input' & co Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 05/16] packages: Add 'modify-inputs' Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 06/16] gnu: Change inputs of core packages to plain lists Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 07/16] utils: 'edit-expression' no longer leaks file ports Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 08/16] utils: Add 'go-to-location' with source location caching Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 09/16] utils: 'edit-expression' modifies the file only if necessary Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 10/16] utils: 'edit-expression' copies part of the original source map Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 11/16] Add 'guix style' Ludovic Courtès
2021-07-01 14:13     ` zimoun
2021-06-30 20:48   ` [bug#49169] [PATCH v2 12/16] packages: 'hidden-package' inherits the original package location Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 13/16] import: pypi: Emit new-style package inputs Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 14/16] import: cran: " Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 15/16] import: print: Emit new-style package inputs when possible Ludovic Courtès
2021-06-30 20:48   ` [bug#49169] [PATCH v2 16/16] import: elpa: Emit new-style package inputs Ludovic Courtès
2021-07-10  4:53   ` [bug#49169] [PATCH 00/11] Removing input labels from package definitions Sarah Morgensen via Guix-patches via
2021-07-10 13:45     ` Ludovic Courtès
2021-07-10 23:15     ` Ludovic Courtès
2021-07-12  6:15       ` Sarah Morgensen via Guix-patches via
2021-07-12  8:47         ` Ludovic Courtès
2021-07-10 23:11   ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210622090830.15561-5-ludo@gnu.org \
    --to=ludo@gnu.org \
    --cc=49169@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).