Initial testament functionality

svn path=/trunk/netsurf/; revision=12020
This commit is contained in:
Daniel Silverstone 2011-03-13 11:59:20 +00:00
parent c29ae3efef
commit cc18b5f21e
4 changed files with 245 additions and 1 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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 */
};

150
utils/svn-testament.pl Executable file
View File

@ -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;
}