#!/usr/bin/perl -w
use strict;
=head1
Generate a testament describing the current Git status. This gets written
out in a C form which can be used to construct the NetSurf Git testament
file for signon notification.
If there is no Git in place, the data is invented arbitrarily.
=cut
$ENV{LC_ALL} = 'C';
my $targetfile = shift @ARGV;
my %gitinfo; # The Git information
$root .= "/" unless ($root =~ m@/$@);
my $git_present = 0;
if ( -d ".git" ) {
$git_present = 1;
}
sub compat_tmpnam {
# File::Temp was introduced in Perl 5.6.1
if ( ! $have_file_tmp ) {
} else {
}
}
sub compat_md5_hex {
# Digest::MD5 was introduced in Perl 5.7.1
if ( ! $have_digest_md5 ) {
} else {
return Digest
::MD5->new->add($data)->hexdigest;
}
}
sub gather_output {
my $tmpfile = compat_tmpnam();
open(my $CMDH, "<", $tmpfile);
my $ret = <$CMDH>;
}
if ( $git_present ) {
my @bits = split /\s+/, `git config --get-regexp "^remote.*.url\$"`;
$gitinfo{url} = $bits[1];
$gitinfo{revision} = `git rev-parse HEAD`;
chomp $gitinfo{revision
};
$gitinfo{branch} = `git for-each-ref --format="\%(refname:short)" \$(git symbolic-ref HEAD 2>/dev/null || git show-ref -s HEAD)`;
@bits = split /\s+/, `git describe --tags --exact-match HEAD 2>/dev/null`;
$bits[0] = "" unless exists $bits[0];
$gitinfo{tag} = $bits[0];
} else {
$gitinfo{url} = "http://nowhere/tarball/";
$gitinfo{revision} = "unknown";
$gitinfo{branch} = "tarball";
$gitinfo{tag} = "";
}
my %gitstatus; # The Git status output
if ( $git_present ) {
foreach my $line (split(/\n/, gather_output
("git status --porcelain"))) {
my ($X, $Y, $fp) = ($line =~ /^(.)(.) (.+)$/);
my $fn = $fp;
$fn = ($fp =~ /(.+) ->/) if ($fp =~ / -> /);
next unless (care_about_file($fn));
# Normalise $X and $Y (WT and index) into a simple A/M/D etc
$gitstatus{$fn} = "$X$Y";
}
}
my %userinfo; # The information about the current user
{
$userinfo{USERNAME} = $pwent[0];
my $gecos = $pwent[6];
$gecos =~ s/,.+//g;
$gecos =~ s/"/'/g;
$gecos =~ s/\\/\\\\/g;
$userinfo{GECOS} = $gecos;
}
# The current date, in AmigaOS version friendly format (dd.mm.yyyy)
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
my $compiledate = sprintf("%02d.%02d.%d",$mday,$mon+1,$year+1900);
# Spew the testament out
my $testament = "";
$testament .= "#define USERNAME \"$userinfo{USERNAME}\"\n";
$testament .= "#define GECOS \"$userinfo{GECOS}\"\n";
my $qroot = $root;
$qroot =~ s/"/\\"/g;
my $hostname = $ENV{HOSTNAME};
unless ( defined($hostname) && $hostname ne "") {
# Try hostname command if env-var empty
$hostname = gather_output("hostname");
}
$hostname = "unknown-host" unless (defined($hostname) && $hostname ne "");
$hostname =~ s/"/\\"/g;
$testament .= "#define WT_ROOT \"$qroot\"\n";
$testament .= "#define WT_HOSTNAME \"$hostname\"\n";
$testament .= "#define WT_COMPILEDATE \"$compiledate\"\n";
my $cibuild = $ENV{CI_BUILD};
if (defined ($cibuild) && ($cibuild ne '')) {
$testament .= "#define CI_BUILD \"$cibuild\"\n";
}
$testament .= "#define WT_BRANCHPATH \"$gitinfo{branch}\"\n";
if ($gitinfo{branch
} =~ m@^master
$@) {
$testament .= "#define WT_BRANCHISMASTER 1\n";
}
if ($gitinfo{tag
} =~ m@.@) {
$testament .= "#define WT_BRANCHISTAG 1\n";
$testament .= "#define WT_TAGIS \"$gitinfo{tag}\"\n";
}
if ($gitinfo{url
} =~ m@/tarball
/@) {
$testament .= "#define WT_NO_GIT 1\n";
}
$testament .= "#define WT_REVID \"$gitinfo{revision}\"\n";
$testament .= "#define WT_MODIFIED " . scalar(keys %gitstatus) . "\n";
$testament .= "#define WT_MODIFICATIONS {\\\n";
my $doneone = 0;
foreach my $filename (sort keys %gitstatus) {
if ($doneone) {
$testament .= ", \\\n";
}
$testament .= " { \"$filename\", \"$gitstatus{$filename}\" }";
$doneone = 1;
}
$testament .= " \\\n}\n";
my $oldcsum = "";
if ( -e $targetfile ) {
open(my $OLDVALUES, "<", $targetfile);
foreach my $line (readline($OLDVALUES)) {
if ($line =~ /MD5:([0-9a-f]+)/) {
$oldcsum = $1;
}
}
}
my $newcsum = compat_md5_hex($testament);
if ($oldcsum ne $newcsum) {
print "TESTMENT: $targetfile\n";
open(my $NEWVALUES, ">", $targetfile) or die "$!";
print $NEWVALUES "/* ", $targetfile,"\n";
print $NEWVALUES <<'EOS';
*
* Revision testament.
*
* *WARNING* this file is automatically generated by git-testament.pl
*
* Copyright 2012 NetSurf Browser Project
*/
EOS
print $NEWVALUES "#ifndef NETSURF_REVISION_TESTAMENT\n";
print $NEWVALUES "#define NETSURF_REVISION_TESTAMENT \"$newcsum\"\n\n";
print $NEWVALUES "/* Revision testament checksum:\n";
print $NEWVALUES " * MD5:", $newcsum,"\n */\n\n";
print $NEWVALUES "/* Revision testament: */\n";
print $NEWVALUES $testament;
print $NEWVALUES "\n#endif\n";
foreach my $unwanted (@ARGV) {
next unless(-e $unwanted);
print "TESTAMENT: Removing $unwanted\n";
system("rm", "-f", "--", $unwanted);
}
} else {
print "TESTMENT: unchanged\n";
}
sub care_about_file {
my ($fn) = @_;
return 0 if ($fn =~ /\.d$/); # Don't care for extraneous DEP files
return 0 if ($fn =~ /\.a$/); # Don't care for extraneous archive files
return 0 if ($fn =~ /\.md5$/); # Don't care for md5sum files
return 0 if ($fn =~ /\.map$/); # Don't care for map files
return 0 if ($fn =~ /\.gitt$/); # Don't care for testament temp files
}