1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
4 ;;; This file is part of GNU Guix.
6 ;;; GNU Guix is free software; you can redistribute it and/or modify it
7 ;;; under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 3 of the License, or (at
9 ;;; your option) any later version.
11 ;;; GNU Guix is distributed in the hope that it will be useful, but
12 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;; GNU General Public License for more details.
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
21 ;;; This scripts updates the definition of the 'guix' package in Guix for the
22 ;;; current commit. It requires Git to be installed.
32 (gnu packages package-management)
36 (string-append (current-source-directory) "/.."))
38 (define version-controlled?
39 (git-predicate %top-srcdir))
41 (define (package-definition-location)
42 "Return the source properties of the definition of the 'guix' package."
43 (call-with-input-file (location-file (package-location guix))
48 (error "definition of 'guix' package could not be found"
49 (port-filename port)))
50 (('define-public 'guix value)
51 (source-properties value))
55 (define* (update-definition commit hash
56 #:key version old-hash)
57 "Return a one-argument procedure that takes a string, the definition of the
58 'guix' package, and returns a string, the update definition for VERSION,
60 (define (linear-offset str line column)
61 ;; Return the offset in characters to reach LINE and COLUMN (both
62 ;; zero-indexed) in STR.
63 (call-with-input-string str
65 (let loop ((offset 0))
66 (cond ((and (= (port-column port) column)
67 (= (port-line port) line))
69 ((eof-object? (read-char port))
70 (error "line and column not reached!"
73 (loop (+ 1 offset))))))))
75 (define (update-hash str)
76 ;; Replace OLD-HASH with HASH in STR.
77 (string-replace-substring str
78 (bytevector->nix-base32-string old-hash)
79 (bytevector->nix-base32-string hash)))
82 (match (call-with-input-string str read)
83 (('let (('version old-version)
85 ('revision old-revision))
87 (let* ((location (source-properties defn))
88 (line (assq-ref location 'line))
90 (offset (linear-offset str line column)))
91 (string-append (format #f "(let ((version \"~a\")
94 (or version old-version)
97 (not (string=? version old-version)))
100 (string-drop (update-hash str) offset))))
102 (error "'guix' package definition is not as expected" exp)))))
105 (define (main . args)
109 (let* ((source (add-to-store store
110 "guix-checkout" ;dummy name
111 #t "sha256" %top-srcdir
112 #:select? version-controlled?))
113 (hash (query-path-hash store source))
114 (location (package-definition-location))
115 (old-hash (origin-sha256 (package-source guix))))
116 (edit-expression location
117 (update-definition commit hash
121 ;; Re-add SOURCE to the store, but this time under the real name used
122 ;; in the 'origin'. This allows us to build the package without
123 ;; having to make a real checkout; thus, it also works when working
124 ;; on a private branch.
126 (resolve-module '(gnu packages package-management)))
128 (let* ((source (add-to-store store
129 (origin-file-name (package-source guix))
131 (root (store-path-package-name source)))
133 ;; Add an indirect GC root for SOURCE in the current directory.
134 (false-if-exception (delete-file root))
135 (symlink source root)
136 (add-indirect-root store root)
138 (format #t "source code for commit ~a: ~a (GC root: ~a)~%"
139 commit source root)))))
141 ;; Automatically deduce the version and revision numbers.
144 (apply main (cdr (command-line)))