Automate SPDX header maintenance
This commit is contained in:
parent
c6d4d3acf1
commit
92b0272ba1
2
Makefile
2
Makefile
|
@ -1,3 +1,5 @@
|
|||
__ignored__ := $(shell ./setup.sh)
|
||||
|
||||
PACKAGES=syndicate syndicate-examples
|
||||
COLLECTS=syndicate syndicate-examples
|
||||
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
#!/usr/bin/env racket
|
||||
#lang racket
|
||||
;;; SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
;;; SPDX-FileCopyrightText: Copyright © 2021 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
(require file/glob)
|
||||
(require racket/date)
|
||||
|
||||
(define ((re p) i) (regexp-match p i))
|
||||
(define ((re? p) i) (regexp-match? p i))
|
||||
(define ((s p ins) i) (regexp-replace p i ins))
|
||||
|
||||
(define this-year (number->string (date-year (current-date))))
|
||||
|
||||
(define (get-git-config key)
|
||||
(string-trim (with-output-to-string
|
||||
(lambda () (system (format "git config --get ~a" key))))))
|
||||
|
||||
(define user-name (get-git-config "user.name"))
|
||||
(define user-email (get-git-config "user.email"))
|
||||
|
||||
(define user (format "~a <~a>" user-name user-email))
|
||||
|
||||
(define (make-copyright who low [hi #f])
|
||||
(if (and hi (not (string=? low hi)))
|
||||
(format "Copyright © ~a-~a ~a" low hi who)
|
||||
(format "Copyright © ~a ~a" low who)))
|
||||
|
||||
(define total-file-count 0)
|
||||
(define total-changed-files 0)
|
||||
(define dry-run? #f)
|
||||
|
||||
(define (fix-files file-type-name file-pattern front-matter-re leading-comment-re comment-prefix)
|
||||
(define matched-files (glob file-pattern))
|
||||
(define file-count (length matched-files))
|
||||
(define changed-files 0)
|
||||
(for [(file-number (in-naturals))
|
||||
(f (in-list matched-files))]
|
||||
(printf "~a [~a/~a] ~a ..." file-type-name file-number file-count f)
|
||||
(flush-output)
|
||||
(define all-lines (file->lines f))
|
||||
(define-values (front-matter head tail)
|
||||
(let*-values (((lines) all-lines)
|
||||
((front-matter lines) (if front-matter-re
|
||||
(splitf-at lines (re? front-matter-re))
|
||||
(values '() lines)))
|
||||
((head tail) (splitf-at lines (re? leading-comment-re))))
|
||||
(values front-matter head tail)))
|
||||
(let* ((head (map (s leading-comment-re "") head))
|
||||
(head (map (lambda (l)
|
||||
(match (regexp-match "^([^:]+): (.*)$" l)
|
||||
[(list _ k v) (list k v)]
|
||||
[#f (list #f l)]))
|
||||
head))
|
||||
(head (if (assoc "SPDX-FileCopyrightText" head)
|
||||
head
|
||||
(cons (list "SPDX-FileCopyrightText" (make-copyright user this-year)) head)))
|
||||
(head (if (assoc "SPDX-License-Identifier" head)
|
||||
head
|
||||
(cons (list "SPDX-License-Identifier" "LGPL-3.0-or-later") head)))
|
||||
(head (map (lambda (l)
|
||||
(match l
|
||||
[(list "SPDX-FileCopyrightText"
|
||||
(and (regexp (regexp-quote user-name))
|
||||
(regexp #px"(\\d{4})-\\d{4}" (list _ low))))
|
||||
(list "SPDX-FileCopyrightText"
|
||||
(make-copyright user low this-year))]
|
||||
[(list "SPDX-FileCopyrightText"
|
||||
(and (regexp (regexp-quote user-name))
|
||||
(regexp #px"\\d{4}" (list low))))
|
||||
(list "SPDX-FileCopyrightText"
|
||||
(make-copyright user low this-year))]
|
||||
[_ l]))
|
||||
head))
|
||||
(head (map (lambda (l) (string-append comment-prefix
|
||||
(match l
|
||||
[(list #f v) v]
|
||||
[(list k v) (format "~a: ~a" k v)])))
|
||||
head))
|
||||
(new-lines `(,@front-matter
|
||||
,@head
|
||||
""
|
||||
,@(dropf tail (lambda (l) (string=? (string-trim l) "")))))
|
||||
(changed? (not (equal? all-lines new-lines))))
|
||||
(when (and changed? (not dry-run?))
|
||||
(call-with-atomic-output-file
|
||||
f
|
||||
(lambda (port _tmp-path)
|
||||
(for [(l front-matter)] (displayln l port))
|
||||
(for [(l head)] (displayln l port))
|
||||
(newline port)
|
||||
(for [(l (dropf tail (lambda (l) (string=? (string-trim l) ""))))] (displayln l port)))))
|
||||
(if changed?
|
||||
(begin (set! changed-files (+ changed-files 1))
|
||||
(printf "\e[41mchanged\e[0m\n"))
|
||||
(printf "\r\e[K"))))
|
||||
(when (positive? changed-files)
|
||||
(printf "~a [~a total files, ~a changed]\n" file-type-name file-count changed-files))
|
||||
(set! total-file-count (+ total-file-count file-count))
|
||||
(set! total-changed-files (+ total-changed-files changed-files)))
|
||||
|
||||
(command-line #:once-each
|
||||
[("-n" "--dry-run") "Do not write back changes to files"
|
||||
(set! dry-run? #t)])
|
||||
|
||||
(void (fix-files "Racket" "**.rkt" #px"^#" #px"^;+ *" ";;; "))
|
||||
(printf "fixcopyright: ~a files examined, ~a ~a\n"
|
||||
total-file-count
|
||||
total-changed-files
|
||||
(if dry-run?
|
||||
(if (zero? total-changed-files)
|
||||
"changes are needed"
|
||||
"files need to be updated")
|
||||
(if (zero? total-changed-files)
|
||||
"changes were needed"
|
||||
"files were updated")))
|
||||
(void (system "chmod a+x fixcopyright.rkt"))
|
||||
(exit (if (positive? total-changed-files) 1 0))
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
exec 1>&2
|
||||
./fixcopyright.rkt -n
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Set up a git checkout of this repository for local dev use.
|
||||
|
||||
exec 2>/dev/tty 1>&2
|
||||
|
||||
set -e
|
||||
|
||||
[ -d .git ] || exit 0
|
||||
|
||||
for fullhook in ./git-hooks/*
|
||||
do
|
||||
hook=$(basename "$fullhook")
|
||||
[ -L .git/hooks/$hook ] || (
|
||||
echo "Installing $hook hook"
|
||||
ln -s ../../git-hooks/$hook .git/hooks/$hook
|
||||
)
|
||||
done
|
Loading…
Reference in New Issue