summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludovic.courtes@inria.fr>2020-12-21 14:52:38 +0100
committerLudovic Courtès <ludo@gnu.org>2020-12-27 17:23:40 +0100
commite38d90d497e19e00263fa28961c688a433154386 (patch)
tree555d6dab26eae194cbbccbe8a591e76d48a0e8eb
parent4688c9f52d0f998add29049606db5e7b0655c8eb (diff)
transformations: Add '--with-patch'.
Suggested by Philippe Swartvagher <philippe.swartvagher@inria.fr>. * guix/transformations.scm (transform-package-patches): New procedure. (%transformations): Add it as 'with-patch'. (%transformation-options, show-transformation-options-help/detailed): Add '--with-patch'. * tests/transformations.scm ("options->transformation, with-patch"): New test. * doc/guix.texi (Package Transformation Options): Document it.
-rw-r--r--doc/guix.texi18
-rw-r--r--guix/transformations.scm63
-rw-r--r--tests/transformations.scm24
3 files changed, 104 insertions, 1 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index b12cb11bdf6..6c681494a27 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -10357,6 +10357,24 @@ This is similar to @option{--with-branch}, except that it builds from
10357@var{commit} rather than the tip of a branch. @var{commit} must be a valid 10357@var{commit} rather than the tip of a branch. @var{commit} must be a valid
10358Git commit SHA1 identifier or a tag. 10358Git commit SHA1 identifier or a tag.
10359 10359
10360@item --with-patch=@var{package}=@var{file}
10361Add @var{file} to the list of patches applied to @var{package}, where
10362@var{package} is a spec such as @code{python@@3.8} or @code{glibc}.
10363@var{file} must contain a patch; it is applied with the flags specified
10364in the @code{origin} of @var{package} (@pxref{origin Reference}), which
10365by default includes @code{-p1} (@pxref{patch Directories,,, diffutils,
10366Comparing and Merging Files}).
10367
10368As an example, the command below rebuilds Coreutils with the GNU C
10369Library (glibc) patched with the given patch:
10370
10371@example
10372guix build coreutils --with-patch=glibc=./glibc-frob.patch
10373@end example
10374
10375In this example, glibc itself as well as everything that leads to
10376Coreutils in the dependency graph is rebuilt.
10377
10360@cindex test suite, skipping 10378@cindex test suite, skipping
10361@item --without-tests=@var{package} 10379@item --without-tests=@var{package}
10362Build @var{package} without running its tests. This can be useful in 10380Build @var{package} without running its tests. This can be useful in
diff --git a/guix/transformations.scm b/guix/transformations.scm
index d49041cf592..2385d3231ee 100644
--- a/guix/transformations.scm
+++ b/guix/transformations.scm
@@ -41,6 +41,7 @@
41 #:use-module (srfi srfi-34) 41 #:use-module (srfi srfi-34)
42 #:use-module (srfi srfi-37) 42 #:use-module (srfi srfi-37)
43 #:use-module (ice-9 match) 43 #:use-module (ice-9 match)
44 #:use-module (ice-9 vlist)
44 #:export (options->transformation 45 #:export (options->transformation
45 manifest-entry-with-transformations 46 manifest-entry-with-transformations
46 47
@@ -456,6 +457,60 @@ to the same package but with #:strip-binaries? #f in its 'arguments' field."
456 (rewrite obj) 457 (rewrite obj)
457 obj))) 458 obj)))
458 459
460(define (transform-package-patches specs)
461 "Return a procedure that, when passed a package, returns a package with
462additional patches."
463 (define (package-with-extra-patches p patches)
464 (if (origin? (package-source p))
465 (package/inherit p
466 (source (origin
467 (inherit (package-source p))
468 (patches (append (map (lambda (file)
469 (local-file file))
470 patches)
471 (origin-patches (package-source p)))))))
472 p))
473
474 (define (coalesce-alist alist)
475 ;; Coalesce multiple occurrences of the same key in ALIST.
476 (let loop ((alist alist)
477 (keys '())
478 (mapping vlist-null))
479 (match alist
480 (()
481 (map (lambda (key)
482 (cons key (vhash-fold* cons '() key mapping)))
483 (delete-duplicates (reverse keys))))
484 (((key . value) . rest)
485 (loop rest
486 (cons key keys)
487 (vhash-cons key value mapping))))))
488
489 (define patches
490 ;; Spec/patch alist.
491 (coalesce-alist
492 (map (lambda (spec)
493 (match (string-tokenize spec %not-equal)
494 ((spec patch)
495 (cons spec (canonicalize-path patch)))
496 (_
497 (raise (formatted-message
498 (G_ "~a: invalid package patch specification")
499 spec)))))
500 specs)))
501
502 (define rewrite
503 (package-input-rewriting/spec
504 (map (match-lambda
505 ((spec . patches)
506 (cons spec (cut package-with-extra-patches <> patches))))
507 patches)))
508
509 (lambda (obj)
510 (if (package? obj)
511 (rewrite obj)
512 obj)))
513
459(define %transformations 514(define %transformations
460 ;; Transformations that can be applied to things to build. The car is the 515 ;; Transformations that can be applied to things to build. The car is the
461 ;; key used in the option alist, and the cdr is the transformation 516 ;; key used in the option alist, and the cdr is the transformation
@@ -469,7 +524,8 @@ to the same package but with #:strip-binaries? #f in its 'arguments' field."
469 (with-git-url . ,transform-package-source-git-url) 524 (with-git-url . ,transform-package-source-git-url)
470 (with-c-toolchain . ,transform-package-toolchain) 525 (with-c-toolchain . ,transform-package-toolchain)
471 (with-debug-info . ,transform-package-with-debug-info) 526 (with-debug-info . ,transform-package-with-debug-info)
472 (without-tests . ,transform-package-tests))) 527 (without-tests . ,transform-package-tests)
528 (with-patch . ,transform-package-patches)))
473 529
474(define (transformation-procedure key) 530(define (transformation-procedure key)
475 "Return the transformation procedure associated with KEY, a symbol such as 531 "Return the transformation procedure associated with KEY, a symbol such as
@@ -509,6 +565,8 @@ to the same package but with #:strip-binaries? #f in its 'arguments' field."
509 (parser 'with-debug-info)) 565 (parser 'with-debug-info))
510 (option '("without-tests") #t #f 566 (option '("without-tests") #t #f
511 (parser 'without-tests)) 567 (parser 'without-tests))
568 (option '("with-patch") #t #f
569 (parser 'with-patch))
512 570
513 (option '("help-transform") #f #f 571 (option '("help-transform") #f #f
514 (lambda _ 572 (lambda _
@@ -538,6 +596,9 @@ to the same package but with #:strip-binaries? #f in its 'arguments' field."
538 --with-git-url=PACKAGE=URL 596 --with-git-url=PACKAGE=URL
539 build PACKAGE from the repository at URL")) 597 build PACKAGE from the repository at URL"))
540 (display (G_ " 598 (display (G_ "
599 --with-patch=PACKAGE=FILE
600 add FILE to the list of patches of PACKAGE"))
601 (display (G_ "
541 --with-c-toolchain=PACKAGE=TOOLCHAIN 602 --with-c-toolchain=PACKAGE=TOOLCHAIN
542 build PACKAGE and its dependents with TOOLCHAIN")) 603 build PACKAGE and its dependents with TOOLCHAIN"))
543 (display (G_ " 604 (display (G_ "
diff --git a/tests/transformations.scm b/tests/transformations.scm
index 2d33bed7ae8..9053deba415 100644
--- a/tests/transformations.scm
+++ b/tests/transformations.scm
@@ -26,6 +26,7 @@
26 #:use-module (guix build-system) 26 #:use-module (guix build-system)
27 #:use-module (guix build-system gnu) 27 #:use-module (guix build-system gnu)
28 #:use-module (guix transformations) 28 #:use-module (guix transformations)
29 #:use-module ((guix gexp) #:select (local-file? local-file-file))
29 #:use-module (guix ui) 30 #:use-module (guix ui)
30 #:use-module (guix utils) 31 #:use-module (guix utils)
31 #:use-module (guix git) 32 #:use-module (guix git)
@@ -372,6 +373,29 @@
372 (match (memq #:tests? (package-arguments tar)) 373 (match (memq #:tests? (package-arguments tar))
373 ((#:tests? #f _ ...) #t)))))))) 374 ((#:tests? #f _ ...) #t))))))))
374 375
376(test-equal "options->transformation, with-patch"
377 (search-patches "glibc-locales.patch" "guile-relocatable.patch")
378 (let* ((dep (dummy-package "dep"
379 (source (dummy-origin))))
380 (p (dummy-package "foo"
381 (inputs `(("dep" ,dep)))))
382 (patch1 (search-patch "glibc-locales.patch"))
383 (patch2 (search-patch "guile-relocatable.patch"))
384 (t (options->transformation
385 `((with-patch . ,(string-append "dep=" patch1))
386 (with-patch . ,(string-append "dep=" patch2))
387 (with-patch . ,(string-append "tar=" patch1))))))
388 (let ((new (t p)))
389 (match (bag-direct-inputs (package->bag new))
390 ((("dep" dep) ("tar" tar) _ ...)
391 (and (member patch1
392 (filter-map (lambda (patch)
393 (and (local-file? patch)
394 (local-file-file patch)))
395 (origin-patches (package-source tar))))
396 (map local-file-file
397 (origin-patches (package-source dep)))))))))
398
375(test-end) 399(test-end)
376 400
377;;; Local Variables: 401;;; Local Variables: