cgal/Packages/Maintenance/package_handling/install_www_submission

582 lines
14 KiB
Perl
Executable File

#!/sw/bin/perl -w
use strict;
use File::Find;
use Cwd;
# install_submission <url1> <url2> ...
my $testing=0;
my $MAIL_PROG='/projects/CGAL/admin_scripts/send_cgal_mail';
my ($submission, $packagedir, $oldpackagedir, $download_dir,
$console_output,
$tempdir, $check_source_file_prog, @reply_list);
my $WGET;
my $LOCKCMD="/sw/bin/lockfile";
umask 002;
sub init_variables()
{
if ($testing) {
$packagedir='/users/geert/tmp/inst_www/packages';
$oldpackagedir='/users/geert/tmp/inst_www/old_packages';
$download_dir='/users/geert/tmp/inst_www/download';
$console_output=1;
$check_source_file_prog=
'/users/geert/CGAL/Geert/maintenance/package_handling/check_headers';
} else {
$packagedir='/users/www/CGAL/Members/Develop/updates/packages';
$oldpackagedir='/projects/CGAL/old_packages';
$download_dir='/projects/CGAL/submissions/download';
$console_output=0;
$check_source_file_prog= '/projects/CGAL/admin_scripts/check_headers';
}
@reply_list = ('geert@cs.uu.nl');
$WGET="/projects/CGAL/admin_scripts/get_cgal_html";
}
$ENV{PATH}=
'/sw/bin:/sbin:/usr/sbin:/usr/bsd:/bin:/usr/bin:/usr/bin/X11';
my $ACTUAL_LOGFILE="/tmp/install_www_submission.log.$$";
# write to logfile
#
sub log_header($)
{
if ( $console_output ) {
print "$_[0]\n";
}
print LOGFILE "-------------------------------------------------------\n";
print LOGFILE " $_[0]\n";
print LOGFILE "-------------------------------------------------------\n";
}
sub log_msg($)
{
if ( $console_output ) {
print "$0: $_[0]\n";
}
print LOGFILE " $_[0]\n";
}
sub log_done()
{
if ( $console_output ) {
print " done\n-------------------------------------------------------\n"
}
print LOGFILE "-------------------------------------------------------\n";
print LOGFILE " DONE\n";
print LOGFILE "-------------------------------------------------------\n";
}
sub print_usage()
{
print STDERR "usage: $0 <url1> \n";
}
sub make_package_name($)
{
$_ = $_[0];
# remove the directory path
s|.*/||;
# remove trailing blanks
s|\s*$||;
# remove suffixes
s|\.gz$||;
s|\.tar$||;
s|\.zip$||;
s|\.tgz$||;
# remove version
# s|([-\.\d]+)+[a-zA-Z]?$||;
# or should that be
s|([-\.]\d+)+[a-zA-Z]?$||;
return $_;
}
sub belongs_to_release($)
# parameter 1 is the name of the package
{
open PACKAGES_TO_INCLUDE, "$packagedir/include_in_release" or die;
while (<PACKAGES_TO_INCLUDE>) {
chomp;
if (/^\s*$_[0]\s*$/) {
close PACKAGES_TO_INCLUDE;
return 1;
}
}
close PACKAGES_TO_INCLUDE;
return 0;
}
sub create_package_dir()
{
$tempdir="$packagedir/TMP$$";
mkdir($tempdir, 0775) ;
}
sub unpack_package($)
{
my ($full_file_name);
$full_file_name = shift;
chdir $tempdir;
if ( $full_file_name =~ /\.tar\s*$/) {
system 'gtar', 'xf', "$full_file_name";
} elsif ($full_file_name =~ /\.zip\s*$/) {
system('unzip', '-oqq', "$full_file_name");
} elsif ($full_file_name =~ /\.tgz\s*$/ or $full_file_name =~ /\.tar.gz\s*$/) {
system("gunzip -c $full_file_name | gtar xf -");
} else {
return 0;
}
return !$?;
}
sub gzip_if_psfile
{
if ($_ =~ /\.ps\s*$/ and -f $_) {
system('gzip',"$_");
}
}
sub compress_psfiles()
{
if (-d 'doc_ps') {
find(\&gzip_if_psfile, "doc_ps");
}
}
sub get_version($)
{
my ($version_string, $date);
open VERSION, $_[0] or return ();
while (<VERSION>) {
next if (/^\s*$/);
if ( /^\s*(\d+(?:[\.]\d+)*)\s*\((.*)\)\s*$/ ) {
$version_string = $1;
$date = $2;
$_ = <VERSION>;
close VERSION;
if (/^\s*[Mm]aintainer\s*:\s*(.*)$/ ) {
return ($version_string,$date, $1);
} else {
return ($version_string,$date);
}
}
close VERSION;
return ();
}
close VERSION;
return ();
}
sub check_version($)
{
my $package_name = shift;
my ($new_version_string, $new_date, $package_maintainer,
$old_version_string, $old_date, $old_package_maintainer,
@nversion, @oversion);
($new_version_string, $new_date,$package_maintainer) = get_version('version');
if (!defined($new_version_string)) {
log_msg "Failed to parse version file";
return ();
}
if (!defined($package_maintainer)) {
log_msg "Version file does not contain a maintainer line!";
return ();
}
($old_version_string, $old_date, $old_package_maintainer) =
get_version("$packagedir/$package_name/version");
if (!defined($old_version_string)) {
return ($new_version_string, $old_version_string, $package_maintainer);
}
my ($new_nr,$old_nr);
@nversion = split /\./, $new_version_string;
@oversion = split /\./, $old_version_string;
my $version_ok = 0;
while (@nversion) {
$new_nr = shift @nversion;
$old_nr = shift @oversion;
$old_nr = 0 if !defined($old_nr);
if ($new_nr < $old_nr) {
last;
}
if ($new_nr > $old_nr) {
$version_ok = 1;
last;
}
}
if (defined($old_package_maintainer)) {
if ($old_package_maintainer =~ /\<(.*)\>/) {
push(@reply_list, $1);
}
}
if ( $package_maintainer ne $old_package_maintainer) {
log_msg "Alert: Maintainer changed from '$old_package_maintainer'" .
" to '$package_maintainer'";
}
if ($version_ok ) {
return ($new_version_string,$old_version_string, $package_maintainer);
} else {
log_msg
"Version $new_version_string is not bigger than $old_version_string";
return ();
}
}
my @source_files_to_check;
sub add_codefiles
{
if ( $_ =~ /\.(C|h)\s*$/ and -f $_) {
push @source_files_to_check, $File::Find::name;
}
}
sub check_codefiles($$)
{
my $package_name = $_[0];
my $package_maintainer = $_[1];
@source_files_to_check = ();
if (-d 'include') {
find(\&add_codefiles, "include");
}
if (-d 'src') {
find(\&add_codefiles, "src");
}
if (-d 'config') {
find(\&add_codefiles, "config");
}
my $source_file;
foreach $source_file (@source_files_to_check) {
system("$check_source_file_prog -u -d \"\" -p \"$package_name\" -m \"$package_maintainer\" $source_file >tmpmsg.$$");
open CHECK_MSGS, "<tmpmsg.$$";
while (<CHECK_MSGS>) {
chomp;
log_msg($_);
}
close CHECK_MSGS;
unlink "tmpmsg.$$";
}
}
sub append_maintainer_file_to_version_file()
{
open(MAINTAINER,'maintainer') or return;
$_ = <MAINTAINER>;
if (/^\s*$/) {
close(MAINTAINER);
return;
}
open(VERSION,'>>version');
if ($_ !~ /^maintainer\s*:/) {
print VERSION "maintainer: ";
}
print VERSION $_;
close(VERSION);
while (<MAINTAINER>) {
if ($_ =~ /\<(.*@.*)\>/) {
push(@reply_list, $1);
}
}
close(MAINTAINER);
}
sub filenames_of_package_ok($)
{
my $rc;
$rc = system("/projects/CGAL/admin_scripts/check_filenames_of_package \"$_[0]\" . >tmpmsg.$$");
open CHECK_MSGS, "<tmpmsg.$$";
while (<CHECK_MSGS>) {
chomp;
log_msg($_);
}
close CHECK_MSGS;
unlink "tmpmsg.$$";
$rc >>= 8;
if ($rc == 1) {
log_msg("ERROR: sorry, there was an internal error at Utrecht.")
}
if ($rc == 2) {
log_msg("ERROR: Your submissions contains files that are in use in another package")
}
return ($rc == 0);
}
sub check_for_ignored_files()
{
my %expected_names;
my @expected_names = ("include", "test", "examples", "demo", "src",
"version","doc_tex","stlport","winutils","auxiliary",
"developer_scripts","scripts","cgal_config.bat",
"install.txt","INSTALL.win32",
"submission_info","maintainer","description.txt",
"changes.txt","long_description.txt","doc_ps");
my @files_in_directory;
opendir THISDIR, "." or die "Cannot open current directory: $!";
@files_in_directory = grep !/^\.\.?$/, readdir THISDIR;
closedir THISDIR;
for (@expected_names) {
$expected_names{$_}++;
}
for (@files_in_directory) {
if (!$expected_names{$_}) {
log_msg "WARNING: toplevel file $_ will not go into releases!";
}
}
}
sub check_package($)
{
my ($version, $prev_version, $package_maintainer);
if ( ! -f 'version' ) {
log_msg "ERROR: File version is missing!";
return 0;
}
if (-f 'maintainer') {
append_maintainer_file_to_version_file();
}
if ( ! (($version, $prev_version, $package_maintainer) =
check_version($_[0])) ) {
log_msg "ERROR: version file does not pass the checks!";
return 0;
}
if ( ! -f 'description.txt' ) {
log_msg "WARNING: File description.txt is missing!";
} else {
my $word_count;
$word_count = `cat description.txt| wc -w`;
if ($word_count > 50) {
log_msg "WARNING: File description.txt contains more than 50 words!";
}
my $rc;
$rc = system("sed -e 's/</\\&lt;/g' -e 's/>/\\&gt;/g' < description.txt > descr");
if ($rc == 0) {
rename 'descr', 'description.txt';
} else {
unlink 'descr';
}
}
# if ( ! -f 'changes.txt' ) {
# log_msg "WARNING: File changes.txt is missing!";
# }
check_for_ignored_files();
if ( ! filenames_of_package_ok($_[0])) {
return 0;
}
check_codefiles("$_[0] ($version)", "$package_maintainer");
if (defined($prev_version)) {
log_msg "Version $version will replace $prev_version";
} else {
log_msg "Version $version will be installed";
}
return 1;
}
sub compress_package($)
{
my $package_name = shift;
compress_psfiles;
system 'zip', '-q', '-r', $package_name, glob("*");
return !$?;
}
sub remove_files()
{
my ($file);
opendir THISDIR, "." or die;
foreach $file (readdir THISDIR) {
if (-d $file) {
next if $file eq '.';
next if $file eq '..';
next if $file eq 'doc_ps';
system 'rm', '-rf', "$file";
} elsif (-f $file) {
next if $file =~ /\.zip$/;
next if $file eq 'version';
next if $file eq 'description.txt';
next if $file eq 'long_description.txt';
next if $file eq 'changes.txt';
next if $file eq 'submission_info';
unlink $file;
}
}
closedir THISDIR;
}
sub move_packagedir($)
{
my $package_name = shift;
# first remove the earlier version (if it exists)
if ( -d "$oldpackagedir/$package_name" ) {
# log_msg "removing directory $oldpackagedir/$package_name"
system('rm', '-rf', "$oldpackagedir/$package_name");
}
# move existing version to old packages
if ( -d "$packagedir/$package_name" ) {
# log_msg "moving directory $packagedir/$package_name to $oldpackagedir/$package_name"
print STDERR 'cp',' -r'," $packagedir/$package_name ", $oldpackagedir ,"\n";
(system('cp','-r',"$packagedir/$package_name", $oldpackagedir)==0) or die;
(system('rm','-r',"$packagedir/$package_name")==0) or die;
}
# log_msg "moving directory $tempdir to $packagedir/$package_name"
rename($tempdir, "$packagedir/$package_name") or die;
system 'chgrp', '-R', 'cgal', "$packagedir/$package_name";
system 'chmod', '-R', 'ug+w,a+r', "$packagedir/$package_name" ;
}
sub install_submission($$)
{
my ($file_name, $file_pathname, $package_name);
$file_name = shift;
$package_name = shift;
$file_pathname = "$download_dir/$file_name";
if (! unpack_package( $file_pathname) ) {
log_msg("Failed to unpack $file_pathname");
return 0;
}
if (!check_package($package_name)) {
return 0;
}
if (!compress_package($package_name)) {
log_msg "ERROR: Failed to compress $file_name";
return 0;
}
remove_files;
move_packagedir($package_name);
return 1;
}
sub do_submission($)
{
my ($url, $cur_dir,$file_name,$package_name);
$url = shift;
($file_name) = ($url =~ m|^.*/(.*?)\s*$|);
$package_name = make_package_name($file_name);
if ($package_name !~ /^[a-zA-Z_]\w*$/) {
log_header
"ERROR: Filename $file_name was turned into the illegal package name $package_name";
return 0;
}
if (!belongs_to_release($package_name) ) {
log_msg "WARNING: package $package_name will not go into releases";
log_msg "Send a separate mail to cgal_submit if you want that";
}
unlink glob("$download_dir/*") if (! $testing);
log_header "downloading $url";
# my $logfileno = fileno(LOGFILE);
# die "Log file not open" if ! defined($logfileno);
$cur_dir =cwd();
my $lockfile = "$download_dir/$package_name.lock";
if ( system("$LOCKCMD", "-r", '10', $lockfile) != 0) {
log_msg "ERROR: could not acquire lock on file $lockfile!";
return 0;
}
if (chdir "$download_dir") {
system("$WGET $url");
chdir $cur_dir;
}
if ( ! -f "$download_dir/$file_name" ) {
log_msg "ERROR: download failed!";
return 0;
}
chdir($tempdir);
open SUBMISSION_INFO, ">submission_info";
print SUBMISSION_INFO "URL: $url.\n";
close SUBMISSION_INFO;
if (install_submission("$file_name",$package_name) ) {
log_header "Package was successfully installed!";
} else {
log_header "ERROR: Installation of the package failed!";
unlink $lockfile;
return 0;
}
unlink $lockfile;
return 1;
}
#-----------------------------------
#
# main loop
#
#-----------------------------------
if ($#ARGV < 0) {
print "Too few arguments:",$#ARGV,"\n";
print_usage;
exit 1;
}
my $starting_directory = cwd();
if ($starting_directory =~ m'CGAL/Geert/maintenance') {
$testing=1;
}
init_variables();
$SIG{INT}='IGNORE';
$SIG{QUIT} = 'IGNORE';
$SIG{TERM} = 'IGNORE';
unlink $ACTUAL_LOGFILE;
system("echo >$ACTUAL_LOGFILE");
open LOGFILE, ">$ACTUAL_LOGFILE";
foreach $submission ( @ARGV) {
if (!create_package_dir) {
log_msg "Failed to create temporary directory $tempdir";
exit 1;
}
do_submission($submission);
chdir($starting_directory);
if (-d "$tempdir") {
system('rm', '-rf', "$tempdir");
}
}
close LOGFILE;
@reply_list = sort(@reply_list);
my $prev = "";
my @rlist;
foreach (@reply_list) {
if ($_ ne $prev) {
$prev = $_;
push(@rlist, $prev);
}
}
$ARGV[0] =~ s|.*/||;
system "cat $ACTUAL_LOGFILE | $MAIL_PROG \"CGAL submission $ARGV[0]\" @rlist";
unlink $ACTUAL_LOGFILE;
exit 0;