cgal/Scripts/developer_scripts/create_internal_release

736 lines
22 KiB
Perl
Executable File

#!/usr/bin/env perl
#this script generates the internal release
use Cwd;
use File::Find;
use Getopt::Std;
sub usage() {
print STDERR<<"EOF";
usage:
$0 (-h|-r)
[-n version number]
[-d releasedir] [-a allpackagesdir]
[-l lockfile]
Exactly one of the options -h or -r must be present.
-h show this message and quit
-r release version to be created
-n version number (CGAL_VERSION_NR)
-d releasedir, default releasedir is the current dir
-a allpackagesdir, default is releasedir/trunk
-l lockfile, default is releasedir/release_creation.lock
The version number is stored in include/CGAL/version.h.
The RELEASEDIR is the place where the new release will be created.
The ALLPACKAGESDIR is the directory that contains the checked out packages
from the SVN. Could be trunk or some branch.
The LOCKFILE is some file used by lockfile command as a mutex.
Example of how to use the script:
>svn co svn+ssh://scm.gforge.inria.fr/svn/cgal/trunk
>./create_internal_release -r CGAL-3.3-I-1
or
>./create_internal_release -r CGAL-3.3-I-7 -d \$HOME -a \$HOME/CGALSVN/trunk -l release_creation.lock
EOF
}
my $TEMPFILE="TEMPFILE.$$";
#----------------------------------------------------#
# Initialisation #
#----------------------------------------------------#
my (
$VERSION,
$VERSION_NR,
$LOCKFILE,
$ALLPACKAGESDIR,
$RELEASEDIR,
$MAINDIR,
$SCRIPTSDIR,
$LOCKCMD,
$packages_file
);
sub termination_signal_handler {
unlink $LOCKFILE;
exit 1;
}
sub lock()
{
if (system("$LOCKCMD", "-r", '10', "$LOCKFILE") != 0) {
print STDERR <<"TOTHIER";
The script could not proceed because
it could not acquire the needed lock on file $LOCKFILE.
TOTHIER
exit 1;
}
$SIG{INT} = \&termination_signal_handler;
$SIG{TERM} = \&termination_signal_handler;
}
sub unlock()
{
unlink $LOCKFILE;
$SIG{INT} = 'DEFAULT';
$SIG{TERM} = 'DEFAULT';
}
sub create_packages_dir(){
print "Creating $VERSION/Packages directory ...\n";
chdir $RELEASEDIR or die;
if (! -f $packages_file){
print STDERR "$packages_file file does not exist\n";
unlock;
die "\n";
}
open PACKAGES_TO_INCLUDE, "$packages_file" or die;
while (<PACKAGES_TO_INCLUDE>){
chomp;
s/\s*//g;
next if /^$/;
$is_permitted_package{$_}=1;
}
close PACKAGES_TO_INCLUDE;
opendir ALLPACKAGESDIR, $ALLPACKAGESDIR or die;
while (defined($package_name = readdir(ALLPACKAGESDIR))) {
next unless $is_permitted_package{$package_name};
chdir "$RELEASEDIR/$VERSION" or die;
mkdir('Packages', 0775);
chdir 'Packages';
mkdir($package_name, 0775);
if (-f "$ALLPACKAGESDIR/$package_name/maintainer"){
system('cp', "$ALLPACKAGESDIR/$package_name/maintainer", "$RELEASEDIR/$VERSION/Packages/$package_name");
}
if (-f "$ALLPACKAGESDIR/$package_name/version"){
system('cp', "$ALLPACKAGESDIR/$package_name/version", "$RELEASEDIR/$VERSION/Packages/$package_name");
}
if (-f "$ALLPACKAGESDIR/$package_name/changes.txt"){
system('cp', "$ALLPACKAGESDIR/$package_name/changes.txt", "$RELEASEDIR/$VERSION/Packages/$package_name");
}
if (-f "$ALLPACKAGESDIR/$package_name/description.txt"){
system('cp', "$ALLPACKAGESDIR/$package_name/description.txt", "$RELEASEDIR/$VERSION/Packages/$package_name");
}
}
closedir ALLPACKAGESDIR;
}
sub create_global_makefile{
printf("Creating the global makefile in the test dir ...\n");
chdir "$RELEASEDIR/$VERSION" or die;
if ( -e "test/Makefile"){
system("rm -f Makefile");
}
opendir testdir, "test";
@dirs = readdir testdir;
closedir testdir;
shift @dirs; shift @dirs;
chdir "test" or die;
open(TEMPFILE, ">tempfile") or die;
print TEMPFILE "testsuite: ";
foreach $dir (@dirs){
if ( -d $dir){
print TEMPFILE "test_$dir ";
}
}
print TEMPFILE "\n";
foreach $dir (@dirs){
if ( -d $dir){
print TEMPFILE "test_$dir:\n\t+ ./run_testsuite $dir\n";
}
}
system('mv', "tempfile", 'Makefile');
};
sub install_packages() {
my ($filename, $direc, %is_permited_package, $package_name, $tmp_package_name);
print "Installing packages ...\n";
chdir $RELEASEDIR or die;
if (! -f $packages_file){
print STDERR "$packages_file file does not exist\n";
unlock;
die "\n";
}
open PACKAGES_TO_INCLUDE, "$packages_file" or die;
while (<PACKAGES_TO_INCLUDE>){
chomp;
s/\s*//g;
next if /^$/;
$is_permitted_package{$_}=1;
}
close PACKAGES_TO_INCLUDE;
opendir ALLPACKAGESDIR, $ALLPACKAGESDIR or die;
while (defined($package_name = readdir(ALLPACKAGESDIR))) {
next unless $is_permitted_package{$package_name};
$dont_submit="$ALLPACKAGESDIR/$package_name/dont_submit";
$exclude_command="--exclude-from=$dont_submit";
chdir "$ALLPACKAGESDIR" or die;
if(-f $dont_submit){
system('tar', '-cf', "$RELEASEDIR/temppack.tar", '--exclude=.svn', "$exclude_command", '--exclude=TODO', '--exclude=dont_submit', '--exclude=maintainer', '--exclude=description.txt', '--exclude=changes.txt', "$package_name");
} else {
system('tar', '-cf', "$RELEASEDIR/temppack.tar", '--exclude=.svn', '--exclude=dont_submit', '--exclude=maintainer', '--exclude=description.txt', '--exclude=changes.txt', '--exclude=TODO', "$package_name");
}
system('mv', "$RELEASEDIR/temppack.tar", "$RELEASEDIR/$VERSION/");
chdir "$RELEASEDIR/$VERSION" or die;
system('tar', '-xf', "temppack.tar");
$tmp_package_name = "temp_${package_name}";
system("mv", "$package_name", "$tmp_package_name");
opendir packagename, "$tmp_package_name";
@fichiers = readdir packagename;
closedir packagename;
shift @fichiers; shift @fichiers;
foreach $fichier (@fichiers){
system('cp', '-r', "$tmp_package_name/$fichier", "$RELEASEDIR/$VERSION");
}
system('rm', '-rf', "$tmp_package_name");
}
closedir ALLPACKAGESDIR;
unlink 'temppack.tar', 'description.txt', 'long_description.txt', 'changes.txt', 'submission_info', 'long_description.txt.old';
}
#-----------------------------------------------------------------------#
# set the version information in the include/CGAL/version.h #
#-----------------------------------------------------------------------#
sub create_version_file()
{
chdir "$RELEASEDIR/$VERSION/include/CGAL" or die;
open(TEMPFILE, ">tempfile") or die;
#if VERSION starts with CGAL-, we remove "CGAL-" from version
#the $newver variable will store the right version
if ($result = $VERSION =~ /CGAL-(.*)/){
$newver = $1;
} else {
$newver = $VERSION;
}
# TODO : add `svnversion` Revision.
print TEMPFILE << 'EOF';
// Copyright (c) 2006 Utrecht University (The Netherlands),
// ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
// (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with CGAL.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Author(s) : -
// This file is automatically created by create_internal_release.
// Do not edit manually.
#ifndef CGAL_VERSION_H
#define CGAL_VERSION_H
EOF
print TEMPFILE "#define CGAL_VERSION $newver\n";
print TEMPFILE "#define CGAL_VERSION_NR $VERSION_NR\n";
print TEMPFILE "#define CGAL_SVN_REVISION 0\n\n#endif\n";
close TEMPFILE || die "Error closing temporary file: $!\n";
system('mv', "tempfile", 'version.h');
chdir '../..' or die;
}
#-----------------------------------------------------------------------#
# set the version information in the doc_tex/version.tex #
#-----------------------------------------------------------------------#
sub create_version_tex_file()
{
chdir "$RELEASEDIR/$VERSION/doc_tex" or die;
open(TEMPFILE, ">tempfile") or die;
#if VERSION starts with CGAL-, we remove "CGAL-" from version
#the $newver variable will store the right version
if ($result = $VERSION =~ /CGAL-(.*)/){
$newver = $1;
} else {
$newver = $VERSION;
}
print TEMPFILE << 'EOF';
%% This file is automatically created by create_internal_release.
%% Do not edit manually.
EOF
print TEMPFILE "\\gdef\\cgalversion{$newver}\n";
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my @months = ( "January", "February", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December" );
print TEMPFILE "\\gdef\\cgalversiondate{$mday $months[$mon] ", 1900 + $year, "}\n";
close TEMPFILE || die "Error closing temporary file: $!\n";
system('mv', "tempfile", 'version.tex');
chdir '../..' or die;
}
#---------------------------------------------------------------#
# CreateExampleTestDirs
#---------------------------------------------------------------#
sub CreateExampleTestDirs()
{
my $DIR;
print "Creating $VERSION/test/example directories ...\n";
chdir "$RELEASEDIR/$VERSION" or die;
chdir 'examples' or return;
foreach $DIR (glob("*")) {
if ( -d $DIR ) {
system('cp', '-r', "$DIR", "../test/${DIR}_Examples");
}
}
chdir '..';
}
#---------------------------------------------------------------#
# CreateDemoTestDirs
#---------------------------------------------------------------#
sub CreateDemoTestDirs()
{
my $DIR;
print "Creating $VERSION/test/demo directories ...\n";
chdir "$RELEASEDIR/$VERSION" or die;
chdir 'demo' or return;
foreach $DIR (glob("*")) {
if ( -d $DIR ) {
system('cp', '-r', "$DIR", "../test/${DIR}_Demo");
open(CGAL_TEST,">../test/${DIR}_Demo/cgal_test");
print CGAL_TEST <<'EOF';
#! /bin/sh
# This is a script for the CGAL test suite. Such a script must obey
# the following rules:
#
# - the name of the script is cgal_test
# - for every target two one line messages are written to the file 'error.txt'
# the first one indicates if the compilation was successful
# the second one indicates if the execution was successful
# if one of the two was not successful, the line should start with 'ERROR:'
# - running the script should not require any user interaction
# - the script should clean up object files and executables
ERRORFILE=error.txt
#---------------------------------------------------------------------#
# compile
#---------------------------------------------------------------------#
compile()
{
if eval 'make CGAL_MAKEFILE=$CGAL_MAKEFILE \
TESTSUITE_CXXFLAGS="$TESTSUITE_CXXFLAGS" \
TESTSUITE_LDFLAGS="$TESTSUITE_LDFLAGS" all' >compiler_output 2>&1 ; then
echo " succesful compilation " >> $ERRORFILE
cat compiler_output
else
echo " ERROR: compilation " >> $ERRORFILE
eval "2>&1 make CGAL_MAKEFILE=$CGAL_MAKEFILE clean > /dev/null "
eval 'make -k CGAL_MAKEFILE=$CGAL_MAKEFILE \
TESTSUITE_CXXFLAGS="$TESTSUITE_CXXFLAGS" \
TESTSUITE_LDFLAGS="$TESTSUITE_LDFLAGS" all'
fi
rm compiler_output
eval "2>&1 make CGAL_MAKEFILE=$CGAL_MAKEFILE clean > /dev/null "
}
#---------------------------------------------------------------------#
# remove the previous error file
#---------------------------------------------------------------------#
rm -f $ERRORFILE
touch $ERRORFILE
#---------------------------------------------------------------------#
# compile and run the tests
#---------------------------------------------------------------------#
compile
EOF
close(CGAL_TEST);
chmod 0755, "../test/${DIR}_Demo/cgal_test";
}
}
chdir '..';
}
sub CreateConfigurationTestdir(){
print "Creating $VERSION/test/Configuration directory ...\n";
chdir "$RELEASEDIR/$VERSION" or die;
system('cp', '-r', 'config/testfiles', 'test/Configuration');
}
#---------------------------------------------------------------#
# create cgal_test script in tests
#---------------------------------------------------------------#
sub create_test(){
open(CGAL_TEST,">cgal_test");
print CGAL_TEST <<'EOF';
#! /bin/sh
# This is a script for the CGAL test suite. Such a script must obey
# the following rules:
#
# - the name of the script is cgal_test
# - for every target two one line messages are written to the file 'error.txt'
# the first one indicates if the compilation was successful
# the second one indicates if the execution was successful
# if one of the two was not successful, the line should start with 'ERROR:'
# - running the script should not require any user interaction
# - the script should clean up object files and executables
ERRORFILE=error.txt
#---------------------------------------------------------------------#
# compile_and_run <target>
#---------------------------------------------------------------------#
compile_and_run()
{
echo "Compiling $1 ... "
SUCCES="y"
if eval 'make CGAL_MAKEFILE=$CGAL_MAKEFILE \
TESTSUITE_CXXFLAGS="$TESTSUITE_CXXFLAGS" \
TESTSUITE_LDFLAGS="$TESTSUITE_LDFLAGS" $1' ; then
echo " succesful compilation of $1" >> $ERRORFILE
else
echo " ERROR: compilation of $1" >> $ERRORFILE
SUCCES=""
fi
if [ -n "${SUCCES}" ] ; then
OUTPUTFILE=ProgramOutput.$1.$PLATFORM
rm -f $OUTPUTFILE
COMMAND="./$1"
if [ -f $1.cmd ] ; then
COMMAND="$COMMAND `cat $1.cmd`"
fi
if [ -f $1.cin ] ; then
COMMAND="cat $1.cin | $COMMAND"
fi
echo "Executing $1 ... "
echo
ulimit -t 3600 2> /dev/null
if eval $COMMAND > $OUTPUTFILE 2>&1 ; then
echo " succesful execution of $1" >> $ERRORFILE
else
echo " ERROR: execution of $1" >> $ERRORFILE
fi
else
echo " ERROR: not executed $1" >> $ERRORFILE
fi
eval "make CGAL_MAKEFILE=$CGAL_MAKEFILE clean > /dev/null 2>&1 "
}
#---------------------------------------------------------------------#
# remove the previous error file
#---------------------------------------------------------------------#
rm -f $ERRORFILE
touch $ERRORFILE
#---------------------------------------------------------------------#
# compile and run the tests
#---------------------------------------------------------------------#
if [ $# -ne 0 ] ; then
for file in $* ; do
compile_and_run $file
done
else
EOF
close(CGAL_TEST);
open(CGAL_TEST,">>cgal_test");
my $cfile;
foreach $cfile (glob("*.C")) {
substr($cfile, -2, 2) = "";
print CGAL_TEST " compile_and_run $cfile\n";
}
print CGAL_TEST "fi\n";
close(CGAL_TEST);
chmod 0755, 'cgal_test';
}
#---------------------------------------------------------------#
# make_testscripts and generate makefiles in test and examples
#---------------------------------------------------------------#
sub make_testscripts()
{
my ($DIR, $BASEDIR);
chdir "$RELEASEDIR/$VERSION" or die;
$BASEDIR = cwd();
print "Creating and checking makefiles ...\n";
chdir 'test';
foreach $DIR (glob("*")) {
if ( -d $DIR ) {
chdir $DIR;
if ( -f 'Makefile') {
rename 'Makefile', 'makefile';
}
if ( -f 'makefile' ) {
open MAKEFILE, "makefile";
open NEW_MAKEFILE, ">makefile.new";
while (<MAKEFILE>) {
s/\.o\b/\$(OBJ_EXT)/g;
s/-g\b/\$(DEBUG_OPT)/g;
print NEW_MAKEFILE $_;
}
close NEW_MAKEFILE;
close MAKEFILE;
rename("makefile.new","makefile");
} else {
my $options = '-t';
if ( -f 'cgal_create_makefile_options') {
if (open(OPTIONS, "<cgal_create_makefile_options")) {
$_ = <OPTIONS>;
chomp;
if (/^[\w\s-]+$/) { $options = $_;
} else {
print STDERR "Rejected cgal_create_makefile_options in $DIR\n";
}
close OPTIONS;
}
}
system("$SCRIPTSDIR/cgal_create_makefile", $options) == 0 or die "Execution of $SCRIPTSDIR/cgal_create_makefile failed";
}
if ( ! -f 'cgal_test' ) {
create_test();
}
chdir '..';
}
}
chdir $BASEDIR;
chdir 'examples';
# Windows specific stuff
print "Creating VC++ projects in examples\n";
system("../developer_scripts/examples/C2vcproj", glob("*"));
print "Creating makefiles in examples\n";
foreach $DIR (glob("*")) {
if ( -d $DIR ) {
chdir $DIR;
if ( -f 'Makefile') {
rename 'Makefile', 'makefile';
}
if ( -f 'makefile' ) {
open MAKEFILE, "makefile";
open NEW_MAKEFILE, ">makefile.new";
while (<MAKEFILE>) {
s/\.o\b/\$(OBJ_EXT)/g;
s/-g\b/\$(DEBUG_OPT)/g;
print NEW_MAKEFILE $_;
}
close NEW_MAKEFILE;
close MAKEFILE;
rename("makefile.new","makefile");
} else {
my $options = '-d';
if ( -f 'cgal_create_makefile_options') {
if (open(OPTIONS, "<cgal_create_makefile_options")) {
$_ = <OPTIONS>;
chomp;
if (/^[\w\s-]+$/) { $options = $_;
} else {
print STDERR "Rejected cgal_create_makefile_options in $DIR\n";
}
close OPTIONS;
}
}
system("$SCRIPTSDIR/cgal_create_makefile", $options) == 0 or die "Execution of $SCRIPTSDIR/cgal_create_makefile failed";
}
chdir '..';
}
}
chdir $BASEDIR;
}
#----------------------------------------------------------------#
# check_and_update_file #
#----------------------------------------------------------------#
sub check_and_update_file($$)
{
my ($filename, $filename_with_dir) = @_;
my $header_type = 0;
my $lines_exceeding_length = 0;
my $has_line_directives = 0;
unlink $TEMPFILE;
open SOURCE_FILE, "<$filename" || die "Error opening $filename_with_dir: $!\n";
open TEMPFILE, ">$TEMPFILE" || die;
while ( <SOURCE_FILE> ) {
$header_type = 1
if m|^Copyright \(c\) \d{4](,\s?\d{4})* The CGAL Consortium|;
$header_type = 2
if m|^// Copyright \(c\) \d{4}(,\s?\d{4})* The CGAL Consortium|;
$lines_exceeding_length +=1 if length $_ > 80;
$has_line_directives = 1 if m|^\s*#\s*line\s|;
print TEMPFILE $_;
}
close SOURCE_FILE || die "Error closing $filename_with_dir: $!";
close TEMPFILE || die "Error closing temporary file: $!\n";
rename($TEMPFILE, $filename )
|| system('mv', "$TEMPFILE", "$filename")
|| warn "Could not update file $filename_with_dir\n";
if ($header_type == 0) {
print FILE_CHECKS "$filename_with_dir has unrecognised header.\n";
} elsif ($header_type == 1) {
print FILE_CHECKS "$filename_with_dir has old style header.\n";
}
if ($lines_exceeding_length) {
print FILE_CHECKS "$filename_with_dir has $lines_exceeding_length",
" lines over 80 characters.\n";
}
if ($has_line_directives) {
print FILE_CHECKS "$filename_with_dir has line directives.\n";
}
}
#----------------------------------------------------------------#
# set_file_headers #
#----------------------------------------------------------------#
sub set_file_headers()
{
print "Setting file headers...\n";
chdir "$RELEASEDIR/$VERSION";
open(FILE_CHECKS,">$PARENT_DIR/code_check_$VERSION");
find(\&file_header_setting, 'include', 'src', 'examples', 'config/testfiles');
close FILE_CHECKS;
chdir $MAIN_DIR;
}
sub file_header_setting
{
my ($filename,$dev,$ino,$mode,$nlink,$uid,$gid,$filetype);
$filename = $_;
if ( ! /\.[h|C]$/ ||
! (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($filename)) ||
! -f _ ) {
return;
}
check_and_update_file($filename, $File::Find::name);
}
#----------------------------------------------------#
# Main entry point #
#----------------------------------------------------#
sub main(){
$RELEASEDIR=cwd();
$ALLPACKAGESDIR="$RELEASEDIR/trunk";
$LOCKFILE="$RELEASEDIR/release_creation.lock";
$LOCKCMD='lockfile';
getopts('hr:a:d:l:p:s:n:');
if ($::opt_h ) {
usage();
die "\n";
}
if ($::opt_d){
$RELEASEDIR = $::opt_d;
$ALLPACKAGESDIR = "$RELEASEDIR/trunk";
$LOCKFILE="$RELEASEDIR/release_creation.lock";
}
if ($::opt_r){
$VERSION = $::opt_r;
if ($::opt_n){
$VERSION_NR = $::opt_n;
} else {
$VERSION_NR = $VERSION;
}
} else {
usage();
die "\n";
}
if ($::opt_a){
$ALLPACKAGESDIR = $::opt_a;
}
if ($::opt_l){
$LOCKFILE = $::opt_l;
}
$SCRIPTSDIR="$ALLPACKAGESDIR/Scripts/scripts";
$packages_file="$ALLPACKAGESDIR/Maintenance/release_building/include_in_release";
print "Initializing variables ...\n";
print " Release dir: $RELEASEDIR\n";
print " All packages dir: $ALLPACKAGESDIR\n";
print " Scripts dir: $SCRIPTSDIR\n";
print " Lockfile: $LOCKFILE\n";
print " Packages file : $packages_file\n";
umask(002);
chdir $RELEASEDIR or die;
if (! -d $VERSION){
print "Creating release directory ${VERSION} ...\n";
mkdir($VERSION, 0775);
} else {
print "$VERSION already exists in $RELEASEDIR\n";
print "Please remove it first\n";
exit 1;
}
lock;
create_packages_dir();
install_packages();
CreateConfigurationTestdir();
CreateDemoTestDirs();
CreateExampleTestDirs();
create_version_file();
create_version_tex_file();
make_testscripts();
set_file_headers();
create_global_makefile();
unlock;
}
main();