summaryrefslogtreecommitdiff
path: root/utils/git-testament.pl
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@netsurf-browser.org>2012-06-04 15:48:21 +0000
committerDaniel Silverstone <dsilvers@netsurf-browser.org>2012-06-04 15:48:21 +0000
commit0437f81c55eb1a3d37cfbc1598ee861efe68c70a (patch)
tree1688f16be4cb4f5a0ad5ae0db1c151152a1aac94 /utils/git-testament.pl
parent9154e8b940c2a420c1af6257c7ac3c3a46d40c20 (diff)
downloadnetsurf-0437f81c55eb1a3d37cfbc1598ee861efe68c70a.tar.gz
netsurf-0437f81c55eb1a3d37cfbc1598ee861efe68c70a.tar.bz2
Testament generation now supports git
svn path=/trunk/netsurf/; revision=13946
Diffstat (limited to 'utils/git-testament.pl')
-rw-r--r--utils/git-testament.pl220
1 files changed, 220 insertions, 0 deletions
diff --git a/utils/git-testament.pl b/utils/git-testament.pl
new file mode 100644
index 000000000..5d1586bed
--- /dev/null
+++ b/utils/git-testament.pl
@@ -0,0 +1,220 @@
+#!/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 $root = shift @ARGV;
+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
+ my $have_file_tmp = eval { require File::Temp };
+
+ if ( ! $have_file_tmp ) {
+ return "$$.gitt";
+ } else {
+ return File::Temp::tmpnam();
+ }
+}
+
+sub compat_md5_hex {
+ # Digest::MD5 was introduced in Perl 5.7.1
+ my $have_digest_md5 = eval { require Digest::MD5 };
+ my $have_md5 = eval { require MD5 };
+ my $data = shift;
+
+ if ( ! $have_digest_md5 ) {
+ return MD5->hexhash($data);
+ } else {
+ return Digest::MD5->new->add($data)->hexdigest;
+ }
+}
+
+sub gather_output {
+ my $cmd = shift;
+ my $tmpfile = compat_tmpnam();
+ local $/ = undef();
+ system("$cmd > $tmpfile");
+ open(my $CMDH, "<", $tmpfile);
+ my $ret = <$CMDH>;
+ close($CMDH);
+ unlink($tmpfile);
+ return $ret;
+}
+
+if ( $git_present ) {
+ my @bits = split /\s+/, `git config --get-regexp "^remote.*.url\$"`;
+ $gitinfo{url} = $bits[1];
+ chomp $gitinfo{url};
+ $gitinfo{revision} = `git rev-parse HEAD`;
+ chomp $gitinfo{revision};
+ $gitinfo{branch} = `git for-each-ref --format="\%(refname:short)" \$(git symbolic-ref HEAD)`;
+ chomp $gitinfo{branch};
+ @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"))) {
+ chomp $line;
+ 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
+
+{
+ my @pwent = getpwuid($<);
+ $userinfo{USERNAME} = $pwent[0];
+ my $gecos = $pwent[6];
+ $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);
+chomp $compiledate;
+
+# 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");
+ chomp $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";
+
+$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;
+ }
+ }
+ close($OLDVALUES);
+}
+
+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";
+ close($NEWVALUES);
+ foreach my $unwanted (@ARGV) {
+ next unless(-e $unwanted);
+ print "TESTAMENT: Removing $unwanted\n";
+ system("rm", "-f", "--", $unwanted);
+ }
+} else {
+ print "TESTMENT: unchanged\n";
+}
+
+exit 0;
+
+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
+ return 1;
+}