From cc18b5f21e5c81c87e547b496eb4cf083aafb513 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sun, 13 Mar 2011 11:59:20 +0000 Subject: Initial testament functionality svn path=/trunk/netsurf/; revision=12020 --- Makefile | 10 +++- Makefile.sources | 2 + content/fetchers/about.c | 84 ++++++++++++++++++++++++++ utils/svn-testament.pl | 150 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 245 insertions(+), 1 deletion(-) create mode 100755 utils/svn-testament.pl diff --git a/Makefile b/Makefile index 2761a0dbb..10e9c8779 100644 --- a/Makefile +++ b/Makefile @@ -359,7 +359,7 @@ $(TOOLROOT)/created: $(OBJROOT)/created $(Q)$(MKDIR) $(TOOLROOT) $(Q)$(TOUCH) $(TOOLROOT)/created -CLEANS := clean-target +CLEANS := clean-target clean-testament POSTEXES := @@ -480,6 +480,10 @@ clean-target: $(VQ)echo " CLEAN: $(EXETARGET)" $(Q)$(RM) $(EXETARGET) +clean-testament: + $(VQ)echo " CLEAN: utils/testament.h" + $(Q)$(RM) utils/testament.h + clean-builddir: $(VQ)echo " CLEAN: $(OBJROOT)" $(Q)$(RM) -r $(OBJROOT) @@ -487,6 +491,10 @@ CLEANS += clean-builddir all-program: $(EXETARGET) post-exe +.PHONY: testament +testament: + $(Q)$(PERL) utils/svn-testament.pl $(shell pwd) utils/testament.h + post-exe: $(POSTEXES) .SUFFIXES: diff --git a/Makefile.sources b/Makefile.sources index 3b9e11368..6651f4943 100644 --- a/Makefile.sources +++ b/Makefile.sources @@ -45,6 +45,8 @@ S_BROWSER := browser.c download.c frames.c history_core.c netsurf.c \ save_complete.c save_text.c selection.c textinput.c S_BROWSER := $(addprefix desktop/,$(S_BROWSER)) +# The following files depend on the testament +content/fetchers/about.c: testament # Some extra rules for building the transliteration table. ifeq ($(HOST),riscos) diff --git a/content/fetchers/about.c b/content/fetchers/about.c index 4d6b13ce0..1f441d485 100644 --- a/content/fetchers/about.c +++ b/content/fetchers/about.c @@ -46,6 +46,7 @@ #include "utils/url.h" #include "utils/utils.h" #include "utils/ring.h" +#include "utils/testament.h" struct fetch_about_context; @@ -279,6 +280,88 @@ fetch_about_choices_handler_aborted: return false; } +/** Generate the text of an svn testament which represents the current + * build-tree status + */ +typedef struct { const char *leaf; const char modtype; } modification_t; +static bool fetch_about_testament_handler(struct fetch_about_context *ctx) +{ + static modification_t modifications[] = WT_MODIFICATIONS; + char buffer[1024]; + int code = 200; + int slen; + int i; + + + /* content is going to return ok */ + fetch_set_http_code(ctx->fetchh, code); + + /* content type */ + if (fetch_about_send_header(ctx, "Content-Type: text/plain")) + goto fetch_about_testament_handler_aborted; + + slen = snprintf(buffer, sizeof buffer, + "# Automatically generated by NetSurf build system\n\n"); + + if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen, + FETCH_ERROR_NO_ERROR)) + goto fetch_about_testament_handler_aborted; + + slen = snprintf(buffer, sizeof buffer, +#if defined(WT_BRANCHISTRUNK) + "# This is a *DEVELOPMENT* build from the trunk.\n\n" +#elif defined(WT_BRANCHISRELEASE) + "# This is a release build of NetSurf\n\n" +#else + "# This NetSurf was built from a branch.\n\n" +#endif + ); + + if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen, + FETCH_ERROR_NO_ERROR)) + goto fetch_about_testament_handler_aborted; + + + slen = snprintf(buffer, sizeof buffer, + "Built by %s (%s) from %s at revision %s\n\n", + GECOS, USERNAME, WT_BRANCHPATH, WT_REVID); + + if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen, + FETCH_ERROR_NO_ERROR)) + goto fetch_about_testament_handler_aborted; + + if (WT_MODIFIED > 0) { + slen = snprintf(buffer, sizeof buffer, + "Working tree has %d modification%s\n\n", + WT_MODIFIED, WT_MODIFIED == 1 ? "" : "s"); + } else { + slen = snprintf(buffer, sizeof buffer, + "Working tree is not modified.\n"); + } + + if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen, + FETCH_ERROR_NO_ERROR)) + goto fetch_about_testament_handler_aborted; + + for (i = 0; i < WT_MODIFIED; ++i) { + slen = snprintf(buffer, sizeof buffer, + " %c %s\n", + modifications[i].modtype, + modifications[i].leaf); + if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen, + FETCH_ERROR_NO_ERROR)) + goto fetch_about_testament_handler_aborted; + + } + + fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0, + FETCH_ERROR_NO_ERROR); + + return true; + +fetch_about_testament_handler_aborted: + return false; +} struct about_handlers { const char *name; @@ -290,6 +373,7 @@ struct about_handlers about_handler_list[] = { { "licence", fetch_about_licence_handler }, { "config", fetch_about_config_handler }, { "Choices", fetch_about_choices_handler }, + { "testament", fetch_about_testament_handler }, { "blank", fetch_about_blank_handler } /* The default */ }; diff --git a/utils/svn-testament.pl b/utils/svn-testament.pl new file mode 100755 index 000000000..35df4af15 --- /dev/null +++ b/utils/svn-testament.pl @@ -0,0 +1,150 @@ +#!/usr/bin/perl -w + +use strict; + +=head1 + +Generate a testament describing the current SVN status. This gets written +out in a C form which can be used to construct the NetSurf SVN testament +file for signon notification. + +If there is no SVN in place, the data is invented arbitrarily. + +=cut + +my $root = shift @ARGV; +my $targetfile = shift @ARGV; + +my %svninfo; # The SVN info output + +my $svn_present = 0; +if ( -d ".svn" ) { + $svn_present = 1; +} + +if ( $svn_present ) { + foreach my $line (split(/\n/, `cd $root;svn info`)) { + my ($key, $value) = split(/: /, $line, 2); + $key = lc($key); + $key =~ s/\s+//g; + $svninfo{$key} = $value; + } +} else { + $svninfo{repositoryroot} = "http://nowhere/"; + $svninfo{url} = "http://nowhere/netsurf/trunk/"; + $svninfo{revision} = "0"; +} + +my %svnstatus; # The SVN status output + +if ( $svn_present ) { + foreach my $line (split(/\n/, `cd $root; svn status `)) { + my $op = substr($line, 0, 1); + if ($op eq ' ' && substr($line, 1, 1) ne ' ') { $op = "p"; } + my $fn = substr($line, 7); + next unless (care_about_file($fn, $op)); + $svnstatus{$fn} = $op; + } +} + +my %userinfo; # The information about the current user + +{ + my $pwdline = `getent passwd $<`; + chomp $pwdline; + my @pwdinfo = split(/:/, $pwdline); + $userinfo{USERNAME} = $pwdinfo[0]; + my $gecos = $pwdinfo[4]; + $gecos =~ s/,.+//g; + $gecos =~ s/"/'/g; + $userinfo{GECOS} = $gecos; +} + +# Spew the testament out + +my $testament = ""; + +$testament .= "#define USERNAME \"$userinfo{USERNAME}\"\n"; +$testament .= "#define GECOS \"$userinfo{GECOS}\"\n"; + +my $url = $svninfo{url}; +# This only works on 1.3.x and above +$url = substr($url, length($svninfo{repositoryroot})); +if ( substr($url,0,1) ne '/' ) { $url = "/$url"; } +$testament .= "#define WT_BRANCHPATH \"$url\"\n"; +if ($url =~ m@/trunk/@) { + $testament .= "#define WT_BRANCHISTRUNK 1\n"; +} +if ($url =~ m@/tags/@) { + $testament .= "#define WT_BRANCHISTAG 1\n"; +} +$testament .= "#define WT_REVID \"$svninfo{revision}\"\n"; +$testament .= "#define WT_MODIFIED " . scalar(keys %svnstatus) . "\n"; +$testament .= "#define WT_MODIFICATIONS {\\\n"; +my $doneone = 0; +foreach my $filename (sort keys %svnstatus) { + if ($doneone) { + $testament .= ", \\\n"; + } + $testament .= " { \"$filename\", '$svnstatus{$filename}' }"; + $doneone = 1; +} +$testament .= " \\\n}\n"; + +use Digest::MD5 qw(md5_hex); + +my $oldcsum = ""; +if ( -e $targetfile ) { + open OLDVALUES, "<", $targetfile; + foreach my $line (readline(OLDVALUES)) { + if ($line =~ /MD5:([0-9a-f]+)/) { + $oldcsum = $1; + } + } + close OLDVALUES; +} + +my $newcsum = md5_hex($testament); + +if ($oldcsum ne $newcsum) { + print "TESTMENT: $targetfile\n"; + open NEWVALUES, ">", $targetfile or die "$!"; + print NEWVALUES "/* ", $targetfile,"\n"; + print NEWVALUES <<'EOS'; + * + * Revision testament. + * + * *WARNING* this file is automatically generated by svn-testament.pl + * + * Copyright 2011 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, $op) = @_; + 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 1; +} -- cgit v1.2.3