summaryrefslogtreecommitdiff
path: root/etc
diff options
context:
space:
mode:
authorRicardo Wurmus <rekado@elephly.net>2021-04-07 21:20:55 +0200
committerRicardo Wurmus <rekado@elephly.net>2021-04-08 03:10:13 +0200
commitc8c3afe8485bd614692f13e1e8a4200136da1302 (patch)
treebb7aec3729a9f2ae3db9fcc2621606053805beed /etc
parente1a38cbad89c79a7bc324b96c74752f6785efedd (diff)
etc/committer: Handle package additions.
* etc/committer.scm.in (<hunk>)[diff]: Rename this field... [diff-lines]: ...to this. [definition?]: New field. (hunk->patch): Join diff lines. (diff-info): Do not join diff lines; record whether a hunk is a new definition. (commit-message): Rename this procedure... (change-commit-message): ...to this. (add-commit-message): New procedure. (main): Handle new package definitions before changes.
Diffstat (limited to 'etc')
-rwxr-xr-xetc/committer.scm.in113
1 files changed, 80 insertions, 33 deletions
diff --git a/etc/committer.scm.in b/etc/committer.scm.in
index ebe6b96bccd..824483e0886 100755
--- a/etc/committer.scm.in
+++ b/etc/committer.scm.in
@@ -3,7 +3,7 @@
3!# 3!#
4 4
5;;; GNU Guix --- Functional package management for GNU 5;;; GNU Guix --- Functional package management for GNU
6;;; Copyright © 2020 Ricardo Wurmus <rekado@elephly.net> 6;;; Copyright © 2020, 2021 Ricardo Wurmus <rekado@elephly.net>
7;;; 7;;;
8;;; This file is part of GNU Guix. 8;;; This file is part of GNU Guix.
9;;; 9;;;
@@ -28,7 +28,10 @@
28 28
29(import (sxml xpath) 29(import (sxml xpath)
30 (srfi srfi-1) 30 (srfi srfi-1)
31 (srfi srfi-2)
31 (srfi srfi-9) 32 (srfi srfi-9)
33 (srfi srfi-11)
34 (srfi srfi-26)
32 (ice-9 format) 35 (ice-9 format)
33 (ice-9 popen) 36 (ice-9 popen)
34 (ice-9 match) 37 (ice-9 match)
@@ -63,7 +66,8 @@ LINE-NO in PORT."
63 (make-hunk file-name 66 (make-hunk file-name
64 old-line-number 67 old-line-number
65 new-line-number 68 new-line-number
66 diff) 69 diff-lines
70 definition?)
67 hunk? 71 hunk?
68 (file-name hunk-file-name) 72 (file-name hunk-file-name)
69 ;; Line number before the change 73 ;; Line number before the change
@@ -71,14 +75,16 @@ LINE-NO in PORT."
71 ;; Line number after the change 75 ;; Line number after the change
72 (new-line-number hunk-new-line-number) 76 (new-line-number hunk-new-line-number)
73 ;; The full diff to be used with "git apply --cached" 77 ;; The full diff to be used with "git apply --cached"
74 (diff hunk-diff)) 78 (diff-lines hunk-diff-lines)
79 ;; Does this hunk add a definition?
80 (definition? hunk-definition?))
75 81
76(define* (hunk->patch hunk #:optional (port (current-output-port))) 82(define* (hunk->patch hunk #:optional (port (current-output-port)))
77 (let ((file-name (hunk-file-name hunk))) 83 (let ((file-name (hunk-file-name hunk)))
78 (format port 84 (format port
79 "diff --git a/~a b/~a~%--- a/~a~%+++ b/~a~%~a" 85 "diff --git a/~a b/~a~%--- a/~a~%+++ b/~a~%~a"
80 file-name file-name file-name file-name 86 file-name file-name file-name file-name
81 (hunk-diff hunk)))) 87 (string-join (hunk-diff-lines hunk) ""))))
82 88
83(define (diff-info) 89(define (diff-info)
84 "Read the diff and return a list of <hunk> values." 90 "Read the diff and return a list of <hunk> values."
@@ -88,21 +94,26 @@ LINE-NO in PORT."
88 ;; Do not include any context lines. This makes it 94 ;; Do not include any context lines. This makes it
89 ;; easier to find the S-expression surrounding the 95 ;; easier to find the S-expression surrounding the
90 ;; change. 96 ;; change.
91 "--unified=0"))) 97 "--unified=0"
98 "gnu")))
92 (define (extract-line-number line-tag) 99 (define (extract-line-number line-tag)
93 (abs (string->number 100 (abs (string->number
94 (car (string-split line-tag #\,))))) 101 (car (string-split line-tag #\,)))))
95 (define (read-hunk) 102 (define (read-hunk)
96 (reverse 103 (let loop ((lines '())
97 (let loop ((lines '())) 104 (definition? #false))
98 (let ((line (read-line port 'concat))) 105 (let ((line (read-line port 'concat)))
99 (cond 106 (cond
100 ((eof-object? line) lines) 107 ((eof-object? line)
101 ((or (string-prefix? "@@ " line) 108 (values (reverse lines) definition?))
102 (string-prefix? "diff --git" line)) 109 ((or (string-prefix? "@@ " line)
103 (unget-string port line) 110 (string-prefix? "diff --git" line))
104 lines) 111 (unget-string port line)
105 (else (loop (cons line lines)))))))) 112 (values (reverse lines) definition?))
113 (else
114 (loop (cons line lines)
115 (or definition?
116 (string-prefix? "+(define" line))))))))
106 (define info 117 (define info
107 (let loop ((acc '()) 118 (let loop ((acc '())
108 (file-name #f)) 119 (file-name #f))
@@ -116,13 +127,14 @@ LINE-NO in PORT."
116 ((string-prefix? "@@ " line) 127 ((string-prefix? "@@ " line)
117 (match (string-split line #\space) 128 (match (string-split line #\space)
118 ((_ old-start new-start . _) 129 ((_ old-start new-start . _)
119 (loop (cons (make-hunk file-name 130 (let-values
120 (extract-line-number old-start) 131 (((diff-lines definition?) (read-hunk)))
121 (extract-line-number new-start) 132 (loop (cons (make-hunk file-name
122 (string-join (cons* line "\n" 133 (extract-line-number old-start)
123 (read-hunk)) "")) 134 (extract-line-number new-start)
124 acc) 135 (cons* line "\n" diff-lines)
125 file-name)))) 136 definition?) acc)
137 file-name)))))
126 (else (loop acc file-name)))))) 138 (else (loop acc file-name))))))
127 (close-pipe port) 139 (close-pipe port)
128 info)) 140 info))
@@ -148,7 +160,7 @@ corresponding to the top-level definition containing the staged changes."
148 (surrounding-sexp port 160 (surrounding-sexp port
149 (hunk-new-line-number hunk))))) 161 (hunk-new-line-number hunk)))))
150 162
151(define* (commit-message file-name old new #:optional (port (current-output-port))) 163(define* (change-commit-message file-name old new #:optional (port (current-output-port)))
152 "Print ChangeLog commit message for changes between OLD and NEW." 164 "Print ChangeLog commit message for changes between OLD and NEW."
153 (define (get-values expr field) 165 (define (get-values expr field)
154 (match ((sxpath `(// ,field quasiquote *)) expr) 166 (match ((sxpath `(// ,field quasiquote *)) expr)
@@ -193,6 +205,12 @@ corresponding to the top-level definition containing the staged changes."
193 (listify added))))))))) 205 (listify added)))))))))
194 '(inputs propagated-inputs native-inputs))) 206 '(inputs propagated-inputs native-inputs)))
195 207
208(define* (add-commit-message file-name variable-name #:optional (port (current-output-port)))
209 "Print ChangeLog commit message for a change to FILE-NAME adding a definition."
210 (format port
211 "gnu: Add ~a.~%~%* ~a (~a): New variable.~%"
212 variable-name file-name variable-name))
213
196(define (group-hunks-by-sexp hunks) 214(define (group-hunks-by-sexp hunks)
197 "Return a list of pairs associating all hunks with the S-expression they are 215 "Return a list of pairs associating all hunks with the S-expression they are
198modifying." 216modifying."
@@ -223,9 +241,38 @@ modifying."
223 (() 241 (()
224 (display "Nothing to be done." (current-error-port))) 242 (display "Nothing to be done." (current-error-port)))
225 (hunks 243 (hunks
226 (for-each (match-lambda 244 (let-values
227 ((new old . hunks) 245 (((definitions changes)
228 (for-each (lambda (hunk) 246 (partition hunk-definition? hunks)))
247
248 ;; Additions.
249 (for-each (lambda (hunk)
250 (and-let*
251 ((define-line (find (cut string-prefix? "+(define" <>)
252 (hunk-diff-lines hunk)))
253 (variable-name (and=> (string-tokenize define-line) second)))
254 (add-commit-message (hunk-file-name hunk) variable-name)
255 (let ((port (open-pipe* OPEN_WRITE
256 "git" "apply"
257 "--cached"
258 "--unidiff-zero")))
259 (hunk->patch hunk port)
260 (unless (eqv? 0 (status:exit-val (close-pipe port)))
261 (error "Cannot apply")))
262
263 (let ((port (open-pipe* OPEN_WRITE "git" "commit" "-F" "-")))
264 (add-commit-message (hunk-file-name hunk)
265 variable-name port)
266 (sleep 1)
267 (unless (eqv? 0 (status:exit-val (close-pipe port)))
268 (error "Cannot commit"))))
269 (sleep 1))
270 definitions)
271
272 ;; Changes.
273 (for-each (match-lambda
274 ((new old . hunks)
275 (for-each (lambda (hunk)
229 (let ((port (open-pipe* OPEN_WRITE 276 (let ((port (open-pipe* OPEN_WRITE
230 "git" "apply" 277 "git" "apply"
231 "--cached" 278 "--cached"
@@ -235,16 +282,16 @@ modifying."
235 (error "Cannot apply"))) 282 (error "Cannot apply")))
236 (sleep 1)) 283 (sleep 1))
237 hunks) 284 hunks)
238 (commit-message (hunk-file-name (first hunks)) 285 (change-commit-message (hunk-file-name (first hunks))
239 old new 286 old new
240 (current-output-port)) 287 (current-output-port))
241 (let ((port (open-pipe* OPEN_WRITE "git" "commit" "-F" "-"))) 288 (let ((port (open-pipe* OPEN_WRITE "git" "commit" "-F" "-")))
242 (commit-message (hunk-file-name (first hunks)) 289 (change-commit-message (hunk-file-name (first hunks))
243 old new 290 old new
244 port) 291 port)
245 (sleep 1) 292 (sleep 1)
246 (unless (eqv? 0 (status:exit-val (close-pipe port))) 293 (unless (eqv? 0 (status:exit-val (close-pipe port)))
247 (error "Cannot commit"))))) 294 (error "Cannot commit")))))
248 (new+old+hunks hunks))))) 295 (new+old+hunks changes))))))
249 296
250(main) 297(main)