diff options
Diffstat (limited to 'guix/channels.scm')
-rw-r--r-- | guix/channels.scm | 97 |
1 files changed, 82 insertions, 15 deletions
diff --git a/guix/channels.scm b/guix/channels.scm index 041fae2a9c..0fa036446c 100644 --- a/guix/channels.scm +++ b/guix/channels.scm @@ -38,6 +38,7 @@ #:select (source-properties->location &error-location &fix-hint)) + #:use-module ((guix build utils) #:select (substitute*)) #:use-module (srfi srfi-1) #:use-module (srfi srfi-2) #:use-module (srfi srfi-9) @@ -199,6 +200,46 @@ description file or its default value." channel INSTANCE." (channel-metadata-dependencies (channel-instance-metadata instance))) +;; Patch to apply to a source tree. +(define-record-type <patch> + (patch predicate application) + patch? + (predicate patch-predicate) ;procedure + (application patch-application)) ;procedure + +(define (apply-patches checkout commit patches) + "Apply the matching PATCHES to CHECKOUT, modifying files in place. The +result is unspecified." + (let loop ((patches patches)) + (match patches + (() #t) + ((($ <patch> predicate modify) rest ...) + ;; PREDICATE is passed COMMIT so that it can choose to only apply to + ;; ancestors. + (when (predicate checkout commit) + (modify checkout)) + (loop rest))))) + +(define* (latest-channel-instance store channel + #:key (patches %patches)) + "Return the latest channel instance for CHANNEL." + (define (dot-git? file stat) + (and (string=? (basename file) ".git") + (eq? 'directory (stat:type stat)))) + + (let-values (((checkout commit) + (update-cached-checkout (channel-url channel) + #:ref (channel-reference channel)))) + (when (guix-channel? channel) + ;; Apply the relevant subset of PATCHES directly in CHECKOUT. This is + ;; safe to do because 'switch-to-ref' eventually does a hard reset. + (apply-patches checkout commit patches)) + + (let* ((name (url+commit->name (channel-url channel) commit)) + (checkout (add-to-store store name #t "sha256" checkout + #:select? (negate dot-git?)))) + (channel-instance channel commit checkout)))) + (define* (latest-channel-instances store channels #:optional (previous-channels '())) "Return a list of channel instances corresponding to the latest checkouts of CHANNELS and the channels on which they depend. PREVIOUS-CHANNELS is a list @@ -224,20 +265,16 @@ of previously processed channels." (G_ "Updating channel '~a' from Git repository at '~a'...~%") (channel-name channel) (channel-url channel)) - (let-values (((checkout commit) - (latest-repository-commit store (channel-url channel) - #:ref (channel-reference - channel)))) - (let ((instance (channel-instance channel commit checkout))) - (let-values (((new-instances new-channels) - (latest-channel-instances - store - (channel-instance-dependencies instance) - previous-channels))) - (values (append (cons channel new-channels) - previous-channels) - (append (cons instance new-instances) - instances)))))))) + (let ((instance (latest-channel-instance store channel))) + (let-values (((new-instances new-channels) + (latest-channel-instances + store + (channel-instance-dependencies instance) + previous-channels))) + (values (append (cons channel new-channels) + previous-channels) + (append (cons instance new-instances) + instances))))))) previous-channels '() ;instances channels)) @@ -333,12 +370,42 @@ to '%package-module-path'." 'guile-2.2.4)) (define %quirks - ;; List of predicate/package pairs. This allows us provide information + ;; List of predicate/package pairs. This allows us to provide information ;; about specific Guile versions that old Guix revisions might need to use ;; just to be able to build and run the trampoline in %SELF-BUILD-FILE. See ;; <https://bugs.gnu.org/37506> `((,syscalls-reexports-local-variables? . ,guile-2.2.4))) + +(define %bug-41028-patch + ;; Patch for <https://bugs.gnu.org/41028>. The faulty code is the + ;; 'compute-guix-derivation' body, which uses 'call-with-new-thread' without + ;; importing (ice-9 threads). However, the 'call-with-new-thread' binding + ;; is no longer available in the default name space on Guile 3.0. + (let () + (define (missing-ice-9-threads-import? source commit) + ;; Return true if %SELF-BUILD-FILE is missing an (ice-9 threads) import. + (define content + (call-with-input-file (string-append source "/" %self-build-file) + read-string)) + + (and (string-contains content "(call-with-new-thread") + (not (string-contains content "(ice-9 threads)")))) + + (define (add-missing-ice-9-threads-import source) + ;; Add (ice-9 threads) import in the gexp of 'compute-guix-derivation'. + (substitute* (string-append source "/" %self-build-file) + (("^ +\\(use-modules \\(ice-9 match\\)\\)") + (object->string '(use-modules (ice-9 match) (ice-9 threads)))))) + + (patch missing-ice-9-threads-import? add-missing-ice-9-threads-import))) + +(define %patches + ;; Bits of past Guix revisions can become incompatible with newer Guix and + ;; Guile. This variable lists <patch> records for the Guix source tree that + ;; apply to the Guix source. + (list %bug-41028-patch)) + (define* (guile-for-source source #:optional (quirks %quirks)) "Return the Guile package to use when building SOURCE or #f if the default '%guile-for-build' should be good enough." |