guix build: Add '--with-git-url'.

* guix/scripts/build.scm (%not-equal): New variable.
(evaluate-git-replacement-specs): Use it instead of local variable
'not-equal'.
(transform-package-source-git-url): New procedure.
(%transformations): Add 'with-git-url'.
(%transformation-options, show-transformation-options-help): Add
'--with-git-url'.
* tests/scripts-build.scm ("options->transformation, with-git-url"):
New test.
This commit is contained in:
Ludovic Courtès 2019-03-12 15:50:13 +01:00 committed by Ludovic Courtès
parent 55da450a1f
commit 880916ac52
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
3 changed files with 87 additions and 20 deletions

View file

@ -7780,9 +7780,32 @@ 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}
@item --with-git-url=@var{package}=@var{url}
@cindex Git, using the latest commit
@cindex latest commit, building
Build @var{package} from the latest commit of the @code{master} branch of the
Git repository at @var{url}.
For example, the following commands builds the GNU C Library (glibc) straight
from its Git repository instead of building the currently-packaged release:
@example
guix build glibc \
--with-git-url=glibc=git://sourceware.org/git/glibc.git
@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.
@item --with-branch=@var{package}=@var{branch}
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
@ -7798,17 +7821,6 @@ specific @code{guile-sqlite3} build:
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.
@item --with-commit=@var{package}=@var{commit}
This is similar to @code{--with-branch}, except that it builds from
@var{commit} rather than the tip of a branch. @var{commit} must be a valid

View file

@ -272,16 +272,16 @@ (define (replacement-pair old new)
(rewrite obj)
obj))))
(define %not-equal
(char-set-complement (char-set #\=)))
(define (evaluate-git-replacement-specs specs proc)
"Parse SPECS, a list of strings like \"guile=stable-2.2\", and return a list
of package pairs, where (PROC PACKAGE URL BRANCH-OR-COMMIT) returns the
replacement package. 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)
(match (string-tokenize spec %not-equal)
((name branch-or-commit)
(let* ((old (specification->package name))
(source (package-source old))
@ -341,6 +341,33 @@ (define (replace old url commit)
(rewrite obj)
obj))))
(define (transform-package-source-git-url replacement-specs)
"Return a procedure that, when passed a package, replaces its dependencies
according to REPLACEMENT-SPECS. REPLACEMENT-SPECS is a list of strings like
\"guile-json=https://gitthing.com/…\" meaning that packages are built using
a checkout of the Git repository at the given URL."
;; FIXME: Currently this cannot be combined with '--with-branch' or
;; '--with-commit' because they all transform "from scratch".
(define replacements
(map (lambda (spec)
(match (string-tokenize spec %not-equal)
((name url)
(let* ((old (specification->package name))
(new (package
(inherit old)
(source (git-checkout (url url)
(recursive? #t))))))
(cons old new)))))
replacement-specs))
(define 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
@ -350,7 +377,8 @@ (define %transformations
(with-input . ,transform-package-inputs)
(with-graft . ,transform-package-inputs/graft)
(with-branch . ,transform-package-source-branch)
(with-commit . ,transform-package-source-commit)))
(with-commit . ,transform-package-source-commit)
(with-git-url . ,transform-package-source-git-url)))
(define %transformation-options
;; The command-line interface to the above transformations.
@ -368,7 +396,9 @@ (define %transformation-options
(option '("with-branch") #t #f
(parser 'with-branch))
(option '("with-commit") #t #f
(parser 'with-commit)))))
(parser 'with-commit))
(option '("with-git-url") #t #f
(parser 'with-git-url)))))
(define (show-transformation-options-help)
(display (G_ "
@ -385,7 +415,10 @@ (define (show-transformation-options-help)
build PACKAGE from the latest commit of BRANCH"))
(display (G_ "
--with-commit=PACKAGE=COMMIT
build PACKAGE from COMMIT")))
build PACKAGE from COMMIT"))
(display (G_ "
--with-git-url=PACKAGE=URL
build PACKAGE from the repository at URL")))
(define (options->transformation opts)

View file

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2016, 2017, 2019 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@ -23,6 +23,7 @@ (define-module (test-scripts-build)
#:use-module (guix scripts build)
#:use-module (guix ui)
#:use-module (guix utils)
#:use-module (guix git)
#:use-module (gnu packages)
#:use-module (gnu packages base)
#:use-module (gnu packages busybox)
@ -164,4 +165,25 @@ (define-module (test-scripts-build)
((("x" dep))
(eq? (package-replacement dep) findutils)))))))))))
(test-equal "options->transformation, with-git-url"
(let ((source (git-checkout (url "https://example.org")
(recursive? #t))))
(list source source))
(let* ((p (dummy-package "guix.scm"
(inputs `(("foo" ,grep)
("bar" ,(dummy-package "chbouib"
(native-inputs `(("x" ,grep)))))))))
(t (options->transformation '((with-git-url . "grep=https://example.org")))))
(with-store store
(let ((new (t store p)))
(and (not (eq? new p))
(match (package-inputs new)
((("foo" dep1) ("bar" dep2))
(and (string=? (package-full-name dep1)
(package-full-name grep))
(string=? (package-name dep2) "chbouib")
(match (package-native-inputs dep2)
((("x" dep3))
(map package-source (list dep1 dep3))))))))))))
(test-end)