Windows-Server-2003/tools/locemvs.pl

457 lines
9.8 KiB
Perl

# USE section
use GetParams;
use strict;
no strict 'vars';
# GLOBAL Variables
$ScriptName=$0;
$Lang="";
$SDXROOT=$ENV{SDXROOT};
$CompName="";
$CompType="";
$ProjName="";
$Enlist=0;
$Map=0;
$Sync=0;
$Timestamp="";
$Branch="locpart";
$Codebase="NT";
%SDMAP=();
# GLOBAL Constants
@COMPTYPES=("res", "bin", "tools");
@BRANCHES=("main", "locpart");
$LOGGING=0;
$ERROR=1;
%MSG=($LOGGING => "", $ERROR => "error: ");
# MAIN {
# Parse the command line parameters.
&ParseCmdLine(@ARGV);
# Verify the command line parameters and the environment.
&VerifyParams();
# Load data from the "SD.MAP" file.
&LoadSDMap();
# Set project name.
$ProjName = sprintf ("%s_%s", $Lang, $CompType);
# Enlist project.
if ($Enlist) {
&EnlistProject($ProjName);
}
# Set client view for component.
if ( $Map || $Enlist ) {
&MapClientView( $ProjName, $CompName );
}
# Sync project.
if ($Sync) {
&SyncProject( $ProjName, $CompName, $Timestamp );
}
# }
sub EnlistProject {
my ($projname) = @_;
&DisplayMsg( $LOGMSG, "Enlisting project \"$projname\"...");
if ( exists $SDMAP{lc($projname)} ) {
&DisplayMsg( $LOGMSG, "Already enlisted in project \"$projname\".");
return;
}
system( "sdx enlist $projname /q");
# As sdx does not set the error level in case of errors, reload the SD.MAP
# mapping file to verify that the project got actually enlisted.
&LoadSDMap();
if ( ! exists $SDMAP{lc($projname)} ){
&FatalError( "Enlist project \"$projname\" command failed." );
} else {
&DisplayMsg( $LOGMSG, "Project \"$projname\" enlisted successfully." );
}
return;
} # EnlistProject
sub MapClientView {
my ( $projname, $compname ) = @_;
my $workdir="$SDXROOT\\$SDMAP{lc($projname)}";
# Any ExecuteCmd failure is a fatal error.
&DisplayMsg( $LOGMSG, "Mapping client view for project \"$projname\" and component \"$compname\"..." );
&DisplayMsg($LOGMSG, "cd /d $workdir");
chdir( $workdir ) ||
&FatalError( "Unable to change directory to \"$workdir\" to update project's \"$projname\" client view." );
&ExecuteCmd( "sd client -o \> sd.client" );
if ( &UpdateClient( $projname, $compname ) ) {
&ExecuteCmd( "sd client -i \< sd.client" );
&DisplayMsg( $LOGMSG, "Component \"$compname\" successfully mapped in project's \"$projname\" client view.");
}
&ExecuteCmd( "del sd.client");
} # MapClientView
sub UpdateClient {
my ($projname, $compname) = @_;
my $workdir="$SDXROOT\\$SDMAP{lc($projname)}";
my @sdclient=();
# Flag set to 1 if at least one entry is found in the client view for the given project.
my $MAPPED_PROJECT_FLAG=0;
# Flag set to 1 if the component is already mapped in the client view.
my $MAPPED_COMPONENT_FLAG=0;
# Flag set to 1 if the client view file is modified.
# The client view is modified in one of the following situations:
# 1. The component is already mapped, but for a different branch from the given one.
# 2. A new entry, specific to the given component, has been added.
# 3. The '$projname/...' entry has been replaced by the '$projname/*' entry.
my $MODIFIED_FLAG=0;
open( FILE, "sd.client" ) || &FatalError( "Unable to open file $workdir\\sd.client." );
@sdclient=<FILE>;
close(FILE);
for ( $i=0; $i < @sdclient; $i++ ) {
if ( $sdclient[$i] =~ /\/$projname/i ) {
$MAPPED_PROJECT_FLAG=1;
if ( $sdclient[$i] =~ /\/$projname\/$compname\//i ) {
$MAPPED_COMPONENT_FLAG=1;
$sdclient[$i] =~ /\/\/depot\/(\w+)\//i;
if ( lc($1) ne lc($Branch) ) {
$sdclient[$i] =~s/\/$1\//\/$Branch\//;
$MODIFIED_FLAG=1;
}
}
if ( $sdclient[$i] =~ /\/$projname\/\.\.\./i ) {
$sdclient[$i] =~ s/\/\.\.\./\/*/g;
$MODIFIED_FLAG=1;
}
}
}
$MAPPED_PROJECT_FLAG ||
&FatalError( "No entry found for \"$projname\". Enlist project \"$projname\" first." );
if ( !$MAPPED_COMPONENT_FLAG ) {
my $last=@sdclient;
$sdclient[$last]=$SDMAP{lc($projname)};
$sdclient[$last] =~ s/\\/\//g;
$sdclient[$last] = sprintf (" \/\/depot\/\%s\/%s\/%s\/... \/\/%s\/%s\/%s\/...\r\n",
$Branch,
$projname,
$compname,
$SDMAP{client},
$sdclient[$last],
$compname);
$MODIFIED_FLAG=1;
}
if ( $MODIFIED_FLAG ) {
&DisplayMsg( $LOGMSG, "Saving project's \"$projname\" updated client view...");
open(FILE, ">sd.client") ||
&FatalError( "Unable to open \"$workdir\\sd.client\" for writing." );
for ($i=0; $i < @sdclient; $i++ ) {
printf FILE $sdclient[$i];
}
close (FILE);
} else {
&DisplayMsg( $LOGMSG, "Project's \"$projname\" client view is up-to-date.");
}
return $MODIFIED_FLAG;
} # UpdateClient
sub SyncProject {
my ( $projname, $compname, $timestamp ) = @_;
my $workdir = "$SDXROOT\\$SDMAP{lc($projname)}";
my $cmdsync = "";
&DisplayMsg($LOGMSG, "cd /d $workdir");
chdir( $workdir ) ||
&FatalError( "Unable to change directory to $workdir in order to sync up the tree." );
$cmdsync = "sd sync *";
if ( $timstamp ) {
$cmdsync .= @$timestamp;
}
&ExecuteCmd( $cmdsync );
$cmdsync = "sd sync $compname\\...";
if ( $timstamp ) {
$cmdsync .= @$timestamp;
}
# If it fails, ExecuteCmd exits the script automatically.
&ExecuteCmd( $cmdsync );
# Workaround: sd sync does not set the errorlevel in case of error.
( -e $compname ) || &FatalError( "Command \"$cmdsync\" failed." );
&DisplayMsg( $LOGMSG, "Component \"$compname\" of project \"$projname\" synchronized successfully." );
} # SyncProject
sub LoadSDMap {
my @mapfile=();
my $i=0;
my $sdmap="$SDXROOT\\sd.map";
foreach (keys %SDMAP) {
delete $SDMAP{$_};
}
( -e $sdmap ) || &FatalError( "Unable to find file $sdmap" );
open( FILE, $sdmap ) || &FatalError( "Unable to open file $sdmap." );
@mapfile=<FILE>;
close(FILE);
for ($i=0; $i < @mapfile; $i++) {
foreach ($mapfile[$i]) {
SWITCH: {
# commented lines
if ( /\s*#/ ) { last SWITCH;}
# valid entries
if (/\s*(\S+)\s*=\s*(\S+)/ ) {
$SDMAP{lc($1)}=$2;
last SWITCH;
}
# default
last SWITCH;
} # SWITCH
} # foreach
} # for
# verify codebase
( exists $SDMAP{codebase} ) ||
&FatalError( "CODEBASE is not listed in the SD mapping file $sdmap." );
( lc($SDMAP{codebase}) eq lc($Codebase) ) ||
&FatalError( "Codebase '$Codebase' does not match the SDXROOT '$SDMAP{codebase}' codebase." );
# verify branch
( exists $SDMAP{branch} ) ||
&FatalError( "BRANCH is not listed in the SD mapping file $sdmap." );
# verify client
( exists $SDMAP{client} ) ||
&FatalError( "CLIENT is not listed in the SD mapping file $sdmap." );
} # LoadSDMap
sub ParseCmdLine {
my @arguments = @_;
if ( @_ == 0 ) {
&Usage();
}
my @syntax=(
-n => 'l:d:y:',
-o => 'emst:b:',
-p => "Lang CompName CompType Enlist Map Sync Timestamp Branch"
);
&GetParameters(\@syntax, \@arguments);
} # ParseCmdLine
sub ExecuteCmd {
my ($command) = @_;
DisplayMsg( $LOGMSG, $command );
if ( system( "$command" ) ) {
&FatalError( "Command \"$command\" failed." );
}
}
sub VerifyParams {
my $i=0;
my $strerr="";
# Must run this script from a razzle
if ( !$ENV{RazzleToolPath} || !$ENV{SDXROOT} ) {
&DisplayMsg($ERROR, "Please run this script from a razzle.\n");
&Usage();
}
# Verify component types
for ( $i=0; $i < @COMPTYPES; $i++ ) {
if ( lc($CompType) eq lc($COMPTYPES[$i]) ) {
last;
}
}
if ( $i == @COMPTYPES ) {
for ( $i=0; $i < @COMPTYPES; $i++ ) {
$strerr .= "$COMPTYPES[$i] ";
}
&DisplayMsg($ERROR, "Component type must be one of { $strerr}");
&Usage();
}
# If component type is "tools", then language must be "usa" and viceverse.
if ( lc($CompType) eq "tools" || lc($Lang) eq "usa" ) {
( lc($Lang) eq "usa" && lc($CompType) eq "tools" ) ||
&FatalError( "Only language \"usa\" can be used with \"tools\" as the component type.");
}
# If neither of e, m, and s is specified, set them all.
if ( !$Enlist && !$Map && !$Sync ) {
$Enlist=1;
$Map=1;
$Sync=1;
}
} # VerifyParams
sub GetParameters {
my ($syntax, $arguments)=@_;
my $getparams=GetParams->new;
&{$getparams->{-Process}}(@$syntax,@$arguments);
if ( $HELP ) {
&Usage();
}
} # GetParameters
sub DisplayMsg {
print "$ScriptName : $MSG{@_[0]}@_[1]\n";
} # DisplayMsg
sub FatalError {
my ( $strerr ) = @_;
&DisplayMsg( $ERRMSG, $strerr );
exit 1;
} # FatalError
sub Usage {
print <<USAGE;
perl $0 - Enlist, Map, and Sync localization specific projects.
This script is used by the Whistler localization
partners to set up their Source Depot enlistments.
Usage:
perl $0 -l:<language>
-d:<compname>
-y:res|bin
[-e] [-m] [-s [-t:<timestamp>]]
[-b:<branch>]
<language> Language.
<compname> Component name.
res|bin Component type: resource or binary type.
Also, use 'tools' as component type and 'usa'
as language to enlist in the 'tools' project.
e Enlist project.
m Map client view.
s Sync project.
If none of e, m, and s is specified, they are all executed.
<timestamp> Timestamp to use with sync. Use the format:
yyyy/mm/dd or yyyy/mm/dd:hh:mm:ss.
<branch> Branch name. Default value is "locpart".
Examples:
perl $0 -l:ger -y:res -d:windows
perl $0 -l:jpn -y:bin -d:windows
perl $0 -l:usa -y:tools -d:windows
USAGE
exit(1);
} # Usage