From e8d67d50c455600675cbf2ce11bc198efd7d6286 Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Thu, 23 Mar 2023 23:15:42 +0000 Subject: [PATCH 1/4] First draft of check-copyright-dates script. --- tool/check-copyright-dates | 83 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 tool/check-copyright-dates diff --git a/tool/check-copyright-dates b/tool/check-copyright-dates new file mode 100755 index 0000000000..a30d365718 --- /dev/null +++ b/tool/check-copyright-dates @@ -0,0 +1,83 @@ +#!/bin/sh +# tool/check-copyright-dates -- check copyrights dates are consistent with Git dates +# Richard Brooksby, Ravenbrook Limited, 2023-03-23 +# +# Copyright (c) 2023 Ravenbrook Limited. See end of file for license. +# +# FIXME: Only works for Ravenbrook copyrights. Should perhaps look +# for the last notice in a group of lines. +# +# FIXME: Will break if a filename has a '!' in it, because that isn't +# escaped to the sed expression. + +{ + git ls-tree -r --name-only HEAD | + while read -r filename; do + # Skip binary files + if ! file --brief -- "$filename" | grep -q 'text'; then continue; fi + + # Debugging output + # echo 1>&2 "$filename: checking..." + + # Ask Git for the year of the last commit to the file + author_year=$(git log -1 --format="%ai" "$filename" | + sed --silent --regexp-extended \ + --expression='s/^([[:digit:]]{4})-.*$/\1/p') + + # Search for copyright notices and extract the end years + nl < "$filename" | + sed --silent --regexp-extended \ + --expression='s!^[[:space:]]*([[:digit:]]+)[[:space:]].*Copyright[[:space:]]+(.*[[:space:]]+)?([[:digit:]]{4}[[:space:]]*-[[:space:]]*)?([[:digit:]]{4})[[:space:]]+Ravenbrook[[:space:]].*$!'"$filename"':\1 '"$author_year"' \4!p' + done +} | { + code=0 + while read -r fileline author_year end_year; do + # echo 1>&2 "$fileline: Checking $author_year = $end_year" + if test "$end_year" -ne "$author_year"; then + code=1 + echo 1>&2 "$fileline: Copyright end year $end_year does not match Git author year $author_year" + fi + done + exit $code +} + +# A. REFERENCES +# +# [None] +# +# +# B. DOCUMENT HISTORY +# +# 2023-03-23 RB Created in response to review brainstorm . +# +# +# C. COPYRIGHT AND LICENSE +# +# Copyright (C) 2023 Ravenbrook Limited . +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# $Id$ From 07084b2d680284068677de0e33b3f4f95c2510e0 Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Thu, 23 Mar 2023 23:24:04 +0000 Subject: [PATCH 2/4] Fixing filename escaping issue. --- tool/check-copyright-dates | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/tool/check-copyright-dates b/tool/check-copyright-dates index a30d365718..fda62a3752 100755 --- a/tool/check-copyright-dates +++ b/tool/check-copyright-dates @@ -7,36 +7,39 @@ # FIXME: Only works for Ravenbrook copyrights. Should perhaps look # for the last notice in a group of lines. # -# FIXME: Will break if a filename has a '!' in it, because that isn't -# escaped to the sed expression. +# FIXME: Should probably use ``find`` rather than ``git ls-tree`` so +# that it can check files not in Git, and be consistent with other +# checking scripts. { git ls-tree -r --name-only HEAD | - while read -r filename; do + while read -r path; do # Skip binary files - if ! file --brief -- "$filename" | grep -q 'text'; then continue; fi + if ! file --brief -- "$path" | grep -q 'text'; then continue; fi # Debugging output - # echo 1>&2 "$filename: checking..." + # echo 1>&2 "$path: checking..." # Ask Git for the year of the last commit to the file - author_year=$(git log -1 --format="%ai" "$filename" | + author_year=$(git log -1 --format="%ai" "$path" | sed --silent --regexp-extended \ --expression='s/^([[:digit:]]{4})-.*$/\1/p') # Search for copyright notices and extract the end years - nl < "$filename" | + nl < "$path" | sed --silent --regexp-extended \ - --expression='s!^[[:space:]]*([[:digit:]]+)[[:space:]].*Copyright[[:space:]]+(.*[[:space:]]+)?([[:digit:]]{4}[[:space:]]*-[[:space:]]*)?([[:digit:]]{4})[[:space:]]+Ravenbrook[[:space:]].*$!'"$filename"':\1 '"$author_year"' \4!p' + --expression='s/^[[:space:]]*([[:digit:]]+)[[:space:]].*Copyright[[:space:]]+(.*[[:space:]]+)?([[:digit:]]{4}[[:space:]]*-[[:space:]]*)?([[:digit:]]{4})[[:space:]]+Ravenbrook[[:space:]].*$/\1 \4/p' | + while read -r line end_year; do + if test "$end_year" -ne "$author_year"; then + echo "$path $line $author_year $end_year" + fi + done done } | { code=0 - while read -r fileline author_year end_year; do - # echo 1>&2 "$fileline: Checking $author_year = $end_year" - if test "$end_year" -ne "$author_year"; then - code=1 - echo 1>&2 "$fileline: Copyright end year $end_year does not match Git author year $author_year" - fi + while read -r path line author_year end_year; do + code=1 + echo 1>&2 "$path:$line: Copyright end year $end_year does not match Git author year $author_year" done exit $code } From 5232c62bdc7dadc882763f34375049e05cc09912 Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Fri, 24 Mar 2023 07:46:47 +0000 Subject: [PATCH 3/4] Checking all files, whether or not they are in Git. --- tool/check-copyright-dates | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/tool/check-copyright-dates b/tool/check-copyright-dates index fda62a3752..c454b27f38 100755 --- a/tool/check-copyright-dates +++ b/tool/check-copyright-dates @@ -6,13 +6,13 @@ # # FIXME: Only works for Ravenbrook copyrights. Should perhaps look # for the last notice in a group of lines. -# -# FIXME: Should probably use ``find`` rather than ``git ls-tree`` so -# that it can check files not in Git, and be consistent with other -# checking scripts. + +this_year="$(date '+%Y')" { - git ls-tree -r --name-only HEAD | + find . -path './.git' -prune -o \ + -type f ! -name '*~' ! -name '#*#' -print | + # git ls-tree -r --name-only HEAD | while read -r path; do # Skip binary files if ! file --brief -- "$path" | grep -q 'text'; then continue; fi @@ -25,21 +25,34 @@ sed --silent --regexp-extended \ --expression='s/^([[:digit:]]{4})-.*$/\1/p') + # ``git log`` has empty output if the file is not in Git + if test -z "$author_year"; then + author_year=0 + fi + # Search for copyright notices and extract the end years nl < "$path" | sed --silent --regexp-extended \ --expression='s/^[[:space:]]*([[:digit:]]+)[[:space:]].*Copyright[[:space:]]+(.*[[:space:]]+)?([[:digit:]]{4}[[:space:]]*-[[:space:]]*)?([[:digit:]]{4})[[:space:]]+Ravenbrook[[:space:]].*$/\1 \4/p' | while read -r line end_year; do - if test "$end_year" -ne "$author_year"; then - echo "$path $line $author_year $end_year" + if test "$end_year" -eq "$author_year"; then + continue + elif test "$author_year" -eq 0 -a "$end_year" -eq "$this_year"; then + continue fi + echo "$path $line $author_year $end_year" done done } | { code=0 while read -r path line author_year end_year; do code=1 - echo 1>&2 "$path:$line: Copyright end year $end_year does not match Git author year $author_year" + if test "$author_year" -ne 0; then + year="Git author year $author_year" + else + year="this year $this_year" + fi + echo 1>&2 "$path:$line: Copyright end year $end_year does not match $year" done exit $code } From 68643795bcad1e072bb1f2e76477eae701ff686e Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Thu, 9 Nov 2023 12:01:01 +0000 Subject: [PATCH 4/4] Updating FIXME to a longer term TODO about non-Ravenbrook copyrights. --- tool/check-copyright-dates | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tool/check-copyright-dates b/tool/check-copyright-dates index c454b27f38..25a31f40a5 100755 --- a/tool/check-copyright-dates +++ b/tool/check-copyright-dates @@ -4,8 +4,8 @@ # # Copyright (c) 2023 Ravenbrook Limited. See end of file for license. # -# FIXME: Only works for Ravenbrook copyrights. Should perhaps look -# for the last notice in a group of lines. +# Only works for Ravenbrook copyrights. TODO: Should perhaps look for +# the last notice in a group of lines. this_year="$(date '+%Y')"