transformations: Add '--with-version'.

This is a followup to 8aeccc6240.

* guix/transformations.scm (package-with-upstream-version): New procedure.
(transform-package-latest)[package-with-latest-upstream]: Remove.
Use 'package-with-upstream-version' instead.
(transform-package-version): New procedure.
(%transformations, %transformation-options)
(show-transformation-options-help/detailed): Add '-with-version'.
* tests/transformations.scm ("options->transformation, with-version"):
New test.
* doc/guix.texi (Package Transformation Options): Document '--with-version'.
(Defining Package Variants): Mention it.
This commit is contained in:
Ludovic Courtès 2023-01-07 15:22:14 +01:00
parent f094c3831f
commit 137b91f03b
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
3 changed files with 113 additions and 33 deletions

View File

@ -8073,8 +8073,9 @@ vintage!):
"0lappv4slgb5spyqbh6yl5r013zv72yqg2pcl30mginf3wdqd8k9"))))))
@end lisp
The example above corresponds to what the @option{--with-source} package
transformation option does. Essentially @code{hello-2.2} preserves all
The example above corresponds to what the @option{--with-version}
or @option{--with-source} package transformations option do.
Essentially @code{hello-2.2} preserves all
the fields of @code{hello}, except @code{version} and @code{source},
which it overrides. Note that the original @code{hello} variable is
still there, in the @code{(gnu packages base)} module, unchanged. When
@ -12740,7 +12741,9 @@ Coreutils in the dependency graph is rebuilt.
@cindex upstream, latest version
@item --with-latest=@var{package}
So you like living on the bleeding edge? This option is for you! It
@itemx --with-version=@var{package}=@var{version}
So you like living on the bleeding edge? The @option{--with-latest}
option is for you! It
replaces occurrences of @var{package} in the dependency graph with its
latest upstream version, as reported by @command{guix refresh}
(@pxref{Invoking guix refresh}).
@ -12756,6 +12759,26 @@ of Guile-JSON:
guix build guix --with-latest=guile-json
@end example
The @option{--with-version} works similarly except that it lets you
specify that you want precisely @var{version}, assuming that version
exists upstream. For example, to spawn a development environment with
SciPy built against version 1.22.4 of NumPy (skipping its test suite
because hey, we're not gonna wait this long), you would run:
@example
guix shell python python-scipy --with-version=python-numpy=1.22.4
@end example
@quotation Warning
Because they depend on source code published at a given point in time on
upstream servers, deployments made with @option{--with-latest} and
@option{--with-version} may be non-reproducible: source might disappear
or be modified in place on the servers.
To deploy old software versions without compromising on reproducibility,
@ref{Invoking guix time-machine, @command{guix time-machine}}.
@end quotation
There are limitations. First, in cases where the tool cannot or does
not know how to authenticate source code, you are at risk of running
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
that need to be added, patches to apply, and more generally the quality
assurance work that Guix developers normally do will be missing.
You've been warned! In all the other cases, it's a snappy way to stay
on top. We encourage you to submit patches updating the actual package
definitions once you have successfully tested an upgrade
(@pxref{Contributing}).
You've been warned! When those limitations are acceptable, it's a
snappy way to stay on top. We encourage you to submit patches updating
the actual package definitions once you have successfully tested an
upgrade with @option{--with-latest} (@pxref{Contributing}).
@cindex test suite, skipping
@item --without-tests=@var{package}

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016-2022 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2016-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
;;;
;;; This file is part of GNU Guix.
@ -757,35 +757,69 @@ additional patches."
(rewrite obj)
obj)))
(define* (package-with-upstream-version p #:optional version)
"Return package P changed to use the given upstream VERSION or, if VERSION
is #f, the latest known upstream version."
(let ((source (package-latest-release p #:version version)))
(cond ((not source)
(if version
(warning
(G_ "could not find version ~a of '~a' upstream~%")
version (package-name p))
(warning
(G_ "could not determine latest upstream release of '~a'~%")
(package-name p)))
p)
((string=? (upstream-source-version source)
(package-version p))
p)
(else
(when (version>? (package-version p)
(upstream-source-version source))
(warning (G_ "using ~a ~a, which is older than the packaged \
version (~a)~%")
(package-name p)
(upstream-source-version source)
(package-version p)))
(unless (pair? (upstream-source-signature-urls source))
(warning (G_ "cannot authenticate source of '~a', version ~a~%")
(package-name p)
(upstream-source-version source)))
;; TODO: Take 'upstream-source-input-changes' into account.
(package
(inherit p)
(version (upstream-source-version source))
(source source))))))
(define (transform-package-latest specs)
"Return a procedure that rewrites package graphs such that those in SPECS
are replaced by their latest upstream version."
(define (package-with-latest-upstream p)
(let ((source (package-latest-release p)))
(cond ((not source)
(warning
(G_ "could not determine latest upstream release of '~a'~%")
(package-name p))
p)
((string=? (upstream-source-version source)
(package-version p))
p)
(else
(unless (pair? (upstream-source-signature-urls source))
(warning (G_ "cannot authenticate source of '~a', version ~a~%")
(package-name p)
(upstream-source-version source)))
;; TODO: Take 'upstream-source-input-changes' into account.
(package
(inherit p)
(version (upstream-source-version source))
(source source))))))
(define rewrite
(package-input-rewriting/spec
(map (lambda (spec)
(cons spec package-with-latest-upstream))
(cons spec package-with-upstream-version))
specs)))
(lambda (obj)
(if (package? obj)
(rewrite obj)
obj)))
(define (transform-package-version specs)
"Return a procedure that rewrites package graphs such that those in SPECS
are replaced by the specified upstream version."
(define rewrite
(package-input-rewriting/spec
(map (lambda (spec)
(match (string-tokenize spec %not-equal)
((spec version)
(cons spec (cut package-with-upstream-version <> version)))
(_
(raise (formatted-message
(G_ "~a: invalid upstream version specification")
spec)))))
specs)))
(lambda (obj)
@ -809,7 +843,8 @@ are replaced by their latest upstream version."
(with-debug-info . ,transform-package-with-debug-info)
(without-tests . ,transform-package-tests)
(with-patch . ,transform-package-patches)
(with-latest . ,transform-package-latest)))
(with-latest . ,transform-package-latest)
(with-version . ,transform-package-version)))
(define (transformation-procedure key)
"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~%")
(parser 'with-patch))
(option '("with-latest") #t #f
(parser 'with-latest))
(option '("with-version") #t #f
(parser 'with-version))
(option '("help-transform") #f #f
(lambda _
@ -915,6 +952,9 @@ building for ~a instead of ~a, so tuning cannot be guessed~%")
(display (G_ "
--with-latest=PACKAGE
use the latest upstream release of PACKAGE"))
(display (G_ "
--with-version=PACKAGE=VERSION
use the given upstream VERSION of PACKAGE"))
(display (G_ "
--with-c-toolchain=PACKAGE=TOOLCHAIN
build PACKAGE and its dependents with TOOLCHAIN"))

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016-2017, 2019-2022 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2016-2017, 2019-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
;;;
;;; This file is part of GNU Guix.
@ -497,6 +497,23 @@
`((with-latest . "foo")))))
(package-version (t p)))))
(test-equal "options->transformation, with-version"
"1.0"
(mock ((guix upstream) %updaters
(delay (list (upstream-updater
(name 'dummy)
(pred (const #t))
(description "")
(import (const (upstream-source
(package "foo")
(version "1.0")
(urls '("http://example.org")))))))))
(let* ((p0 (dummy-package "foo" (version "7.7")))
(p1 (dummy-package "bar" (inputs (list p0))))
(t (options->transformation
`((with-version . "foo=1.0")))))
(package-version (lookup-package-input (t p1) "foo")))))
(test-equal "options->transformation, tune"
'(cpu-tuning . "superfast")
(let* ((p0 (dummy-package "p0"))