Skip to content

Commit 225fbdc

Browse files
committed
feat: Basic copyright script and CI integration
This PR adds a script to do basic copyright notice checks, and will be used to add the necessary features in issue #7690. It reads the list of files from argv[] and exits with a useful return status. This PR also creates a copyright CI workflow
1 parent 1b4f481 commit 225fbdc

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Copyright The IETF Trust 2024. All Rights Reserved.
2+
name: Copyright years
3+
on: [pull_request, push]
4+
permissions:
5+
contents: read
6+
7+
jobs:
8+
copyright-notice:
9+
runs-on: ubuntu-latest
10+
name: Test changed-files
11+
steps:
12+
- name: Get changed files
13+
id: changed-files
14+
uses: tj-actions/changed-files@v44
15+
- uses: actions/checkout@v4
16+
- name: Check changed files
17+
env:
18+
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
19+
run: perl ./ietf/check-copyright -lv -f ${ALL_CHANGED_FILES};

ietf/check-copyright

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/usr/bin/env perl
2+
# Copyright The IETF Trust 2024. All Rights Reserved.
3+
4+
use strict;
5+
use warnings;
6+
use POSIX qw/strftime/;
7+
use Getopt::Std;
8+
9+
# Number of errors found; exit status
10+
my $ERRORS = 0;
11+
12+
# Convenience variables, for the copyright year regexp patterns.
13+
my $this_year = strftime("%Y", localtime);
14+
my $some_year = "[12][0-9][0-9][0-9]";
15+
my $year_range = "(${some_year})(-${some_year})?";
16+
my $copyright = "Copyright The IETF Trust *${year_range}";
17+
18+
# Getopt settings.
19+
our($opt_h, $opt_f, $opt_v, $opt_c, $opt_l, $opt_m);
20+
21+
sub
22+
usage()
23+
{
24+
my $retcode = pop();
25+
26+
print STDERR "Options:\n";
27+
print STDERR " -h This help message\n";
28+
print STDERR " -f Read filenames from argv\n";
29+
print STDERR " -v List files as processed\n";
30+
print STDERR " -c Modify files that should be changed\n";
31+
print STDERR " (Does not do a git commit)\n";
32+
print STDERR " -l List files that need to be changed\n";
33+
print STDERR " -m List files missing copyright\n";
34+
exit $retcode;
35+
}
36+
37+
38+
## Get list of files changed during this year.
39+
sub
40+
collect_files
41+
{
42+
# Get last commit of the of the previous year/
43+
my $FIRST=`git rev-list -1 --before=$this_year-01-01 HEAD`;
44+
chop $FIRST;
45+
46+
# Get every file changed since then, ignoring deleted files.
47+
open(my $FH, "-|", "git diff-tree -r --name-status $FIRST..HEAD")
48+
|| die "Can't open diff-tree, $!";
49+
my @FILES = ();
50+
my @FIELDS;
51+
while ( <$FH> ) {
52+
@FIELDS = split();
53+
next if $FIELDS[0] =~ /D/; # ignore deleted files
54+
push(@FILES, $FIELDS[1]);
55+
}
56+
close($FH) || die "Can't close diff-tree";
57+
return @FILES;
58+
}
59+
60+
## Process file, notice if copyright is missing or outdated.
61+
sub
62+
process()
63+
{
64+
my $NAME = pop();
65+
my $NEW = "";
66+
my $found = 0;
67+
my $changed = 0;
68+
my $SAVE;
69+
70+
print "# Processing $NAME\n" if defined $opt_v;
71+
72+
# ignore ZIP files
73+
return if $NAME =~ /\.zip/;
74+
75+
# Read the file, copying to $NEW and changing copyright
76+
# along the way.
77+
open my $FH, '<', $NAME || die "Can't open $NAME, $!";
78+
while ( <$FH> ) {
79+
$SAVE = $_;
80+
if ( /$copyright/io ) {
81+
$found = 1;
82+
$SAVE =~ s|${year_range}|$1-${this_year}|;
83+
$SAVE =~ s|(${some_year})-$1|$1|;
84+
$changed = 1 if $SAVE ne $_;
85+
}
86+
$NEW .= $SAVE;
87+
}
88+
close($FH) || die "Can't close $NAME, $!";
89+
90+
# Copyright missing?
91+
if ( defined $opt_m ) {
92+
print "$NAME\n" if ! $found;
93+
$ERRORS++;
94+
return;
95+
}
96+
97+
# Unchanged file?
98+
return if ! $changed;
99+
100+
if ( defined $opt_l ) {
101+
print "$NAME\n";
102+
$ERRORS++;
103+
} else {
104+
# Write the new file
105+
open my $FH, '>', $NAME || die "Can't close-write $NAME, $!";
106+
print $FH $NEW;
107+
close($FH) || die "Can't close-write $NAME, $!";
108+
}
109+
}
110+
111+
## Parse JCL.
112+
getopts('hfvclm') || &usage(1);
113+
&usage(0) if $opt_h;
114+
if ( defined($opt_m) + defined($opt_l) + defined($opt_c) != 1 ) {
115+
print STDERR "Must have exactly one of m/l/c options\n";
116+
exit 1;
117+
}
118+
119+
## Do the work.
120+
my @FILES = ();
121+
if ( defined($opt_f) ) {
122+
@FILES = @ARGV;
123+
} else {
124+
@FILES = &collect_files();
125+
}
126+
127+
foreach my $F ( @FILES ) {
128+
&process($F);
129+
}
130+
exit $ERRORS;

0 commit comments

Comments
 (0)