From: Bruno Haible Date: Sun, 7 Apr 2019 16:56:57 +0000 (+0200) Subject: build: Verify that newly added files have an appropriate copyright notice. X-Git-Tag: v0.20~71 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=63cdedd9b62caa07dfdccb6a406982f88ea3765b;p=thirdparty%2Fgettext.git build: Verify that newly added files have an appropriate copyright notice. * check-copyright-headers: New file. * Makefile.am (EXTRA_DIST): Add it. (distcheck-hook): Run check-copyright-headers and fail if it fails. --- diff --git a/Makefile.am b/Makefile.am index a8f483af6..f3f7b652b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -52,6 +52,7 @@ changelog_etc = \ EXTRA_DIST = \ $(changelog_etc) DEPENDENCIES PACKAGING HACKING ChangeLog.0 autogen.sh \ + check-copyright-headers \ build-aux/ac-help.sed build-aux/git-version-gen build-aux/texi2html \ m4/fixautomake.m4 m4/woe32-dll.m4 \ m4/libtool.m4 @@ -59,8 +60,8 @@ EXTRA_DIST = \ # Additional dependencies for configure, due to the use of autoconf --trace. $(srcdir)/configure: $(srcdir)/gettext-runtime/configure.ac $(srcdir)/gettext-tools/configure.ac -# Verify that some files are the same. distcheck-hook: +# Verify that some files are the same. cmp -s $(srcdir)/gettext-runtime/po/Makefile.in.in $(srcdir)/gettext-tools/po/Makefile.in.in cmp -s $(srcdir)/gettext-runtime/po/Rules-quot $(srcdir)/gettext-tools/po/Rules-quot cmp -s $(srcdir)/gettext-runtime/po/boldquot.sed $(srcdir)/gettext-tools/po/boldquot.sed @@ -118,7 +119,8 @@ distcheck-hook: cmp -s $(srcdir)/gettext-tools/examples/hello-java-awt/m4/TestAWT.java $(srcdir)/gettext-tools/examples/hello-java-swing/m4/TestAWT.java cmp -s $(srcdir)/gettext-tools/examples/hello-java-awt/m4/TestAWT.class $(srcdir)/gettext-tools/examples/hello-java-swing/m4/TestAWT.class test "`sed 1,15d $(srcdir)/gnulib-local/lib/alloca.in.h | md5sum`" = "`sed 1,15d $(srcdir)/gettext-runtime/libasprintf/alloca.in.h | md5sum`" - +# Verify that all files have appropriate copyright headers. + if test -d '$(distdir)'; then $(srcdir)/check-copyright-headers '$(distdir)'; fi # OS/2 port. diff --git a/check-copyright-headers b/check-copyright-headers new file mode 100755 index 000000000..27a68d593 --- /dev/null +++ b/check-copyright-headers @@ -0,0 +1,283 @@ +#!/bin/sh +# +# Copyright (C) 2019 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# This script checks whether the files in the GNU gettext package +# have the required copyright headers resp. license notices. +# +# Copyright notices have two purposes: +# +# 1. They tell the people who obtain the package (as a git checkout, +# source tarball, or binary package) what they are allowed to do +# with it. +# +# 2. They provide the legal basis for suing people who infringe on +# the copyright of the package (or part of it). In particular, +# they should prove that the infringer knew what they were doing +# when they took a source file (or part of it) and used it in +# a way that is not compliant with the license. +# +# For the purpose 1, a file COPYING at the top-level of the package +# and a reference to it in the main README are all that's needed. +# +# For the purpose 2, we put copyright notices in each file that we +# don't want to be abused of. See also the section "Copyright Notices" +# in the 'Information for maintainers of GNU software', +# . +# +# This script helps with purpose 2. The input of this script is a +# source tarball, not a git checkout. Rationale: +# - It is convenient to add files to a git repository, without having +# to attach a copyright notice to it. +# - Files that we don't include in the source tarball are not so valuable +# that we would like to sue infringers over them. +# +# We classify the files in several categories: +# - Source code that ends up being executed by end users (in source or +# compiled form). This is the most valuable one and needs copyright +# notices. +# - Source of large documentation. This is valuable too, and needs +# copyright notices. +# - Source code of build infrastructure. +# - Files that contain convenience information for programmers and +# packagers. +# The latter categories are not valuable enough to warrant sueing +# infringers. +# +# Not all files files qualify for a copyright header. Namely, since +# copyright applies to the expression of an idea (think roughly of the +# program as an art work), it makes no sense to attach a copyright header +# to a file which different programmers would write in the same way. +# This includes tiny files, as well as files that contain only machine- +# generated data. + +# Usage: check-copyright-headers UNPACKED-GETTEXT-TARBALL + +progname="$0" + +if test $# != 1; then + echo "Usage: check-copyright-headers UNPACKED-GETTEXT-TARBALL" 1>&2 + exit 1 +fi + +dir="$1" +test -d "$dir" || { + echo "*** $progname: '$dir' is not a directory." 1>&2 + exit 1 +} +if test -d "$dir/.git"; then + echo "*** $progname: '$dir' is a git checkout, not an unpacked tarball." 1>&2 + exit 1 +fi + +# func_check_file FILE +# checks FILE, a relative file name. +# Return code: 0 if OK, 1 if missing a copyright header. +func_check_file () +{ + case "/$1" in + + */tests/* | *-tests/* ) + # A test file. + # We are not interested in suing infringers of test code. + # In fact, anyone can apply our test suites to even prorietary software. + # And this is even welcome (regarding the competing implementations of + # the libintl functions), because it helps in portability of software + # that uses the libintl API. + return 0 ;; + + */modules/* ) + # Gnulib modules are not valuable enough to warrant suing infringers. + # Also, they often don't have much programmer expression. + return 0 ;; + + /gettext-tools/doc/ISO_3166 | /gettext-tools/doc/ISO_3166_de | \ + /gettext-tools/doc/ISO_639 | /gettext-tools/doc/ISO_639-2 | \ + /gettext-tools/examples/hello-*/m4/Makefile.am | \ + /gettext-tools/examples/hello-objc-gnustep/po/LocaleAliases ) + # These are a mostly data. They don't have much programmer expression. + return 0 ;; + + */ChangeLog* ) + # ChangeLog files are convenience information, not worth sueing for. + return 0 ;; + + */AUTHORS | */COPYING* | */DEPENDENCIES | */FILES | */HACKING | \ + */INSTALL* | */NEWS | */PACKAGING | */README* | */THANKS ) + # These files contain convenience information, not worth sueing for. + return 0 ;; + + /os2/* ) + # Old stuff, not worth sueing for. + return 0 ;; + + */libcroco/* | */libxml/* ) + # We repackage libcroco and libxml as sources and are not interested + # in attaching our own copyright header to each. + return 0 ;; + + /gettext-tools/examples/hello-*-gnome/m4/*.m4 | \ + /gettext-tools/projects/GNOME/teams.html ) + # These files come from the GNOME project. + # We are not interested in attaching our own copyright header to each. + return 0 ;; + + /gettext-tools/examples/hello-*-kde/admin/* | \ + /gettext-tools/projects/KDE/teams.html ) + # These files come from the KDE project. + # We are not interested in attaching our own copyright header to each. + return 0 ;; + + /gettext-tools/examples/hello-*-wxwidgets/m4/wxwidgets.m4 ) + # These files come from the wxwidgets project. + # We are not interested in attaching our own copyright header to each. + return 0 ;; + + /gettext-tools/projects/TP/teams.html ) + # These files come from the translationproject.org project. + # We are not interested in attaching our own copyright header to each. + return 0 ;; + + /gettext-tools/misc/DISCLAIM ) + # This is a form, used for communication with the FSF. + return 0 ;; + + *.gmo ) + # These are binary files. FOO.gmo is generated from FOO.po, which is + # also distributed. + return 0 ;; + + *.class ) + # These are binary files. FOO.class is generated from FOO.java, which is + # also distributed. + return 0 ;; + + /gettext-runtime/intl-csharp/doc/* | \ + /gettext-runtime/intl-java/javadoc2/* | \ + /gettext-runtime/doc/matrix.texi | \ + /gettext-tools/doc/iso-639.texi | /gettext-tools/doc/iso-639-2.texi | \ + /gettext-tools/doc/iso-3166.texi | \ + */man/*.[13].html | \ + */*_[0-9].html | */*_[0-9][0-9].html | \ + */*_all.html | */*_toc.html | */*_fot.html | */*_abt.html | \ + *.priv.h | *.vt.h | \ + /libtextstyle/lib/libtextstyle.sym.in ) + # These are generated files. We ship their sources as well. + return 0 ;; + + *.diff ) + # These are patches to existing files. It is understood that the patch + # preserves the copyright status of the file, that is, that the .diff + # file delegates its copyright status to the file. + return 0 ;; + + */quot.sed | */boldquot.sed | */en@quot.header | */en@boldquot.header ) + if test -f "$dir"/`dirname "$1"`/Rules-quot; then + # These files are covered by the notice in the Rules-quot file in the + # same directory. + return 0 + fi + ;; + + /gettext-tools/libgrep/kwset.c ) + # The file has a copyright header, with the Copyright line spread + # across two lines. + return 0 ;; + + */texinfo.tex ) + # The file has a copyright header, with the Copyright line spread + # across three lines. + return 0 ;; + + *.texi ) + if head -n 100 "$dir/$1" | LC_ALL=C grep 'Copyright ([Cc]) ' >/dev/null; then + # The file has a copyright notice, although not exactly at the beginning. + return 0 + fi + ;; + + *.rc ) + if LC_ALL=C grep 'This program is free software[:;] you can redistribute it' "$dir/$1" >/dev/null \ + || LC_ALL=C grep 'This library is free software[:;] you can redistribute it' "$dir/$1" >/dev/null; then + # The file carries a copyright notice in it. + return 0 + fi + ;; + + esac + + if head -n 15 "$dir/$1" | LC_ALL=C grep 'Copyright ([Cc]) ' >/dev/null; then + # The file has a copyright header. + return 0 + fi + + # + # says that the (C) "can be omitted entirely; the word ‘Copyright’ suffices. + if head -n 15 "$dir/$1" | LC_ALL=C grep 'Copyright .* Free Software Foundation' >/dev/null; then + # The file has a copyright header. + return 0 + fi + + # + # says " If a file has been explicitly placed in the public domain, then + # instead of a copyright notice, it should have a notice saying explicitly + # that it is in the public domain." + if head -n 15 "$dir/$1" | LC_ALL=C grep 'This .* is in the public domain\.' >/dev/null \ + || head -n 15 "$dir/$1" | LC_ALL=C fgrep 'In the public domain.' >/dev/null \ + || head -n 15 "$dir/$1" | LC_ALL=C fgrep 'Public domain.' >/dev/null \ + || head -n 15 "$dir/$1" | LC_ALL=C fgrep 'public-domain implementation' >/dev/null; then + # The file has a public domain notice. + return 0 + fi + + if head -n 15 "$dir/$1" | LC_ALL=C fgrep 'This file is distributed under the same license as ' >/dev/null; then + # The file has a notice that delegates to another copyright notice. + return 0 + fi + + if head -n 1 "$dir/$1" | LC_ALL=C fgrep 'Generated from configure.ac by autoheader.' >/dev/null \ + || head -n 1 "$dir/$1" | LC_ALL=C fgrep 'code produced by gperf version' >/dev/null \ + || head -n 1 "$dir/$1" | LC_ALL=C fgrep 'Creator : groff version' >/dev/null \ + || head -n 1 "$dir/$1" | LC_ALL=C fgrep 'DO NOT MODIFY THIS FILE! It was generated by help2man' >/dev/null \ + || head -n 3 "$dir/$1" | LC_ALL=C fgrep 'Generated automatically by gen-uni-tables.c for Unicode' >/dev/null \ + || head -n 6 "$dir/$1" | LC_ALL=C fgrep 'Generated automatically by the gen-uninames utility.' >/dev/null; then + # These are generated files. We ship their sources as well. + return 0 + fi + + if test `LC_ALL=C wc -l < "$dir/$1"` -le 8; then + # The file has very few lines. + # It thus doesn't have much programmer expression. + return 0 + fi + + return 1 +} + +fail=false +for file in `cd "$dir" && find . -type f -print | sed -e 's,^[.]/,,' | LC_ALL=C sort`; do + func_check_file "$file" || { + echo "*** Missing copyright header in file $file" 1>&2 + fail=true + } +done + +if $fail; then + exit 1 +else + exit 0 +fi