]> eyrie.org Git - kerberos/krb5-strength.git/blob - tests/docs/spdx-license-t
cf407ad2b9105281db8f9df3e92e81cd497e6fac
[kerberos/krb5-strength.git] / tests / docs / spdx-license-t
1 #!/usr/bin/perl
2 #
3 # Check source files for SPDX-License-Identifier fields.
4 #
5 # Examine all source files in a distribution to check that they contain an
6 # SPDX-License-Identifier field.  This does not check the syntax or whether
7 # the identifiers are valid.
8 #
9 # The canonical version of this file is maintained in the rra-c-util package,
10 # which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
11 #
12 # Copyright 2018-2023 Russ Allbery <eagle@eyrie.org>
13 #
14 # Permission is hereby granted, free of charge, to any person obtaining a
15 # copy of this software and associated documentation files (the "Software"),
16 # to deal in the Software without restriction, including without limitation
17 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 # and/or sell copies of the Software, and to permit persons to whom the
19 # Software is furnished to do so, subject to the following conditions:
20 #
21 # The above copyright notice and this permission notice shall be included in
22 # all copies or substantial portions of the Software.
23 #
24 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
27 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 # DEALINGS IN THE SOFTWARE.
31 #
32 # SPDX-License-Identifier: MIT
33
34 use 5.010;
35 use strict;
36 use warnings;
37
38 use lib "$ENV{C_TAP_SOURCE}/tap/perl";
39
40 use Test::RRA qw(skip_unless_automated);
41 use Test::RRA::Automake qw(all_files automake_setup);
42
43 use File::Basename qw(basename);
44 use Test::More;
45
46 # File name (the file without any directory component) and path patterns to
47 # skip for this check.
48 ## no critic (RegularExpressions::ProhibitFixedStringMatches)
49 my @IGNORE = (
50     qr{ \A LICENSE \z }xms,             # Generated file with no license itself
51     qr{ \A (NEWS|THANKS|TODO) \z }xms,  # Package license should be fine
52     qr{ \A README ( [.] .* )? \z }xms,  # Package license should be fine
53     qr{ \A (Makefile|libtool) \z }xms,  # Generated file
54     qr{ [.] json \z }xms,               # Data files without comment support
55     qr{ ~ \z }xms,                      # Backup files
56     qr{ [.] l?a \z }xms,                # Created by libtool
57     qr{ [.] o \z }xms,                  # Compiler objects
58     qr{ [.] output \z }xms,             # Test data
59 );
60 my @IGNORE_PATHS = (
61     qr{ \A cracklib/ }xms,                     # Special case for krb5-strength
62     qr{ \A debian/ }xms,                       # Found in debian/* branches
63     qr{ \A docs/metadata/ }xms,                # Package license should be fine
64     qr{ \A docs/protocol[.](html|txt) \z }xms, # Generated by xml2rfc
65     qr{ \A m4/ (libtool|lt.*) [.] m4 \z }xms,  # Files from Libtool
66     qr{ \A perl/Build \z }xms,                 # Perl build files
67     qr{ \A perl/MANIFEST \z }xms,              # Perl build files
68     qr{ \A perl/MYMETA [.] }xms,               # Perl build files
69     qr{ \A perl/blib/ }xms,                    # Perl build files
70     qr{ \A perl/cover_db/ }xms,                # Perl test files
71     qr{ \A perl/_build }xms,                   # Perl build files
72     qr{ \A php/Makefile [.] global \z }xms,    # Created by phpize
73     qr{ \A php/autom4te [.] cache/ }xms,       # Created by phpize
74     qr{ \A php/acinclude [.] m4 \z }xms,       # Created by phpize
75     qr{ \A php/build/ }xms,                    # Created by phpize
76     qr{ \A php/config [.] (guess|sub) \z }xms, # Created by phpize
77     qr{ \A php/configure [.] (ac|in) \z }xms,  # Created by phpize
78     qr{ \A php/ltmain [.] sh \z }xms,          # Created by phpize
79     qr{ \A php/run-tests [.] php \z }xms,      # Created by phpize
80     qr{ \A php/ .* [.] dep \z }xms,            # Created by phpize
81     qr{ \A python/ .* [.] egg-info/ }xms,      # Python build files
82     qr{ \A tests/config/ (?!README) }xms,      # Test configuration
83     qr{ \A tests/tmp/ }xms,                    # Temporary test files
84     qr{ [.] mypy_cache/ }xms,                  # mypy caches
85 );
86 ## use critic
87
88 # Only run this test during automated testing, since failure doesn't indicate
89 # any user-noticable flaw in the package itself.
90 skip_unless_automated('SPDX identifier tests');
91
92 # Set up Automake testing.
93 automake_setup();
94
95 # Check a single file for an occurrence of the string.
96 #
97 # $path - Path to the file
98 #
99 # Returns: undef
100 sub check_file {
101     my ($path) = @_;
102     my $filename = basename($path);
103
104     # Ignore files in the whitelist and binary files.
105     for my $pattern (@IGNORE) {
106         return if $filename =~ $pattern;
107     }
108     for my $pattern (@IGNORE_PATHS) {
109         return if $path =~ $pattern;
110     }
111     return if !-T $path;
112
113     # Scan the file.
114     my ($saw_legacy_notice, $saw_spdx, $skip_spdx);
115     open(my $file, '<', $path) or BAIL_OUT("Cannot open $path: $!");
116     while (defined(my $line = <$file>)) {
117         if ($line =~ m{ Generated [ ] by [ ] libtool [ ] }xms) {
118             close($file) or BAIL_OUT("Cannot close $path: $!");
119             return;
120         }
121         if ($line =~ m{ \b See \s+ LICENSE \s+ for \s+ licensing }xms) {
122             $saw_legacy_notice = 1;
123         }
124         if ($line =~ m{ \b SPDX-License-Identifier: \s+ \S+ }xms) {
125             $saw_spdx = 1;
126             last;
127         }
128         if ($line =~ m{ no \s SPDX-License-Identifier \s registered }xms) {
129             $skip_spdx = 1;
130             last;
131         }
132     }
133     close($file) or BAIL_OUT("Cannot close $path: $!");
134
135     # If there is a legacy license notice, report a failure regardless of file
136     # size.  Otherwise, skip files under 1KB.  They can be rolled up into the
137     # overall project license and the license notice may be a substantial
138     # portion of the file size.
139     if ($saw_legacy_notice) {
140         ok(!$saw_legacy_notice, "$path has legacy license notice");
141     } else {
142         ok($saw_spdx || $skip_spdx || -s $path < 1024, $path);
143     }
144     return;
145 }
146
147 # Scan every file.  We don't declare a plan since we skip a lot of files and
148 # don't want to precalculate the file list.
149 my @paths = all_files();
150 for my $path (@paths) {
151     check_file($path);
152 }
153 done_testing();