diff options
| -rw-r--r-- | doc/guix.texi | 37 | ||||
| -rw-r--r-- | guix/transformations.scm | 88 | ||||
| -rw-r--r-- | tests/transformations.scm | 19 |
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 | ||
| 8076 | The example above corresponds to what the @option{--with-source} package | 8076 | The example above corresponds to what the @option{--with-version} |
| 8077 | transformation option does. Essentially @code{hello-2.2} preserves all | 8077 | or @option{--with-source} package transformations option do. |
| 8078 | Essentially @code{hello-2.2} preserves all | ||
| 8078 | the fields of @code{hello}, except @code{version} and @code{source}, | 8079 | the fields of @code{hello}, except @code{version} and @code{source}, |
| 8079 | which it overrides. Note that the original @code{hello} variable is | 8080 | which it overrides. Note that the original @code{hello} variable is |
| 8080 | still there, in the @code{(gnu packages base)} module, unchanged. When | 8081 | still 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} |
| 12743 | So you like living on the bleeding edge? This option is for you! It | 12744 | @itemx --with-version=@var{package}=@var{version} |
| 12745 | So you like living on the bleeding edge? The @option{--with-latest} | ||
| 12746 | option is for you! It | ||
| 12744 | replaces occurrences of @var{package} in the dependency graph with its | 12747 | replaces occurrences of @var{package} in the dependency graph with its |
| 12745 | latest upstream version, as reported by @command{guix refresh} | 12748 | latest 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: | |||
| 12756 | guix build guix --with-latest=guile-json | 12759 | guix build guix --with-latest=guile-json |
| 12757 | @end example | 12760 | @end example |
| 12758 | 12761 | ||
| 12762 | The @option{--with-version} works similarly except that it lets you | ||
| 12763 | specify that you want precisely @var{version}, assuming that version | ||
| 12764 | exists upstream. For example, to spawn a development environment with | ||
| 12765 | SciPy built against version 1.22.4 of NumPy (skipping its test suite | ||
| 12766 | because hey, we're not gonna wait this long), you would run: | ||
| 12767 | |||
| 12768 | @example | ||
| 12769 | guix shell python python-scipy --with-version=python-numpy=1.22.4 | ||
| 12770 | @end example | ||
| 12771 | |||
| 12772 | @quotation Warning | ||
| 12773 | Because they depend on source code published at a given point in time on | ||
| 12774 | upstream servers, deployments made with @option{--with-latest} and | ||
| 12775 | @option{--with-version} may be non-reproducible: source might disappear | ||
| 12776 | or be modified in place on the servers. | ||
| 12777 | |||
| 12778 | To deploy old software versions without compromising on reproducibility, | ||
| 12779 | @ref{Invoking guix time-machine, @command{guix time-machine}}. | ||
| 12780 | @end quotation | ||
| 12781 | |||
| 12759 | There are limitations. First, in cases where the tool cannot or does | 12782 | There are limitations. First, in cases where the tool cannot or does |
| 12760 | not know how to authenticate source code, you are at risk of running | 12783 | not know how to authenticate source code, you are at risk of running |
| 12761 | malicious code; a warning is emitted in this case. Second, this option | 12784 | malicious 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 | |||
| 12764 | that need to be added, patches to apply, and more generally the quality | 12787 | that need to be added, patches to apply, and more generally the quality |
| 12765 | assurance work that Guix developers normally do will be missing. | 12788 | assurance work that Guix developers normally do will be missing. |
| 12766 | 12789 | ||
| 12767 | You've been warned! In all the other cases, it's a snappy way to stay | 12790 | You've been warned! When those limitations are acceptable, it's a |
| 12768 | on top. We encourage you to submit patches updating the actual package | 12791 | snappy way to stay on top. We encourage you to submit patches updating |
| 12769 | definitions once you have successfully tested an upgrade | 12792 | the actual package definitions once you have successfully tested an |
| 12770 | (@pxref{Contributing}). | 12793 | upgrade 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 | ||
| 762 | is #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 \ | ||
| 780 | version (~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 |
| 762 | are replaced by their latest upstream version." | 798 | are 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 | ||
| 812 | are 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")) |
