office-gobmx/solenv/bin/cwsadd.pl
Rüdiger Timm 668bce0367 INTEGRATION: CWS changefileheader (1.8.980); FILE MERGED
2008/03/28 15:55:24 rt 1.8.980.1: #i87441# Change license header to LPGL v3.
2008-04-10 15:44:22 +00:00

625 lines
19 KiB
Perl
Executable file

:
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# Copyright 2008 by Sun Microsystems, Inc.
#
# OpenOffice.org - a multi-platform office productivity suite
#
# $RCSfile: cwsadd.pl,v $
#
# $Revision: 1.9 $
#
# This file is part of OpenOffice.org.
#
# OpenOffice.org is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# only, as published by the Free Software Foundation.
#
# OpenOffice.org is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License version 3 for more details
# (a copy is included in the LICENSE file that accompanied this code).
#
# You should have received a copy of the GNU Lesser General Public License
# version 3 along with OpenOffice.org. If not, see
# <http://www.openoffice.org/license.html>
# for a copy of the LGPLv3 License.
#
#*************************************************************************
#
# cwsadd.pl - add modules to child workspaces
#
use strict;
use Getopt::Long;
use Cwd;
use IO::Handle;
use File::Copy;
#### module lookup
my @lib_dirs;
BEGIN {
if ( !defined($ENV{SOLARENV}) ) {
die "No environment found (environment variable SOLARENV is undefined)";
}
push(@lib_dirs, "$ENV{SOLARENV}/bin/modules");
push(@lib_dirs, "$ENV{COMMON_ENV_TOOLS}/modules") if defined($ENV{COMMON_ENV_TOOLS});
}
use lib (@lib_dirs);
use Cws;
use CwsConfig;
eval { require Logging; import Logging; };
# $log variable is only defined in SO environment...
my $log = undef;
$log = Logging->new() if (!$@);
eval { require CopyPrj; import CopyPrj; };
use CvsModule;
#### script id #####
( my $script_name = $0 ) =~ s/^.*\b(\w+)\.pl$/$1/;
my $script_rev;
my $id_str = ' $Revision: 1.9 $ ';
$id_str =~ /Revision:\s+(\S+)\s+\$/
? ($script_rev = $1) : ($script_rev = "-");
print "$script_name -- version: $script_rev\n";
#### global #####
my $force_checkout = '';
my $allow_modified = 0;
my $is_debug = 0;
my $opt_dir = ''; # dir option
my $vcsid = "unknown";
my $add_output_tree = 1;
my $keep_output_trees = 0;
my $force_output_tree_copy = 0;
my @found_platforms = ();
my @args_bak = @ARGV;
# store the @ARGS here for logging
# module names to be rejected
my @invalid_names =
qw(common common.pro cvs cws wntmsci unxsols unxsoli unxlngi unxlngp macosxp);
#### main #####
my $parameter_list = $log->array2string(";",@args_bak) if (defined $log);
my @modules = parse_options();
my ($dir, $cws) = get_and_verify_cws();
my @modules_to_add = check_modules($cws, @modules);
my $workspace_db;
if ( @modules_to_add ) {
if (defined $log) {
require EnvHelper; import EnvHelper;
$workspace_db = EnvHelper::get_workspace_db();
@modules_to_add = copy_modules($cws, $dir, $workspace_db, @modules_to_add);
} else {
@modules_to_add = update_modules($cws, $dir, @modules_to_add);
};
if ( @modules_to_add ) {
my @registered_modules = ();
my $success = 0;
my $module;
foreach (@modules_to_add) {
$module = $_;
$success = branch_module($cws, $dir, $module);
last unless $success;
$success = register_module($cws, $workspace_db, $module);
last unless $success;
push(@registered_modules, $module);
}
if ( @registered_modules ) {
my $modules_str = join(", ", @registered_modules);
my $child = $cws->child();
print "\n";
print_message("Summary:");
print_message("Sucessfully added and registered module(s) '$modules_str'.");
}
if ( !$success ) {
print_error("Adding and/or registering module '$module' failed!", 5);
}
}
}
$log->end_log_extended($script_name,$vcsid,"success") if (defined $log);
exit(0);
#### subroutines ####
#
# Subroutine updates module
#
sub update_modules {
my ($cws, $stand_dir, @modules_to_update) = @_;
my (@updated_modules, @rejected_modules);
my $master_tag = $cws->get_master_tag();
foreach my $module (@modules_to_add) {
my $cvs_module = CvsModule->new();
$cvs_module->module($module);
print "\tUpdating '$module' ...\n";
my $result = $cvs_module->update($stand_dir, $master_tag);
my ($updated, $merged, $conflicts) =
$cvs_module->handle_update_information($result);
if ( ( $merged && ! $allow_modified ) || $conflicts ) {
push(@rejected_modules, $module);
next;
};
push(@updated_modules, $module);
};
if (@rejected_modules) {
print_warning("Found conflicts and/or locally modified files in the following modules:");
print STDERR "$_\n" foreach (@rejected_modules);
print_warning("These modules will not be added to CWS. Clean up and try adding them again.");
};
return @updated_modules;
};
sub get_and_verify_cws
{
# get current child workspace from environment
my $childws = $ENV{CWS_WORK_STAMP};
my $masterws = $ENV{WORK_STAMP};
if ( !defined($childws) || !defined($masterws) ) {
print_error("Can't determine child workspace environment.\n"
. "Please initialize environment with setsolar ...", 1);
}
# get destination directory for modules to add
my $dir = $ENV{SRC_ROOT};
if ( !defined($dir) )
{
print_error("Need to get destination from SOURCE_ROOT - but it's not defined!",1);
}
my $cws = Cws->new();
$cws->child($childws);
$cws->master($masterws);
$log->start_log_extended($script_name,$parameter_list,$masterws,$childws) if (defined $log);
# check if we got a valid child workspace
my $id = $cws->eis_id();
print "Master: $masterws, Child: $childws, $id\n" if $is_debug;
if ( !$id ) {
print_error("Child workspace $childws for master workspace $masterws not found in EIS database.", 2);
}
return ($dir, $cws);
}
sub parse_options
{
# parse options and do some sanity checks
# returns freshly allocated Cws reference
# linking and unlinking requires UNIX
if ( $^O =~ "MSWin32" )
{
print_error("Sorry! not for non-cygwin Windows environment",2);
}
my $help;
my $success = GetOptions(
'-h' => \$help,
'-a' => \$force_checkout,
'-f' => \$allow_modified,
'-o' => \$force_output_tree_copy,
'-k' => \$keep_output_trees
);
if ( $force_checkout && $force_output_tree_copy ) {
print_error ("Can't copy output trees with checkout forced!", 2);
}
if ( $keep_output_trees && $force_output_tree_copy ) {
print_error ("Can't copy output trees but keep existing...", 2);
}
if ( $help || !$success || $#ARGV < 0 ) {
usage();
exit(1);
}
return @ARGV;
}
sub check_modules
{
# check if modules are registered with child workspace
# returns list of modules which can be added
my $cws = shift;
my @modules = @_;
my @registered_modules = $cws->modules();
# create hash for easier searching
my %registered_modules_hash = ();
for (@registered_modules) {
$registered_modules_hash{$_}++;
}
my %invalid_names_hash = ();
for (@invalid_names) {
$invalid_names_hash{$_}++;
}
my $config = CwsConfig->get_config();
my $cvs_module = CvsModule->new();
$cvs_module->cvs_method($config->get_cvs_server_method());
$cvs_module->vcsid($config->get_cvs_server_id());
$cvs_module->cvs_server($config->get_cvs_server());
$cvs_module->cvs_repository($config->get_cvs_server_repository());
my @new_modules = ();
my %cvs_aliases = $cvs_module->get_aliases_hash();
foreach (@modules) {
if ( $_ =~ /[\s\t\|\$\(\)\[\]\{\\}]/ || exists $invalid_names_hash{lc($_)} ) {
print_error("'$_' is an invalid module name.", 3);
}
if ( exists $registered_modules_hash{$_} ) {
print_warning("Module '$_' already registered, skipping.");
next;
};
if (!defined($log) && !defined $cvs_aliases{$_}) {
print_error("There is no such module alias '$_'.", 3);
};
push(@new_modules, $_);
}
return @new_modules;
}
sub copyprj_module_sourcetree
{
my $module_name = shift;
my $src_dest = shift;
print "copyprj $module_name\n";
# hash, that should contain all the
# data needed by CopyPrj module
my %ENVHASH = ();
my %platforms_to_copy = ();
$ENVHASH{'platforms_hash'} = \%platforms_to_copy;
if ( $add_output_tree && !$force_checkout ) {
$platforms_to_copy{$_}++ foreach (@found_platforms);
};
my %projects_to_copy = ();
$ENVHASH{'projects_hash'} = \%projects_to_copy;
$ENVHASH{'no_otree'} = 1; # does this match with %platforms_to_copy???
$ENVHASH{'no_path'} = 1;
$ENVHASH{'only_otree'} = 0;
$ENVHASH{'only_update'} = 1;
$ENVHASH{'last_minor'} = 0;
$ENVHASH{'spec_src'} = 0;
$ENVHASH{'dest'} = "$src_dest";
$ENVHASH{'prj_to_copy'} = '';
$ENVHASH{'i_server'} = '';
$ENVHASH{'current_dir'} = cwd();
$ENVHASH{'remote'} = '';
$ENVHASH{'force_checkout'} = 1 if ($force_checkout);
$projects_to_copy{$module_name}++;
CopyPrj::copy_projects(\%ENVHASH);
};
sub copy_modules
{
# copy modules from master workspace into child workspace
my $cws = shift;
my $dir = shift;
my $workspace_db = shift;
my @modules = @_;
my $masterws = $cws->master();
my $childws = $cws->child();
my $milestone = $cws->milestone();
# ause: Deine Spielwiese
my $result;
my @success_modules = ();
my $workspace = $workspace_db->get_key($masterws);
if ( !$workspace ) {
print_error("Master workspace '$masterws' not found in workspace database.", 3);
}
my $wslocation = $workspace_db->get_value($masterws."/Drives/o:/UnixVolume");
if ( !defined($wslocation) ) {
print_error("Location of master workspace '$masterws' not found in workspace database.", 3);
}
print "$wslocation\n" if $is_debug;
my $source_root = $ENV{SOURCE_ROOT};
if ( !defined( $source_root )) {
print_error("SOURCE_ROOT not defined! Please setup a valid environment for CWS \"$childws\"", 1);
}
my $cws_solver = "$source_root/$masterws";
my $start_dir = getcwd();
$result = chdir($dir);
if ( !$result ) {
print_error("Cannot change to $dir!", 1);
}
# assume that every valid platform on child "solver" has to be copied
$result = opendir( SOLVER, "$cws_solver");
if ( !$result ){ print_error ("Root dir of child workspace not accessible: $!", 1) };
my @found_dirs = readdir( SOLVER );
closedir( SOLVER );
# hack to get the milestone :-(((((
if ( ! defined($milestone))
{
$milestone = $ENV{UPDMINOR};
}
if ( $#found_dirs )
{
foreach my $dir_candidate ( @found_dirs )
{
if ( -d "$cws_solver/$dir_candidate/inc.".$milestone )
{
push @found_platforms, $dir_candidate;
}
}
}
# preparing pseudo environment for copyprj
$ENV{SRC_ROOT}="$wslocation/$masterws/src.$ENV{UPDMINOR}";
print "$ENV{SRC_ROOT}\n" if ( $is_debug );
print "working dir: ".getcwd()."\n" if ( $is_debug );
foreach my $one_module (@modules) {
# do some snity checks for this module
if ( -e "$one_module.lnk" && -e "$one_module" )
{
print_error("Duplicate representation of module $one_module ($one_module.lnk $one_module)", 0);
print_error("Please clean up!", 0);
print_error("Will NOT add module $one_module to child workspace!", 0);
# fail for this module
next;
}
if ( -e "$one_module.backup.lnk" || -e "$one_module.backup" )
{
print_error("Backup of module $one_module already exists.", 0);
print_error("Please clean up!", 0);
print_error("Will NOT add module $one_module to child workspace!", 0);
# fail for this module
next;
}
$result = 0;
$result = rename($one_module, "$one_module.backup.lnk") if ( -l $one_module );
if ( ! -l $one_module && -e $one_module ) {
$result ||= rename($one_module, "$one_module.backup");
# if it is no link, assume incompatible build
# -> don't copy output tree unless required
$add_output_tree = 0 if ( !$force_output_tree_copy );
}
$result ||= rename("$one_module.lnk", "$one_module.backup.lnk") if ( -e "$one_module.lnk" );
$result = 0 if ( -e $one_module || -e "$one_module.lnk" );
if ( ! $result )
{
print_error("Couldn't backup existing module $one_module before copying", 0);
print_error("Will NOT add module $one_module to child workspace!", 0);
# fail for this module
next;
}
# now copy sources
$result = copyprj_module_sourcetree( $one_module, "." );
if ( $result )
{
if ( -d $one_module )
{
$result = rename("$one_module", "$one_module.failed");
$result = system("rm -rf $one_module.failed");
}
print_error("Couldn't copy module $one_module, restoring previous.", 0);
if ( -e "$one_module.backup" )
{
$result = rename("$one_module.backup", $one_module);
}
else
{
$result = rename("$one_module.backup.lnk", "$one_module.lnk");
}
print_error("Restoring link for $one_module failed! Cleanup is in your hands now", 1) if ( ! $result );
# fail for this module
next;
}
# remove backuped link
unlink("$one_module.backup.lnk") if -l "$one_module.backup.lnk";
# or backuped directory...
if ( -d "$one_module.backup" )
{
my $keep_this_module = 0;
if ( $^O =~ "MSWin32" || $^O =~ "cygwin" )
{
print_error("Sorry! not for windows, nobody should ever get here!",2);
}
if ( $keep_output_trees ) {
# copy output trees from backup to added module
foreach my $i ( @found_platforms ) {
if ( ! move "$one_module.backup/$i", "$one_module/$i" ) {
print_warning("Could not keep \"$one_module/$i\" autommatically.");
print_warning("Keeping backuped module \"$one_module.back\" to allow manual copying...");
$keep_this_module = 1;
}
}
}
if ( ! $keep_this_module ) {
$result = system("rm -rf $one_module.backup");
print_warning("Couldn't remove backuped module \"$one_module.backup\".") if $result;
}
}
# insert module in list of successfull copied modules
push(@success_modules, $one_module);
}
chdir($start_dir);
# return my @empty = (); # ause - disable all further steps
return @success_modules;
}
sub branch_module
{
# tag modules with cws branch cws root tag
my $cws = shift;
my $dir = shift;
my $module = shift;
my ($cws_master_tag, $cws_branch_tag, $cws_root_tag) = $cws->get_tags();
# Sanity check
print "operating on $dir/$_\n" if $is_debug;
if ( -S "$dir/$module" || ! -d "$dir/$module" ) {
print_error("Can't find physical copy of module '$module'", 4);
}
STDOUT->autoflush(1);
print_message("Tagging module '$module'.");
my $cvs_module = CvsModule->new();
$cvs_module->module($module);
$cvs_module->verbose(1);
print_message("Tag with branch tag '$cws_branch_tag'.");
my ($branched_files, $branch_errors) = $cvs_module->tag($dir, $cws_branch_tag, '-b');
if ( $branched_files < 1 ) {
print_error("Tagging module '$module' failed.", 0);
return 0;
}
if ( $branch_errors > 0 ) {
print_error(cleanup_tags_msg($module), 0);
return 0;
}
print_message("Tagged $branched_files files in module '$module' with branch tag.");
print_message("Tag with tag '$cws_root_tag'.");
my ($tagged_files, $anchor_errors) = $cvs_module->tag($dir, $cws_root_tag);
if ( $tagged_files < 1 || $anchor_errors > 0
|| $branched_files != $tagged_files )
{
print_error(cleanup_tags_msg($module), 0);
return 0;
}
print_message("Tagged $tagged_files files in module '$module'.");
print_message("Updating module '$module' to branch '$cws_branch_tag'.");
my @dirs = $cvs_module->update($dir, $cws_branch_tag);
if ( $#dirs < 0 ) {
print_error("Updating module '$module' to branch '$cws_branch_tag' failed.\n", 0);
return 0;
}
STDOUT->autoflush(0);
return 1;
}
sub cleanup_tags_msg
{
my $module = shift;
my ($cws_master_tag, $cws_branch_tag, $cws_root_tag) = $cws->get_tags();
my $msg = "Tagging module '$module' failed partly. Can't continue.\n";
$msg .= "Please remember to manually remove the tags '$cws_branch_tag' and '$cws_root_tag'\n";
$msg .= "from module '$module' before retrying the operation!";
return $msg;
}
# Register module with EIS.
sub register_module
{
my $cws = shift;
my $workspace_db = shift;
my $module = shift;
my $public = 1;
# find out if module has public flag
my $master = $cws->master();
if (defined $log) {
my $key = "$master/Drives/o:/Projects/$module/SCS";
my $scs = $workspace_db->get_value($key);
if ( !defined($scs) ) {
print_error("Can't find module '$module' in workspace db", 0);
return 0;
}
# FIXME - this really shouldn't be hard coded
if ( $scs !~ /tunnel/ ) {
$public = 0;
}
}
my $success = $cws->add_module($module, $public);
if ( !$success ) {
print_error("Can't register module '$module' with EIS!", 0);
return 0;
}
print_message("Succesfully registered module '$module'.");
return 1;
}
sub print_message
{
my $message = shift;
print "$script_name: ";
print "$message\n";
return;
}
sub print_warning
{
my $message = shift;
print STDERR "$script_name: ";
print STDERR "WARNING: $message\n";
return;
}
sub print_error
{
my $message = shift;
my $error_code = shift;
print STDERR "$script_name: ";
print STDERR "ERROR: $message\n";
if ( $error_code ) {
print STDERR "\nFAILURE: $script_name aborted.\n";
$log->end_log_extended($script_name,$vcsid,$message) if (defined $log);
exit($error_code);
}
return;
}
sub usage
{
print STDERR "Usage: cwsadd [-h] [-a] [-f ] [-o|-k] <module> ... \n";
print STDERR "Add one or more modules to child workspace.\n";
print STDERR "Options:\n";
print STDERR " -a use cvs checkout instead of copying\n";
print STDERR " -f incorporate modified files into cws\n";
print STDERR " -o force copying output trees (in copy mode only)\n";
print STDERR " -k keep existing output trees\n";
print STDERR " -h print this help\n";
}