guix build: Add '--with-branch' transformation option.
* guix/scripts/build.scm (evaluate-git-replacement-specs) (transform-package-source-branch): New procedures. (%transformations, %transformation-options): Add 'with-branch'. (show-transformation-options-help): Likewise. * tests/guix-build-branch.sh: New file. * Makefile.am (SH_TESTS): Add it. * doc/guix.texi (Package Transformation Options): Document it.
This commit is contained in:
parent
49ae3f6d89
commit
96915a448c
|
@ -407,6 +407,7 @@ endif
|
||||||
|
|
||||||
SH_TESTS = \
|
SH_TESTS = \
|
||||||
tests/guix-build.sh \
|
tests/guix-build.sh \
|
||||||
|
tests/guix-build-branch.sh \
|
||||||
tests/guix-download.sh \
|
tests/guix-download.sh \
|
||||||
tests/guix-gc.sh \
|
tests/guix-gc.sh \
|
||||||
tests/guix-hash.sh \
|
tests/guix-hash.sh \
|
||||||
|
|
|
@ -6451,6 +6451,33 @@ must be compatible. If @var{replacement} is somehow incompatible with
|
||||||
@var{package}, then the resulting package may be unusable. Use with
|
@var{package}, then the resulting package may be unusable. Use with
|
||||||
care!
|
care!
|
||||||
|
|
||||||
|
@item --with-branch=@var{package}=@var{branch}
|
||||||
|
@cindex Git, using the latest commit
|
||||||
|
@cindex latest commit, building
|
||||||
|
Build @var{package} from the latest commit of @var{branch}. The @code{source}
|
||||||
|
field of @var{package} must be an origin with the @code{git-fetch} method
|
||||||
|
(@pxref{origin Reference}) or a @code{git-checkout} object; the repository URL
|
||||||
|
is taken from that @code{source}.
|
||||||
|
|
||||||
|
For instance, the following command builds @code{guile-sqlite3} from the
|
||||||
|
latest commit of its @code{master} branch, and then builds @code{guix} (which
|
||||||
|
depends on it) and @code{cuirass} (which depends on @code{guix}) against this
|
||||||
|
specific @code{guile-sqlite3} build:
|
||||||
|
|
||||||
|
@example
|
||||||
|
guix build --with-branch=guile-sqlite3=master cuirass
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@cindex continuous integration
|
||||||
|
Obviously, since it uses the latest commit of the given branch, the result of
|
||||||
|
such a command varies over time. Nevertheless it is a convenient way to
|
||||||
|
rebuild entire software stacks against the latest commit of one or more
|
||||||
|
packages. This is particularly useful in the context of continuous
|
||||||
|
integration (CI).
|
||||||
|
|
||||||
|
Checkouts are kept in a cache under @file{~/.cache/guix/checkouts} to speed up
|
||||||
|
consecutive accesses to the same repository. You may want to clean it up once
|
||||||
|
in a while to save disk space.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@node Additional Build Options
|
@node Additional Build Options
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#:use-module (srfi srfi-37)
|
#:use-module (srfi srfi-37)
|
||||||
#:autoload (gnu packages) (specification->package %package-module-path)
|
#:autoload (gnu packages) (specification->package %package-module-path)
|
||||||
#:autoload (guix download) (download-to-store)
|
#:autoload (guix download) (download-to-store)
|
||||||
|
#:autoload (guix git-download) (git-reference?)
|
||||||
|
#:autoload (guix git) (git-checkout?)
|
||||||
#:use-module (guix status)
|
#:use-module (guix status)
|
||||||
#:use-module ((guix progress) #:select (current-terminal-columns))
|
#:use-module ((guix progress) #:select (current-terminal-columns))
|
||||||
#:use-module ((guix build syscalls) #:select (terminal-columns))
|
#:use-module ((guix build syscalls) #:select (terminal-columns))
|
||||||
|
@ -270,6 +272,48 @@ current 'gnutls' package, after which version 3.5.4 is grafted onto them."
|
||||||
(rewrite obj)
|
(rewrite obj)
|
||||||
obj))))
|
obj))))
|
||||||
|
|
||||||
|
(define (evaluate-git-replacement-specs specs)
|
||||||
|
"Parse SPECS, a list of strings like \"guile=stable-2.2\", and return a list
|
||||||
|
of package pairs. Raise an error if an element of SPECS uses invalid syntax,
|
||||||
|
or if a package it refers to could not be found."
|
||||||
|
(define not-equal
|
||||||
|
(char-set-complement (char-set #\=)))
|
||||||
|
|
||||||
|
(map (lambda (spec)
|
||||||
|
(match (string-tokenize spec not-equal)
|
||||||
|
((name branch)
|
||||||
|
(let* ((old (specification->package name))
|
||||||
|
(source (package-source old))
|
||||||
|
(url (cond ((and (origin? source)
|
||||||
|
(git-reference? (origin-uri source)))
|
||||||
|
(git-reference-url (origin-uri source)))
|
||||||
|
((git-checkout? source)
|
||||||
|
(git-checkout-url source))
|
||||||
|
(else
|
||||||
|
(leave (G_ "the source of ~a is not a Git \
|
||||||
|
reference~%")
|
||||||
|
(package-full-name old))))))
|
||||||
|
(cons old
|
||||||
|
(package
|
||||||
|
(inherit old)
|
||||||
|
(version (string-append "git." branch))
|
||||||
|
(source (git-checkout (url url) (branch branch)))))))
|
||||||
|
(x
|
||||||
|
(leave (G_ "invalid replacement specification: ~s~%") spec))))
|
||||||
|
specs))
|
||||||
|
|
||||||
|
(define (transform-package-source-branch replacement-specs)
|
||||||
|
"Return a procedure that, when passed a package, replaces its direct
|
||||||
|
dependencies according to REPLACEMENT-SPECS. REPLACEMENT-SPECS is a list of
|
||||||
|
strings like \"guile-next=stable-3.0\" meaning that packages are built using
|
||||||
|
'guile-next' from the latest commit on its 'stable-3.0' branch."
|
||||||
|
(let* ((replacements (evaluate-git-replacement-specs replacement-specs))
|
||||||
|
(rewrite (package-input-rewriting replacements)))
|
||||||
|
(lambda (store obj)
|
||||||
|
(if (package? obj)
|
||||||
|
(rewrite obj)
|
||||||
|
obj))))
|
||||||
|
|
||||||
(define %transformations
|
(define %transformations
|
||||||
;; Transformations that can be applied to things to build. The car is the
|
;; Transformations that can be applied to things to build. The car is the
|
||||||
;; key used in the option alist, and the cdr is the transformation
|
;; key used in the option alist, and the cdr is the transformation
|
||||||
|
@ -277,7 +321,8 @@ current 'gnutls' package, after which version 3.5.4 is grafted onto them."
|
||||||
;; things to build.
|
;; things to build.
|
||||||
`((with-source . ,transform-package-source)
|
`((with-source . ,transform-package-source)
|
||||||
(with-input . ,transform-package-inputs)
|
(with-input . ,transform-package-inputs)
|
||||||
(with-graft . ,transform-package-inputs/graft)))
|
(with-graft . ,transform-package-inputs/graft)
|
||||||
|
(with-branch . ,transform-package-source-branch)))
|
||||||
|
|
||||||
(define %transformation-options
|
(define %transformation-options
|
||||||
;; The command-line interface to the above transformations.
|
;; The command-line interface to the above transformations.
|
||||||
|
@ -291,7 +336,9 @@ current 'gnutls' package, after which version 3.5.4 is grafted onto them."
|
||||||
(option '("with-input") #t #f
|
(option '("with-input") #t #f
|
||||||
(parser 'with-input))
|
(parser 'with-input))
|
||||||
(option '("with-graft") #t #f
|
(option '("with-graft") #t #f
|
||||||
(parser 'with-graft)))))
|
(parser 'with-graft))
|
||||||
|
(option '("with-branch") #t #f
|
||||||
|
(parser 'with-branch)))))
|
||||||
|
|
||||||
(define (show-transformation-options-help)
|
(define (show-transformation-options-help)
|
||||||
(display (G_ "
|
(display (G_ "
|
||||||
|
@ -302,7 +349,10 @@ current 'gnutls' package, after which version 3.5.4 is grafted onto them."
|
||||||
replace dependency PACKAGE by REPLACEMENT"))
|
replace dependency PACKAGE by REPLACEMENT"))
|
||||||
(display (G_ "
|
(display (G_ "
|
||||||
--with-graft=PACKAGE=REPLACEMENT
|
--with-graft=PACKAGE=REPLACEMENT
|
||||||
graft REPLACEMENT on packages that refer to PACKAGE")))
|
graft REPLACEMENT on packages that refer to PACKAGE"))
|
||||||
|
(display (G_ "
|
||||||
|
--with-branch=PACKAGE=BRANCH
|
||||||
|
build PACKAGE from the latest commit of BRANCH")))
|
||||||
|
|
||||||
|
|
||||||
(define (options->transformation opts)
|
(define (options->transformation opts)
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
# GNU Guix --- Functional package management for GNU
|
||||||
|
# Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
|
||||||
|
#
|
||||||
|
# This file is part of GNU Guix.
|
||||||
|
#
|
||||||
|
# GNU Guix is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or (at
|
||||||
|
# your option) any later version.
|
||||||
|
#
|
||||||
|
# GNU Guix is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test 'guix build --with-branch'.
|
||||||
|
#
|
||||||
|
|
||||||
|
guix build --version
|
||||||
|
|
||||||
|
# 'guix build --with-branch' requires access to the network to clone the
|
||||||
|
# Git repository below.
|
||||||
|
|
||||||
|
if ! guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null
|
||||||
|
then
|
||||||
|
# Skipping.
|
||||||
|
exit 77
|
||||||
|
fi
|
||||||
|
|
||||||
|
orig_drv="`guix build guile-gcrypt -d`"
|
||||||
|
latest_drv="`guix build guile-gcrypt --with-branch=guile-gcrypt=master -d`"
|
||||||
|
test -n "$latest_drv"
|
||||||
|
test "$orig_drv" != "$latest_drv"
|
||||||
|
|
||||||
|
# FIXME: '-S' currently doesn't work with non-derivation source.
|
||||||
|
# checkout="`guix build guile-gcrypt --with-branch=guile-gcrypt=master -S`"
|
||||||
|
checkout="`guix gc --references "$latest_drv" | grep guile-gcrypt | grep -v -E '(-builder|\.drv)'`"
|
||||||
|
test -d "$checkout"
|
||||||
|
test -f "$checkout/COPYING"
|
||||||
|
|
||||||
|
orig_drv="`guix build guix -d`"
|
||||||
|
latest_drv="`guix build guix --with-branch=guile-gcrypt=master -d`"
|
||||||
|
guix gc -R "$latest_drv" | grep guile-gcrypt-git.master
|
||||||
|
test "$orig_drv" != "$latest_drv"
|
Loading…
Reference in New Issue