diff options
| author | Ricardo Wurmus <rekado@elephly.net> | 2021-04-07 21:20:55 +0200 |
|---|---|---|
| committer | Ricardo Wurmus <rekado@elephly.net> | 2021-04-08 03:10:13 +0200 |
| commit | c8c3afe8485bd614692f13e1e8a4200136da1302 (patch) | |
| tree | bb7aec3729a9f2ae3db9fcc2621606053805beed /etc | |
| parent | e1a38cbad89c79a7bc324b96c74752f6785efedd (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-x | etc/committer.scm.in | 113 |
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 |
| 198 | modifying." | 216 | modifying." |
| @@ -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) |
