diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2017-05-18 16:21:35 +0200 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2017-05-18 16:24:02 +0200 |
| commit | 920803fbf443f7e40ed299f433255f10a4ae9fb3 (patch) | |
| tree | fa7efbcbdadee16fd75a57b6f2164df3dbb6359c | |
| parent | 266d281d253ffd20336f837fc64a64a14eb44b12 (diff) | |
maint: Add 'update-NEWS' target.
* build-aux/update-NEWS.scm: New file.
* Makefile.am (EXTRA_DIST): Add it.
(GUIX_MAINTENANCE_DIRECTORY): New variable.
(update-NEWS): New target.
(.PHONY): Add it.
| -rw-r--r-- | Makefile.am | 12 | ||||
| -rw-r--r-- | build-aux/update-NEWS.scm | 161 |
2 files changed, 172 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 5bfc9ca88c6..e1c7cdd7fa9 100644 --- a/Makefile.am +++ b/Makefile.am | |||
| @@ -420,6 +420,7 @@ EXTRA_DIST = \ | |||
| 420 | build-aux/generate-authors.scm \ | 420 | build-aux/generate-authors.scm \ |
| 421 | build-aux/test-driver.scm \ | 421 | build-aux/test-driver.scm \ |
| 422 | build-aux/update-guix-package.scm \ | 422 | build-aux/update-guix-package.scm \ |
| 423 | build-aux/update-NEWS.scm \ | ||
| 423 | build-aux/run-system-tests.scm \ | 424 | build-aux/run-system-tests.scm \ |
| 424 | d3.v3.js \ | 425 | d3.v3.js \ |
| 425 | graph.js \ | 426 | graph.js \ |
| @@ -641,6 +642,15 @@ update-guix-package: | |||
| 641 | $(top_srcdir)/build-aux/update-guix-package.scm \ | 642 | $(top_srcdir)/build-aux/update-guix-package.scm \ |
| 642 | "`git rev-parse HEAD`" | 643 | "`git rev-parse HEAD`" |
| 643 | 644 | ||
| 645 | # Location of a checkout of <git://git.savannah.gnu.org/guix/maintenance.git>. | ||
| 646 | # Package data from this checkout is used by 'update-NEWS.scm'. | ||
| 647 | GUIX_MAINTENANCE_DIRECTORY ?= $(top_srcdir)/../guix-maintenance | ||
| 648 | |||
| 649 | update-NEWS: $(GOBJECTS) | ||
| 650 | $(top_builddir)/pre-inst-env "$(GUILE)" \ | ||
| 651 | $(top_srcdir)/build-aux/update-NEWS.scm \ | ||
| 652 | $(top_srcdir)/NEWS "$(GUIX_MAINTENANCE_DIRECTORY)/data" | ||
| 653 | |||
| 644 | # Make sure we're not shipping a file that embeds a local /gnu/store file name. | 654 | # Make sure we're not shipping a file that embeds a local /gnu/store file name. |
| 645 | assert-no-store-file-names: $(distdir)/ChangeLog | 655 | assert-no-store-file-names: $(distdir)/ChangeLog |
| 646 | $(AM_V_at)if grep -r --exclude=*.texi --exclude=*.info \ | 656 | $(AM_V_at)if grep -r --exclude=*.texi --exclude=*.info \ |
| @@ -676,7 +686,7 @@ hydra-jobs.scm: $(GOBJECTS) | |||
| 676 | .PHONY: assert-no-store-file-names assert-binaries-available | 686 | .PHONY: assert-no-store-file-names assert-binaries-available |
| 677 | .PHONY: assert-final-inputs-self-contained | 687 | .PHONY: assert-final-inputs-self-contained |
| 678 | .PHONY: clean-go make-go | 688 | .PHONY: clean-go make-go |
| 679 | .PHONY: update-guix-package release | 689 | .PHONY: update-guix-package update-NEWS release |
| 680 | 690 | ||
| 681 | ## -------------- ## | 691 | ## -------------- ## |
| 682 | ## Silent rules. ## | 692 | ## Silent rules. ## |
diff --git a/build-aux/update-NEWS.scm b/build-aux/update-NEWS.scm new file mode 100644 index 00000000000..2e8f68c9a8e --- /dev/null +++ b/build-aux/update-NEWS.scm | |||
| @@ -0,0 +1,161 @@ | |||
| 1 | ;;; GNU Guix --- Functional package management for GNU | ||
| 2 | ;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org> | ||
| 3 | ;;; | ||
| 4 | ;;; This file is part of GNU Guix. | ||
| 5 | ;;; | ||
| 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. | ||
| 10 | ;;; | ||
| 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. | ||
| 15 | ;;; | ||
| 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/>. | ||
| 18 | |||
| 19 | ;;; Commentary: | ||
| 20 | ;;; | ||
| 21 | ;;; This script updates the list of new and updated packages in 'NEWS'. | ||
| 22 | ;;; | ||
| 23 | ;;; Code: | ||
| 24 | |||
| 25 | (use-modules (gnu) (guix) | ||
| 26 | (guix build utils) | ||
| 27 | ((guix ui) #:select (fill-paragraph)) | ||
| 28 | (srfi srfi-1) | ||
| 29 | (srfi srfi-11) | ||
| 30 | (ice-9 match) | ||
| 31 | (ice-9 rdelim) | ||
| 32 | (ice-9 regex) | ||
| 33 | (ice-9 pretty-print)) | ||
| 34 | |||
| 35 | (define %header-rx | ||
| 36 | (make-regexp "^\\* Changes in (version )?([0-9.]+) \\(since ([0-9.]+)\\)")) | ||
| 37 | |||
| 38 | (define (NEWS->versions port) | ||
| 39 | "Return two values: the previous version and the current version as read | ||
| 40 | from PORT, which is an input port on the 'NEWS' file." | ||
| 41 | (let loop () | ||
| 42 | (let ((line (read-line port))) | ||
| 43 | (cond ((eof-object? line) | ||
| 44 | (error "failed to determine previous and current version" | ||
| 45 | port)) | ||
| 46 | ((regexp-exec %header-rx line) | ||
| 47 | => | ||
| 48 | (lambda (match) | ||
| 49 | (values (match:substring match 3) | ||
| 50 | (match:substring match 2)))) | ||
| 51 | (else | ||
| 52 | (loop)))))) | ||
| 53 | |||
| 54 | (define (skip-to-org-heading port) | ||
| 55 | "Read from PORT until an Org heading is found." | ||
| 56 | (let loop () | ||
| 57 | (let ((next (peek-char port))) | ||
| 58 | (cond ((eqv? next #\*) | ||
| 59 | #t) | ||
| 60 | ((eof-object? next) | ||
| 61 | (error "next heading could not be found")) | ||
| 62 | (else | ||
| 63 | (read-line port) | ||
| 64 | (loop)))))) | ||
| 65 | |||
| 66 | (define (rewrite-org-section input output heading-rx proc) | ||
| 67 | "Write to OUTPUT the text read from INPUT, but with the first Org section | ||
| 68 | matching HEADING-RX replaced by NEW-HEADING and CONTENTS." | ||
| 69 | (let loop () | ||
| 70 | (let ((line (read-line input))) | ||
| 71 | (cond ((eof-object? line) | ||
| 72 | (error "failed to match heading regexp" heading-rx)) | ||
| 73 | ((regexp-exec heading-rx line) | ||
| 74 | => | ||
| 75 | (lambda (match) | ||
| 76 | (proc match output) | ||
| 77 | (skip-to-org-heading input) | ||
| 78 | (dump-port input output) | ||
| 79 | #t)) | ||
| 80 | (else | ||
| 81 | (display line output) | ||
| 82 | (newline output) | ||
| 83 | (loop)))))) | ||
| 84 | |||
| 85 | (define (enumeration->paragraph lst) | ||
| 86 | "Turn LST, a list of strings, into a single string that is a ready-to-print | ||
| 87 | paragraph." | ||
| 88 | (fill-paragraph (string-join (sort lst string<?) ", ") | ||
| 89 | 75)) | ||
| 90 | |||
| 91 | (define (write-packages-added news-file old new) | ||
| 92 | "Write to NEWS-FILE the list of packages added between OLD and NEW." | ||
| 93 | (let ((added (lset-difference string=? (map car new) (map car old)))) | ||
| 94 | (with-atomic-file-replacement news-file | ||
| 95 | (lambda (input output) | ||
| 96 | (rewrite-org-section input output | ||
| 97 | (make-regexp "^(\\*+) (.*) new packages") | ||
| 98 | (lambda (match port) | ||
| 99 | (let ((stars (match:substring match 1))) | ||
| 100 | (format port | ||
| 101 | "~a ~a new packages~%~%~a~%~%" | ||
| 102 | stars (length added) | ||
| 103 | (enumeration->paragraph added))))))))) | ||
| 104 | |||
| 105 | (define (write-packages-updates news-file old new) | ||
| 106 | "Write to NEWS-FILE the list of packages upgraded between OLD and NEW." | ||
| 107 | (let ((upgraded (filter-map (match-lambda | ||
| 108 | ((package . new-version) | ||
| 109 | (match (assoc package old) | ||
| 110 | ((_ . old-version) | ||
| 111 | (and (version>? new-version old-version) | ||
| 112 | (string-append package "@" | ||
| 113 | new-version))) | ||
| 114 | (_ #f)))) | ||
| 115 | new))) | ||
| 116 | (with-atomic-file-replacement news-file | ||
| 117 | (lambda (input output) | ||
| 118 | (rewrite-org-section input output | ||
| 119 | (make-regexp "^(\\*+) (.*) package updates") | ||
| 120 | (lambda (match port) | ||
| 121 | (let ((stars (match:substring match 1))) | ||
| 122 | (format port | ||
| 123 | "~a ~a package updates~%~%~a~%~%" | ||
| 124 | stars (length upgraded) | ||
| 125 | (enumeration->paragraph upgraded))))))))) | ||
| 126 | |||
| 127 | |||
| 128 | (define (main . args) | ||
| 129 | (match args | ||
| 130 | ((news-file data-directory) | ||
| 131 | ;; Don't browse things listed in the user's $GUIX_PACKAGE_PATH. Here we | ||
| 132 | ;; assume that the last item in (%package-module-path) is the distro | ||
| 133 | ;; directory. | ||
| 134 | (parameterize ((%package-module-path | ||
| 135 | (list (last (%package-module-path))))) | ||
| 136 | (define (package-file version) | ||
| 137 | (string-append data-directory "/packages-" | ||
| 138 | version ".txt")) | ||
| 139 | |||
| 140 | (let-values (((previous-version new-version) | ||
| 141 | (call-with-input-file news-file NEWS->versions))) | ||
| 142 | (let* ((old (call-with-input-file (package-file previous-version) | ||
| 143 | read)) | ||
| 144 | (new (fold-packages (lambda (p r) | ||
| 145 | (alist-cons (package-name p) (package-version p) | ||
| 146 | r)) | ||
| 147 | '()))) | ||
| 148 | (call-with-output-file (package-file new-version) | ||
| 149 | (lambda (port) | ||
| 150 | (pretty-print new port))) | ||
| 151 | |||
| 152 | (write-packages-added news-file old new) | ||
| 153 | (write-packages-updates news-file old new))))) | ||
| 154 | (x | ||
| 155 | (format (current-error-port) "Usage: update-NEWS NEWS-FILE DATA-DIRECTORY | ||
| 156 | |||
| 157 | Update the list of new and updated packages in NEWS-FILE using the | ||
| 158 | previous-version package list from DATA-DIRECTORY.\n") | ||
| 159 | (exit 1)))) | ||
| 160 | |||
| 161 | (apply main (cdr (command-line))) | ||
