summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi37
-rw-r--r--guix/transformations.scm88
-rw-r--r--tests/transformations.scm19
3 files changed, 112 insertions, 32 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 9bcaf8ff784..acb0a6da9b2 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8073,8 +8073,9 @@ vintage!):
8073 "0lappv4slgb5spyqbh6yl5r013zv72yqg2pcl30mginf3wdqd8k9")))))) 8073 "0lappv4slgb5spyqbh6yl5r013zv72yqg2pcl30mginf3wdqd8k9"))))))
8074@end lisp 8074@end lisp
8075 8075
8076The example above corresponds to what the @option{--with-source} package 8076The example above corresponds to what the @option{--with-version}
8077transformation option does. Essentially @code{hello-2.2} preserves all 8077or @option{--with-source} package transformations option do.
8078Essentially @code{hello-2.2} preserves all
8078the fields of @code{hello}, except @code{version} and @code{source}, 8079the fields of @code{hello}, except @code{version} and @code{source},
8079which it overrides. Note that the original @code{hello} variable is 8080which it overrides. Note that the original @code{hello} variable is
8080still there, in the @code{(gnu packages base)} module, unchanged. When 8081still there, in the @code{(gnu packages base)} module, unchanged. When
@@ -12740,7 +12741,9 @@ Coreutils in the dependency graph is rebuilt.
12740 12741
12741@cindex upstream, latest version 12742@cindex upstream, latest version
12742@item --with-latest=@var{package} 12743@item --with-latest=@var{package}
12743So you like living on the bleeding edge? This option is for you! It 12744@itemx --with-version=@var{package}=@var{version}
12745So you like living on the bleeding edge? The @option{--with-latest}
12746option is for you! It
12744replaces occurrences of @var{package} in the dependency graph with its 12747replaces occurrences of @var{package} in the dependency graph with its
12745latest upstream version, as reported by @command{guix refresh} 12748latest upstream version, as reported by @command{guix refresh}
12746(@pxref{Invoking guix refresh}). 12749(@pxref{Invoking guix refresh}).
@@ -12756,6 +12759,26 @@ of Guile-JSON:
12756guix build guix --with-latest=guile-json 12759guix build guix --with-latest=guile-json
12757@end example 12760@end example
12758 12761
12762The @option{--with-version} works similarly except that it lets you
12763specify that you want precisely @var{version}, assuming that version
12764exists upstream. For example, to spawn a development environment with
12765SciPy built against version 1.22.4 of NumPy (skipping its test suite
12766because hey, we're not gonna wait this long), you would run:
12767
12768@example
12769guix shell python python-scipy --with-version=python-numpy=1.22.4
12770@end example
12771
12772@quotation Warning
12773Because they depend on source code published at a given point in time on
12774upstream servers, deployments made with @option{--with-latest} and
12775@option{--with-version} may be non-reproducible: source might disappear
12776or be modified in place on the servers.
12777
12778To deploy old software versions without compromising on reproducibility,
12779@ref{Invoking guix time-machine, @command{guix time-machine}}.
12780@end quotation
12781
12759There are limitations. First, in cases where the tool cannot or does 12782There are limitations. First, in cases where the tool cannot or does
12760not know how to authenticate source code, you are at risk of running 12783not know how to authenticate source code, you are at risk of running
12761malicious code; a warning is emitted in this case. Second, this option 12784malicious code; a warning is emitted in this case. Second, this option
@@ -12764,10 +12787,10 @@ which is not always sufficient: there might be additional dependencies
12764that need to be added, patches to apply, and more generally the quality 12787that need to be added, patches to apply, and more generally the quality
12765assurance work that Guix developers normally do will be missing. 12788assurance work that Guix developers normally do will be missing.
12766 12789
12767You've been warned! In all the other cases, it's a snappy way to stay 12790You've been warned! When those limitations are acceptable, it's a
12768on top. We encourage you to submit patches updating the actual package 12791snappy way to stay on top. We encourage you to submit patches updating
12769definitions once you have successfully tested an upgrade 12792the actual package definitions once you have successfully tested an
12770(@pxref{Contributing}). 12793upgrade with @option{--with-latest} (@pxref{Contributing}).
12771 12794
12772@cindex test suite, skipping 12795@cindex test suite, skipping
12773@item --without-tests=@var{package} 12796@item --without-tests=@var{package}
diff --git a/guix/transformations.scm b/guix/transformations.scm
index bf9639020b4..8853f390ce8 100644
--- a/guix/transformations.scm
+++ b/guix/transformations.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016-2022 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2016-2023 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2021 Marius Bakke <marius@gnu.org> 3;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
4;;; 4;;;
5;;; This file is part of GNU Guix. 5;;; This file is part of GNU Guix.
@@ -757,35 +757,69 @@ additional patches."
757 (rewrite obj) 757 (rewrite obj)
758 obj))) 758 obj)))
759 759
760(define* (package-with-upstream-version p #:optional version)
761 "Return package P changed to use the given upstream VERSION or, if VERSION
762is #f, the latest known upstream version."
763 (let ((source (package-latest-release p #:version version)))
764 (cond ((not source)
765 (if version
766 (warning
767 (G_ "could not find version ~a of '~a' upstream~%")
768 version (package-name p))
769 (warning
770 (G_ "could not determine latest upstream release of '~a'~%")
771 (package-name p)))
772 p)
773 ((string=? (upstream-source-version source)
774 (package-version p))
775 p)
776 (else
777 (when (version>? (package-version p)
778 (upstream-source-version source))
779 (warning (G_ "using ~a ~a, which is older than the packaged \
780version (~a)~%")
781 (package-name p)
782 (upstream-source-version source)
783 (package-version p)))
784
785 (unless (pair? (upstream-source-signature-urls source))
786 (warning (G_ "cannot authenticate source of '~a', version ~a~%")
787 (package-name p)
788 (upstream-source-version source)))
789
790 ;; TODO: Take 'upstream-source-input-changes' into account.
791 (package
792 (inherit p)
793 (version (upstream-source-version source))
794 (source source))))))
795
760(define (transform-package-latest specs) 796(define (transform-package-latest specs)
761 "Return a procedure that rewrites package graphs such that those in SPECS 797 "Return a procedure that rewrites package graphs such that those in SPECS
762are replaced by their latest upstream version." 798are replaced by their latest upstream version."
763 (define (package-with-latest-upstream p) 799 (define rewrite
764 (let ((source (package-latest-release p))) 800 (package-input-rewriting/spec
765 (cond ((not source) 801 (map (lambda (spec)
766 (warning 802 (cons spec package-with-upstream-version))
767 (G_ "could not determine latest upstream release of '~a'~%") 803 specs)))
768 (package-name p))
769 p)
770 ((string=? (upstream-source-version source)
771 (package-version p))
772 p)
773 (else
774 (unless (pair? (upstream-source-signature-urls source))
775 (warning (G_ "cannot authenticate source of '~a', version ~a~%")
776 (package-name p)
777 (upstream-source-version source)))
778
779 ;; TODO: Take 'upstream-source-input-changes' into account.
780 (package
781 (inherit p)
782 (version (upstream-source-version source))
783 (source source))))))
784 804
805 (lambda (obj)
806 (if (package? obj)
807 (rewrite obj)
808 obj)))
809
810(define (transform-package-version specs)
811 "Return a procedure that rewrites package graphs such that those in SPECS
812are replaced by the specified upstream version."
785 (define rewrite 813 (define rewrite
786 (package-input-rewriting/spec 814 (package-input-rewriting/spec
787 (map (lambda (spec) 815 (map (lambda (spec)
788 (cons spec package-with-latest-upstream)) 816 (match (string-tokenize spec %not-equal)
817 ((spec version)
818 (cons spec (cut package-with-upstream-version <> version)))
819 (_
820 (raise (formatted-message
821 (G_ "~a: invalid upstream version specification")
822 spec)))))
789 specs))) 823 specs)))
790 824
791 (lambda (obj) 825 (lambda (obj)
@@ -809,7 +843,8 @@ are replaced by their latest upstream version."
809 (with-debug-info . ,transform-package-with-debug-info) 843 (with-debug-info . ,transform-package-with-debug-info)
810 (without-tests . ,transform-package-tests) 844 (without-tests . ,transform-package-tests)
811 (with-patch . ,transform-package-patches) 845 (with-patch . ,transform-package-patches)
812 (with-latest . ,transform-package-latest))) 846 (with-latest . ,transform-package-latest)
847 (with-version . ,transform-package-version)))
813 848
814(define (transformation-procedure key) 849(define (transformation-procedure key)
815 "Return the transformation procedure associated with KEY, a symbol such as 850 "Return the transformation procedure associated with KEY, a symbol such as
@@ -881,6 +916,8 @@ building for ~a instead of ~a, so tuning cannot be guessed~%")
881 (parser 'with-patch)) 916 (parser 'with-patch))
882 (option '("with-latest") #t #f 917 (option '("with-latest") #t #f
883 (parser 'with-latest)) 918 (parser 'with-latest))
919 (option '("with-version") #t #f
920 (parser 'with-version))
884 921
885 (option '("help-transform") #f #f 922 (option '("help-transform") #f #f
886 (lambda _ 923 (lambda _
@@ -916,6 +953,9 @@ building for ~a instead of ~a, so tuning cannot be guessed~%")
916 --with-latest=PACKAGE 953 --with-latest=PACKAGE
917 use the latest upstream release of PACKAGE")) 954 use the latest upstream release of PACKAGE"))
918 (display (G_ " 955 (display (G_ "
956 --with-version=PACKAGE=VERSION
957 use the given upstream VERSION of PACKAGE"))
958 (display (G_ "
919 --with-c-toolchain=PACKAGE=TOOLCHAIN 959 --with-c-toolchain=PACKAGE=TOOLCHAIN
920 build PACKAGE and its dependents with TOOLCHAIN")) 960 build PACKAGE and its dependents with TOOLCHAIN"))
921 (display (G_ " 961 (display (G_ "
diff --git a/tests/transformations.scm b/tests/transformations.scm
index 5c136e1d48e..1fa2c0bba82 100644
--- a/tests/transformations.scm
+++ b/tests/transformations.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016-2017, 2019-2022 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2016-2017, 2019-2023 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2021 Marius Bakke <marius@gnu.org> 3;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
4;;; 4;;;
5;;; This file is part of GNU Guix. 5;;; This file is part of GNU Guix.
@@ -497,6 +497,23 @@
497 `((with-latest . "foo"))))) 497 `((with-latest . "foo")))))
498 (package-version (t p))))) 498 (package-version (t p)))))
499 499
500(test-equal "options->transformation, with-version"
501 "1.0"
502 (mock ((guix upstream) %updaters
503 (delay (list (upstream-updater
504 (name 'dummy)
505 (pred (const #t))
506 (description "")
507 (import (const (upstream-source
508 (package "foo")
509 (version "1.0")
510 (urls '("http://example.org")))))))))
511 (let* ((p0 (dummy-package "foo" (version "7.7")))
512 (p1 (dummy-package "bar" (inputs (list p0))))
513 (t (options->transformation
514 `((with-version . "foo=1.0")))))
515 (package-version (lookup-package-input (t p1) "foo")))))
516
500(test-equal "options->transformation, tune" 517(test-equal "options->transformation, tune"
501 '(cpu-tuning . "superfast") 518 '(cpu-tuning . "superfast")
502 (let* ((p0 (dummy-package "p0")) 519 (let* ((p0 (dummy-package "p0"))