Skip to content

Instantly share code, notes, and snippets.

@jamesray1
Created April 23, 2018 02:06
Show Gist options
  • Save jamesray1/f9754e72c452a856cf02295991a4734e to your computer and use it in GitHub Desktop.
Save jamesray1/f9754e72c452a856cf02295991a4734e to your computer and use it in GitHub Desktop.
Commented out references to author and years , but it's failing at line 131
#!/usr/bin/perl
# Copyright 2013, 2015, 2017 Nitor Creations Oy, Jonas Berlin
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
BEGIN {
push @INC, '.';
}
use strict;
use warnings;
use IPC::Open2;
use File::Temp qw(mktemp);
require '.githooks/license-maintainer/license.pm';
#sub extract_timestamp($) {
# my $gitdate = $_[0];
# if (defined($gitdate)) {
# $gitdate =~ m!(\d{9,})! and return $1;
# }
# return undef;
#}
my $EMPTY_SHA = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391';
my $INJECT_LICENSES = length(($ENV{"INJECT_LICENSES"} || "") =~ s!\s+!!r) > 0;
if ($INJECT_LICENSES) {
print STDERR qq{NOTE: Adding/updating licenses for all maintained files, i.e.
- adds license to files lacking an license
};
}
my $repoRootDir = `pwd`;
chomp $repoRootDir;
my $scriptDir = $repoRootDir.'/.githooks/license-maintainer';
my $origLineSeparator = $/;
$/="\0";
# Fetch author string to use
#my $author = `git config --get license.author`;
#unless(length($author)) {
# print STDERR "ERROR: Author not configured.\n\nConfigure with:\n\n\tgit config license.author \"My Company Inc\"\n";
# exit(1);
#}
#$author =~ s!^\s+!!;
#$author =~ s!\s+$!!;
# get list of files in stage
my @filesInStage;
open my $fileListFh, '-|', qw(git ls-files --stage -z) or die;
while(<$fileListFh>) {
chomp;
die $_ unless(m!^([0-7]{6}) ([0-9a-f]{40}) ([0-3])\t(.*)$!);
push @filesInStage, { mode => $1, sha => $2, stage => $3, name => $4 };
}
close $fileListFh;
# get the license file to use for each staged file
my %licensefile;
my $tmpfile = mktemp(File::Spec->tmpdir.'/licXXXXX');
open my $checkAttrInFh, "|-", "git check-attr licensefile -z --stdin > '$tmpfile'" or die;
print $checkAttrInFh join("\0", map { $_->{name} } @filesInStage),"\0";
close $checkAttrInFh;
open my $changeAttrOutFh, "<", $tmpfile or die;
while(<$changeAttrOutFh>) {
chomp;
my $file = $_;
<$changeAttrOutFh>; # attribute name
my $license = <$changeAttrOutFh>;
chomp $license;
$licensefile{$file} = $license if(defined($license) && length($license) && $license ne "unset" && $license ne "unspecified");
}
close $changeAttrOutFh;
#unlink($tmpfile);
# get list of files that will be changed by this commit
my %changed;
open my $changeListFh, "-|", qw(git diff --cached --raw -z --name-only --no-renames --diff-filter=AM) or die;
while(<$changeListFh>) {
chomp;
$changed{$_} = 1;
}
close $changeListFh;
$/=$origLineSeparator;
# For all files, check license. For files with changes add/update the license as needed.
my @filesInCheckoutThatCouldNotBePatchedWithLicenseUpdate;
my $numFilesWithLicenseBrokenOrMissing = 0;
foreach my $staged (@filesInStage) {
next if ($staged->{stage} != 0); # conflict exists for file, skip
my $licenseFile = $licensefile{$staged->{name}};
next unless(defined($licenseFile)); # no license formatting for file, skip
my $isFileChangedByCommit = defined($changed{$staged->{name}});
# transform file and store transformed in git
# transformedsha=`git cat-file blob <origsha> | perl license.pl LICENSE-<format> <file> | git hash-object -w --path <filepath> --stdin`
# Run "git cat-file blob <origsha>" to get the staged files' contents on stdout e.g. readable through *origFileContentFh
local *origFileContentFh;
open(\*origFileContentFh, '-|', 'git', 'cat-file', 'blob', $staged->{sha}) or die 'git cat-file '.$staged->{sha};
undef $/;
my $origFileContent = <origFileContentFh>;
$/ = $origLineSeparator;
close origFileContentFh;
my $license_text_file = $repoRootDir.'/'.$licenseFile;
if (!$isFileChangedByCommit && !$INJECT_LICENSES) {
# file not changed, just check license
my $ret = My::License::isLackingProperLicense($license_text_file, $staged->{name}, $origFileContent);
if ($ret == 0) {
# license ok
} elsif ($ret == 1) {
# license malformed, error already reported by script
++$numFilesWithLicenseBrokenOrMissing;
} elsif ($ret == 2) {
# license missing
print STDERR "WARNING: License missing in ",$staged->{name},"\n";
++$numFilesWithLicenseBrokenOrMissing;
} else {
die "Unhandled isLackingProperLicense() return code $ret";
}
} else {
# file changed, add license or update license to contain current year
#my %author_years;
#if ($isFileChangedByCommit) {
# # use author timestamp of current commit author
# my $author_date = extract_timestamp($ENV{'GIT_AUTHOR_DATE'}) || time();
# my @author_date_fields = localtime($author_date);
# my $author_year = $author_date_fields[5] + 1900;
# $author_years{$author_year} = 1;
#} else {
# # use author timestamp of commit when file was last changed
# open TSTAMPS, '-|', 'git', 'log', '--format=format:%ai', $staged->{name} or die "Internal error: Unable to find any commits for $staged->{name}";
# while (<TSTAMPS>) {
# my $author_year = substr($_,0,4);
# $author_years{$author_year} = 1;
# }
# close TSTAMPS;
# scalar(keys %author_years) >= 0 or die "Internal error: Unable to find any commits for $staged->{name}";
#}
#my ($ret, @transformedContent) = My::License::maintainLicense($license_text_file, $staged->{name}, $origFileContent, $author, !$isFileChangedByCommit, \%author_years);
my ($ret, @transformedContent) = My::License::maintainLicense($license_text_file, $staged->{name}, $origFileContent, !$isFileChangedByCommit);
if ($ret == 1) {
print STDERR "Please correct the problems before re-attempting commit\n";
exit(1);
} elsif ($ret != 0) {
die "Unhandled maintainLicense() return code $ret";
}
# Run "git hash-object -w --path <file> --stdin". stdin: transformed contents from *transformedFileContentFh, stdout: sha of contents through *transformedShaFh
local *transformedShaFh;
local *transformedFileContentFh;
my $gitHashObjectPid = open2(\*transformedShaFh, \*transformedFileContentFh, 'git', 'hash-object', '-w', '--path', $staged->{name}, '--stdin') or die 'git hash-object';
print transformedFileContentFh @transformedContent;
close transformedFileContentFh;
# read sha of transformed file
my $transformedSha = <transformedShaFh>;
die 'read git hash-object sha' unless(defined($transformedSha));
close transformedShaFh;
chomp $transformedSha;
# check exit codes of commands run
waitpid $gitHashObjectPid, 0;
die "git hash-object failed ".($? >> 8) if ($? >> 8);
# sanity check
die "Refusing to result in empty file" if($transformedSha eq $EMPTY_SHA);
# if transformed version is different from original, update stage and checkout with transformed version
unless ($staged->{sha} eq $transformedSha) {
# Update stage by using the sha of the transformed contents for the filename in question
# Run "git update-index --cacheinfo <mode> <sha> <file>" to update stage with transformed version
system('git', 'update-index', '--cacheinfo', $staged->{mode}, $transformedSha, $staged->{name}) and die 'git update-index '.$transformedSha.' '.$staged->{name}.' returned '.($? >> 8);
# The file in the checkout may be different than the file
# in the index, so we cannot overwrite it directly.
# Instead we try to apply the differencies applied by the
# license transformer, and in case that fails, let user
# resolve it.
# Run "git diff <origsha> <transformedsha>". stdin: none, stdout: effective diff of license transformer operation
local *licenseDiffFh;
open(\*licenseDiffFh, '-|', 'git', 'diff', $staged->{sha}, $transformedSha) or die 'git diff';
# Run "patch --no-backup-if-mismatch <filepath>". stdin: license diff, stdout: passed on to our stdout
my $checkoutPatchPid = open2('>&STDOUT', '<&licenseDiffFh', 'patch', '--no-backup-if-mismatch', $staged->{name}) or die 'patch';
# check exit codes of commands run
waitpid $checkoutPatchPid, 0;
if ($? >> 8) {
push @filesInCheckoutThatCouldNotBePatchedWithLicenseUpdate, $staged->{name};
}
}
}
}
if ($#filesInCheckoutThatCouldNotBePatchedWithLicenseUpdate >= 0) {
print STDERR ("\n",
"WARNING: Unable to apply license update in the checkout to the following files:\n",
" ",join("\n ", @filesInCheckoutThatCouldNotBePatchedWithLicenseUpdate),"\n",
"\n",
"Please apply the license updates manually for these files. Possibly see the associated .rej files for what changes are needed.\n",
"\n");
}
if ($numFilesWithLicenseBrokenOrMissing) {
print STDERR qq{
NOTE: Some files had license problems, kindly fix them in a separate commit by running:
INJECT_LICENSES=1 git commit --allow-empty -m 'Add/update licenses for all maintained files' --edit
This adds/updates licenses for all maintained files, i.e.
- adds license to files lacking an license
- adds the author (configured in the "license.author" configuration option) to
files lacking an author
- adds missing years to existing licenses, for example if some user committed
stuff without updating the license e.g. did not have the pre-commit hook
installed
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment