summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2020-09-25 17:16:34 +0200
committerLudovic Courtès <ludo@gnu.org>2020-10-02 23:28:09 +0200
commit8e1907a72430aa989125b053573ef0897c480697 (patch)
tree99e70ccfd1af5205bc731930733299852cae9658
parentad54a73bb820a685f242976a86be63931789fa97 (diff)
downloadguix-8e1907a72430aa989125b053573ef0897c480697.tar.gz
guix package: Re-apply package transformation when upgrading.
* guix/scripts/package.scm (transaction-upgrade-entry)[upgrade]: Add
'transform' parameter.  Pass PKG through it.  Use
'manifest-entry-with-transformations'.
Call 'options->transformation' to get the transformation procedure.
* tests/guix-package.sh: Add 'guix package -u' test.
* tests/packages.scm ("transaction-upgrade-entry, transformation options preserved"):
New test.
* doc/guix.texi (Invoking guix package): Mention that transformations
are preserved across upgrades.
(Package Transformation Options): Likewise.
-rw-r--r--doc/guix.texi27
-rw-r--r--guix/scripts/package.scm20
-rw-r--r--tests/guix-package.sh15
-rw-r--r--tests/packages.scm23
4 files changed, 80 insertions, 5 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index da48c8a72d..a6260a12aa 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -3101,6 +3101,29 @@ in the distribution currently installed.  To update your distribution,
 you should regularly run @command{guix pull} (@pxref{Invoking guix
 pull}).
 
+@cindex package transformations, upgrades
+When upgrading, package transformations that were originally applied
+when creating the profile are automatically re-applied (@pxref{Package
+Transformation Options}).  For example, assume you first installed Emacs
+from the tip of its development branch with:
+
+@example
+guix install emacs-next --with-branch=emacs-next=master
+@end example
+
+Next time you run @command{guix upgrade}, Guix will again pull the tip
+of the Emacs development branch and build @code{emacs-next} from that
+checkout.
+
+Note that transformation options such as @option{--with-branch} and
+@option{--with-source} depend on external state; it is up to you to
+ensure that they work as expected.  You can also discard a
+transformations that apply to a package by running:
+
+@example
+guix install @var{package}
+@end example
+
 @item --do-not-upgrade[=@var{regexp} @dots{}]
 When used together with the @option{--upgrade} option, do @emph{not}
 upgrade any packages whose name matches a @var{regexp}.  For example, to
@@ -9193,6 +9216,10 @@ This is a convenient way to create customized packages on the fly
 without having to type in the definitions of package variants
 (@pxref{Defining Packages}).
 
+Package transformation options are preserved across upgrades:
+@command{guix upgrade} attempts to apply transformation options
+initially used when creating the profile to the upgraded packages.
+
 @table @code
 
 @item --with-source=@var{source}
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm
index 83f8c123d9..2f04652634 100644
--- a/guix/scripts/package.scm
+++ b/guix/scripts/package.scm
@@ -218,12 +218,13 @@ non-zero relevance score."
         (output (manifest-entry-output old)))
       transaction)))
 
-  (define (upgrade entry)
+  (define (upgrade entry transform)
     (match entry
       (($ <manifest-entry> name version output (? string? path))
        (match (find-best-packages-by-name name #f)
          ((pkg . rest)
-          (let ((candidate-version (package-version pkg)))
+          (let* ((pkg               (transform store pkg))
+                 (candidate-version (package-version pkg)))
             (match (package-superseded pkg)
               ((? package? new)
                (supersede entry new))
@@ -231,12 +232,14 @@ non-zero relevance score."
                (case (version-compare candidate-version version)
                  ((>)
                   (manifest-transaction-install-entry
-                   (package->manifest-entry* pkg output)
+                   (manifest-entry-with-transformations
+                    (package->manifest-entry* pkg output))
                    transaction))
                  ((<)
                   transaction)
                  ((=)
-                  (let* ((new (package->manifest-entry* pkg output)))
+                  (let* ((new (manifest-entry-with-transformations
+                               (package->manifest-entry* pkg output))))
                     ;; Here we want to determine whether the NEW actually
                     ;; differs from ENTRY, but we need to intercept
                     ;; 'build-things' calls because they would prevent us from
@@ -255,7 +258,14 @@ non-zero relevance score."
 
   (if (manifest-transaction-removal-candidate? entry transaction)
       transaction
-      (upgrade entry)))
+
+      ;; Upgrade ENTRY, preserving transformation options listed in its
+      ;; properties.
+      (let ((transform (options->transformation
+                        (or (assq-ref (manifest-entry-properties entry)
+                                      'transformations)
+                            '()))))
+        (upgrade entry transform))))
 
 
 ;;;
diff --git a/tests/guix-package.sh b/tests/guix-package.sh
index a43496699b..3e5fa71d20 100644
--- a/tests/guix-package.sh
+++ b/tests/guix-package.sh
@@ -184,6 +184,21 @@ grep -E 'emacs[[:blank:]]+42\.5\.9rc7' "$tmpfile"
 rm "$emacs_tarball" "$tmpfile"
 rmdir "$module_dir"
 
+# Install with package transformations.
+guix install --bootstrap -p "$profile" sed --with-input=sed=guile-bootstrap
+grep "sed=guile-bootstrap" "$profile/manifest"
+test "$(readlink -f "$profile/bin/guile")" \
+     = "$(guix build guile-bootstrap)/bin/guile"
+test ! -f "$profile/bin/sed"
+
+# Make sure the package transformation is preserved.
+guix package --bootstrap -p "$profile" -u
+grep "sed=guile-bootstrap" "$profile/manifest"
+test "$(readlink -f "$profile/bin/guile")" \
+     = "$(guix build guile-bootstrap)/bin/guile"
+test ! -f "$profile/bin/sed"
+rm "$profile" "$profile"-[0-9]-link
+
 # Profiles with a relative file name.  Make sure we don't create dangling
 # symlinks--see bug report at
 # <https://lists.gnu.org/archive/html/guix-devel/2018-07/msg00036.html>.
diff --git a/tests/packages.scm b/tests/packages.scm
index af8941c2e2..5d5abcbd76 100644
--- a/tests/packages.scm
+++ b/tests/packages.scm
@@ -187,6 +187,29 @@
                  (string=? (manifest-pattern-version pattern) "1")
                  (string=? (manifest-pattern-output pattern) "out")))))))
 
+(test-equal "transaction-upgrade-entry, transformation options preserved"
+  (derivation-file-name (package-derivation %store grep))
+
+  (let* ((old   (dummy-package "emacs" (version "1")))
+         (props '((transformations . ((with-input . "emacs=grep")))))
+         (tx    (transaction-upgrade-entry
+                 %store
+                 (manifest-entry
+                   (inherit (package->manifest-entry old))
+                   (properties props)
+                   (item (string-append (%store-prefix) "/"
+                                        (make-string 32 #\e) "-foo-1")))
+                 (manifest-transaction))))
+    (match (manifest-transaction-install tx)
+      (((? manifest-entry? entry))
+       (and (string=? (manifest-entry-version entry)
+                      (package-version grep))
+            (string=? (manifest-entry-name entry)
+                      (package-name grep))
+            (equal? (manifest-entry-properties entry) props)
+            (derivation-file-name
+             (package-derivation %store (manifest-entry-item entry))))))))
+
 (test-assert "transaction-upgrade-entry, grafts"
   ;; Ensure that, when grafts are enabled, 'transaction-upgrade-entry' doesn't
   ;; try to build stuff.