update-my-copyright.pl now works with Git
This script now takes command line options: ``` ./update-my-copyright.pl [options] --help | -h This help message --quiet | -q Only output critical messages to stdout --check-only exit(111) if there are files with copyrights to edit --search-name=NAME Set search name to NAME --formal-same=NAME Set formal name to NAME ``` The `--check-only` and `--quiet` options are suitable for use in a git pre-commit script to check for out of date copyright headers. Reviewed by jsquyres This commit was SVN r28742.
Этот коммит содержится в:
родитель
028f5ee7a6
Коммит
5626371196
@ -46,6 +46,21 @@
|
||||
|
||||
use strict;
|
||||
use Cwd;
|
||||
use Getopt::Long;
|
||||
|
||||
# Set to true if the script should merely check for up-to-date copyrights.
|
||||
# Will exit with status 111 if there are out of date copyrights which this
|
||||
# script can correct.
|
||||
my $CHECK_ONLY = 0;
|
||||
# used by $CHECK_ONLY logic for bookeeping
|
||||
my $would_replace = 0;
|
||||
|
||||
# Set to true to suppress most informational messages. Only out of date files
|
||||
# will be printed.
|
||||
my $QUIET = 0;
|
||||
|
||||
# Set to true if we just want to see the help message
|
||||
my $HELP = 0;
|
||||
|
||||
# Defaults
|
||||
my $my_search_name = "Cisco";
|
||||
@ -56,13 +71,45 @@ $my_search_name = $ENV{OMPI_COPYRIGHT_SEARCH_NAME}
|
||||
if (defined($ENV{OMPI_COPYRIGHT_SEARCH_NAME}));
|
||||
$my_formal_name = $ENV{OMPI_COPYRIGHT_FORMAL_NAME}
|
||||
if (defined($ENV{OMPI_COPYRIGHT_FORMAL_NAME}));
|
||||
print "==> Copyright search name: $my_search_name\n";
|
||||
print "==> Copyright formal name: $my_formal_name\n";
|
||||
|
||||
GetOptions(
|
||||
"help" => \$HELP,
|
||||
"quiet" => \$QUIET,
|
||||
"check-only" => \$CHECK_ONLY,
|
||||
"search-name=s" => \$my_search_name,
|
||||
"formal-name=s" => \$my_formal_name,
|
||||
) or die "unable to parse options, stopped";
|
||||
|
||||
if ($HELP) {
|
||||
print <<EOT;
|
||||
$0 [options]
|
||||
|
||||
--help | -h This help message
|
||||
--quiet | -q Only output critical messages to stdout
|
||||
--check-only exit(111) if there are files with copyrights to edit
|
||||
--search-name=NAME Set search name to NAME
|
||||
--formal-same=NAME Set formal name to NAME
|
||||
EOT
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# predeclare sub for print-like syntax
|
||||
sub quiet_print {
|
||||
unless ($QUIET) {
|
||||
print @_;
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
quiet_print "==> Copyright search name: $my_search_name\n";
|
||||
quiet_print "==> Copyright formal name: $my_formal_name\n";
|
||||
|
||||
# Get the year
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
||||
$year += 1900;
|
||||
print "==> This year: $year\n";
|
||||
quiet_print "==> This year: $year\n";
|
||||
|
||||
# Find the top-level OMPI source tree dir
|
||||
my $start = cwd();
|
||||
@ -75,61 +122,29 @@ while (! -f "$top/Makefile.man-page-rules") {
|
||||
}
|
||||
chdir($start);
|
||||
|
||||
print "==> Top-level Open MPI dir: $top\n";
|
||||
print "==> Current directory: $start\n";
|
||||
quiet_print "==> Top-level Open MPI dir: $top\n";
|
||||
quiet_print "==> Current directory: $start\n";
|
||||
|
||||
# Are we hg or svn? If we're both hg and svn, assume svn.
|
||||
my $cmd;
|
||||
if (-d "$top/.svn") {
|
||||
$cmd = "svn st .";
|
||||
} elsif (-d "$top/.hg") {
|
||||
$cmd = "hg st .";
|
||||
} elsif (-d "$top/.git") {
|
||||
$cmd = "git status .";
|
||||
} else {
|
||||
die "Can't find SVN or HG meta dirs";
|
||||
}
|
||||
# Select VCS used to obtain modification info. Choose in increasing priority
|
||||
# order (last hit wins).
|
||||
my $vcs;
|
||||
$vcs = "git"
|
||||
if (-d "$top/.git");
|
||||
$vcs = "hg"
|
||||
if (-d "$top/.hg");
|
||||
$vcs = "svn"
|
||||
if (-d "$top/.svn");
|
||||
|
||||
# Run the command, parsing the output. Make a list of files that are
|
||||
# added or modified.
|
||||
print "==> Running: \"$cmd\"\n";
|
||||
open(CMD, "$cmd|") || die "Can't run command";
|
||||
my @files;
|
||||
while (<CMD>) {
|
||||
chomp;
|
||||
# SVN and HG use this form
|
||||
if ($_ =~ /^M/ || $_ =~ /^A/) {
|
||||
my @tokens = split(/\s+/, $_);
|
||||
# Handle output of both forms:
|
||||
# M filenameA
|
||||
# A + filenameB
|
||||
my $filename = $tokens[1];
|
||||
$filename = $tokens[2]
|
||||
if ($tokens[1] =~ /\+/);
|
||||
# Don't bother saving directory names
|
||||
push(@files, $filename)
|
||||
if (-f $filename);
|
||||
}
|
||||
|
||||
# Git uses these forms
|
||||
elsif ($_ =~ m/^#\s+modified:\s+(\S+)$/) {
|
||||
push(@files, $1)
|
||||
if (-f $1);
|
||||
} elsif ($_ =~ m/^#\s+new file:\s+(\S+)$/) {
|
||||
push(@files, $1)
|
||||
if (-f $1);
|
||||
}
|
||||
}
|
||||
close(CMD);
|
||||
my @files = find_modified_files($vcs);
|
||||
|
||||
if ($#files < 0) {
|
||||
print "No added / changed files -- nothing to do\n";
|
||||
quiet_print "No added / changed files -- nothing to do\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
# Examine each of the files and see if they need an updated copyright
|
||||
foreach my $f (@files) {
|
||||
print "Processing added/changed file: $f\n";
|
||||
quiet_print "Processing added/changed file: $f\n";
|
||||
open(FILE, $f) || die "Can't open file: $f";
|
||||
|
||||
# Read in the file, and look for the "$COPYRIGHT$" token; that's
|
||||
@ -159,8 +174,8 @@ foreach my $f (@files) {
|
||||
|
||||
# If there was not copyright token, don't do anything
|
||||
if (!defined($token_line_index)) {
|
||||
print "==> WARNING: Did not find the \$COPYRIGHT\$ token!\n";
|
||||
print " File left unchanged\n";
|
||||
quiet_print "==> WARNING: Did not find the \$COPYRIGHT\$ token!\n";
|
||||
quiet_print " File left unchanged\n";
|
||||
next;
|
||||
}
|
||||
|
||||
@ -170,13 +185,13 @@ foreach my $f (@files) {
|
||||
|
||||
# Now act on it
|
||||
if (!defined($my_line_index)) {
|
||||
print "--- My copyright line not found; adding:\n";
|
||||
quiet_print "--- My copyright line not found; adding:\n";
|
||||
my $str = "${prefix}Copyright (c) $year $my_formal_name\n";
|
||||
print " $str";
|
||||
quiet_print " $str";
|
||||
$lines[$token_line_index] = $str . $lines[$token_line_index];
|
||||
} else {
|
||||
print "--- Found existing copyright line:\n";
|
||||
print " $lines[$my_line_index]";
|
||||
quiet_print "--- Found existing copyright line:\n";
|
||||
quiet_print " $lines[$my_line_index]";
|
||||
$lines[$my_line_index] =~ m/([\d+\-]+)/;
|
||||
my $years = $1;
|
||||
die "Could not find years in copyright line!"
|
||||
@ -202,10 +217,10 @@ foreach my $f (@files) {
|
||||
# Do we need to do anything?
|
||||
if ($year > $last_year) {
|
||||
$lines[$my_line_index] = "${prefix}Copyright (c) $first_year-$year $my_formal_name\n";
|
||||
print " Updated to:\n";
|
||||
print " $lines[$my_line_index]";
|
||||
quiet_print " Updated to:\n";
|
||||
quiet_print " $lines[$my_line_index]";
|
||||
} else {
|
||||
print " This year already included in copyright; not changing file\n";
|
||||
quiet_print " This year already included in copyright; not changing file\n";
|
||||
next;
|
||||
}
|
||||
}
|
||||
@ -217,7 +232,115 @@ foreach my $f (@files) {
|
||||
print FILE join('', @lines);
|
||||
close(FILE);
|
||||
|
||||
# Now replace the old one
|
||||
unlink($f);
|
||||
rename($newf, $f);
|
||||
if ($CHECK_ONLY) {
|
||||
# intentional "loud" print to be more useful in a pre-commit hook
|
||||
print "==> '$f' has a stale/missing copyright\n";
|
||||
unlink($newf);
|
||||
++$would_replace;
|
||||
}
|
||||
else {
|
||||
# Now replace the old one
|
||||
unlink($f);
|
||||
rename($newf, $f);
|
||||
}
|
||||
}
|
||||
|
||||
if ($CHECK_ONLY and $would_replace) {
|
||||
exit(111);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Takes two arguments, the top level directory and the VCS method. Returns a
|
||||
# list of file names (relative to pwd) which the VCS considers to be modified.
|
||||
sub find_modified_files {
|
||||
my $vcs = shift;
|
||||
my @files = ();
|
||||
|
||||
if ($vcs eq "git") {
|
||||
# Number of path entries to remove from ${top}-relative paths.
|
||||
# (--show-cdup either returns the empty string or sequence of "../"
|
||||
# entries, always ending in a "/")
|
||||
my $n_strip = scalar(split(m!/!, scalar(`git rev-parse --show-cdup`))) - 1;
|
||||
|
||||
# "." restricts scope, but does not get us relative path names
|
||||
my $cmd = "git status -z --porcelain --untracked-files=no .";
|
||||
quiet_print "==> Running: \"$cmd\"\n";
|
||||
my $lines = `$cmd`;
|
||||
|
||||
# From git-status(1):
|
||||
# X Y Meaning
|
||||
# -------------------------------------------------
|
||||
# [MD] not updated
|
||||
# M [ MD] updated in index
|
||||
# A [ MD] added to index
|
||||
# D [ M] deleted from index
|
||||
# R [ MD] renamed in index
|
||||
# C [ MD] copied in index
|
||||
# [MARC] index and work tree matches
|
||||
# [ MARC] M work tree changed since index
|
||||
# [ MARC] D deleted in work tree
|
||||
# -------------------------------------------------
|
||||
# D D unmerged, both deleted
|
||||
# A U unmerged, added by us
|
||||
# U D unmerged, deleted by them
|
||||
# U A unmerged, added by them
|
||||
# D U unmerged, deleted by us
|
||||
# A A unmerged, both added
|
||||
# U U unmerged, both modified
|
||||
# -------------------------------------------------
|
||||
# ? ? untracked
|
||||
# -------------------------------------------------
|
||||
foreach my $line (split /\x{00}/, $lines) {
|
||||
my $keep = 0;
|
||||
my ($s1, $s2, $fullname) = $line =~ m/^(.)(.) (.*)$/;
|
||||
|
||||
# ignore all merge cases
|
||||
next if ($s1 eq "D" and $s2 eq "D");
|
||||
next if ($s1 eq "A" and $s2 eq "A");
|
||||
next if ($s1 eq "U" or $s2 eq "U");
|
||||
|
||||
# only update for actually added/modified cases, no copies,
|
||||
# renames, etc.
|
||||
$keep = 1 if ($s1 eq "M" or $s2 eq "M");
|
||||
$keep = 1 if ($s1 eq "A");
|
||||
|
||||
if ($keep) {
|
||||
my $relname = $fullname;
|
||||
$relname =~ s!^([^/]*/){$n_strip}!!g;
|
||||
|
||||
push @files, $relname
|
||||
if (-f $relname);
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ($vcs eq "hg" or $vcs eq "svn") {
|
||||
my $cmd = "$vcs st .";
|
||||
|
||||
# Run the command, parsing the output. Make a list of files that are
|
||||
# added or modified.
|
||||
quiet_print "==> Running: \"$cmd\"\n";
|
||||
open(CMD, "$cmd|") || die "Can't run command";
|
||||
while (<CMD>) {
|
||||
chomp;
|
||||
if ($_ =~ /^M/ || $_ =~ /^A/) {
|
||||
my @tokens = split(/\s+/, $_);
|
||||
# Handle output of both forms:
|
||||
# M filenameA
|
||||
# A + filenameB
|
||||
my $filename = $tokens[1];
|
||||
$filename = $tokens[2]
|
||||
if ($tokens[1] =~ /\+/);
|
||||
# Don't bother saving directory names
|
||||
push(@files, $filename)
|
||||
if (-f $filename);
|
||||
}
|
||||
}
|
||||
close(CMD);
|
||||
}
|
||||
else {
|
||||
die "unknown VCS '$vcs', stopped";
|
||||
}
|
||||
|
||||
return @files;
|
||||
}
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user