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 = \
|
||||
tests/guix-build.sh \
|
||||
tests/guix-build-branch.sh \
|
||||
tests/guix-download.sh \
|
||||
tests/guix-gc.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
|
||||
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
|
||||
|
||||
@node Additional Build Options
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#:use-module (srfi srfi-37)
|
||||
#:autoload (gnu packages) (specification->package %package-module-path)
|
||||
#:autoload (guix download) (download-to-store)
|
||||
#:autoload (guix git-download) (git-reference?)
|
||||
#:autoload (guix git) (git-checkout?)
|
||||
#:use-module (guix status)
|
||||
#:use-module ((guix progress) #:select (current-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)
|
||||
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
|
||||
;; 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
|
||||
|
@ -277,7 +321,8 @@ current 'gnutls' package, after which version 3.5.4 is grafted onto them."
|
|||
;; things to build.
|
||||
`((with-source . ,transform-package-source)
|
||||
(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
|
||||
;; 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
|
||||
(parser 'with-input))
|
||||
(option '("with-graft") #t #f
|
||||
(parser 'with-graft)))))
|
||||
(parser 'with-graft))
|
||||
(option '("with-branch") #t #f
|
||||
(parser 'with-branch)))))
|
||||
|
||||
(define (show-transformation-options-help)
|
||||
(display (G_ "
|
||||
|
@ -302,7 +349,10 @@ current 'gnutls' package, after which version 3.5.4 is grafted onto them."
|
|||
replace dependency PACKAGE by REPLACEMENT"))
|
||||
(display (G_ "
|
||||
--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)
|
||||
|
|
|
@ -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