Windows-Server-2003/tools/postbuildscripts/capturesourcefilelist.cmd

322 lines
7.3 KiB
Batchfile

@echo off
REM ------------------------------------------------------------------
REM
REM <<template_script.cmd>>
REM <<purpose of this script>>
REM
REM Copyright (c) Microsoft Corporation. All rights reserved.
REM
REM ------------------------------------------------------------------
perl -x "%~f0" %*
goto :EOF
#!perl
use strict;
use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
use lib $ENV{RAZZLETOOLPATH};
use PbuildEnv;
use ParseArgs;
use Logmsg;
my $const_SD_project_title =
"project\\s+group\\s+server:port\\s+depotname\\s+projectroot";
my ($ProcessSuccess) = ("TRUE");
my ($SrcFile, $SrcDir, $Group, $Project, $ServerPort, $DepotName, $ProjectRoot, $Validate) = ();
my ($ProjectValue, $GroupValue, $ServerPortValue, $DeportValue) = ();
my ($SrcName, $SdxRoot, $RazPath, $SrcTimeStampFile, $ProjectsNT) = ();
my (%Projects)=();
sub Usage { print<<USAGE; exit(1) }
$0 - Capture Source File List from Source Depot
=============================================================
Syntax:
$0 [-f <SourceFileList>] [-d <SoureFileDir>]
[-g <Group>] [-p <Project>] [-s <ServerPort>]
[-n <DepotName>] [-r <ProjectRoot>] [-v]
Parameter:
SourceFileList : The filename for stored sdx have result
SourceFileDir : The root for stored .offset file
Group : Source depot group
Project : Source depot project
ServerPort : Source depot server port
DepotName : Source depot name
ProjectRoot : Source depot project root
Validate : Validate SourceFileList
Default:
SourceFileList : \%_NTPOSTBLD\%\\build_logs\\SourceFileLists.txt
SourceFileDir : \%_NTPOSTBLD\%\\build_logs\\SourceFileLists
Projects.net : \%RazzleToolPath\%\\projects.nt
Example:
1. Create NTDEV build's SourceFileList
$0 -g ntdev
USAGE
parseargs(
'f:' => \$SrcFile,
'd:' => \$SrcDir,
'g:' => \$Group,
'p:' => \$Project,
's:' => \$ServerPort,
'n:' => \$DepotName,
'r:' => \$ProjectRoot,
'v' => \$Validate,
'?' => \&Usage
);
#
# Add if-clause so pbuild.dat entry can be BEGIN instead of OFFICIAL and we
# still don't waste much time unless a non-official machine has set PDB_SRC_STREAM
# which also controls PdbSrcStream.cmd.
#
if ( defined($ENV{OFFICIAL_BUILD_MACHINE}) || defined($ENV{PDB_SRC_STREAM})) {
&Main;
}
sub Main {
&InitGlobalVariables;
&CreateSDXResult;
&ParseProjectsNT("$RazPath\\projects.nt", \%Projects);
&IndexSrc;
&StoreFileTimeDateStamp;
if ((defined $Validate) && (&ValidateOffsetFile($SrcFile, $SrcDir) eq "FAIL")) {
errmsg("$SrcFile created failed");
}
}
sub InitGlobalVariables {
$SdxRoot = $ENV{ "SDXROOT" };
$RazPath = $ENV{ "RazzleToolPath" };
$SrcName = "SourceFileLists";
$SrcDir = $ENV{ "_NTPostBld" } . "\\build_logs\\$SrcName" if (!defined $SrcDir);
$SrcFile = $ENV{ "_NTPostBld" } . "\\build_logs\\$SrcName" . ".txt" if (!defined $SrcFile);
$SrcTimeStampFile = $SrcDir . "\\" . &FileName($SrcFile) . ".timestamp";
$ProjectsNT = "$RazPath\\projects.nt";
}
sub CreateSDXResult {
chdir "$SdxRoot";
# Create sdx have list
&SuccessExecute("$RazPath\\sdx.cmd have ...>$SrcFile");
}
sub IndexSrc {
my ($curbytes, $curlen, $SECTION) = (0, 0);
my (%ProjectSlots);
my ( $project );
# Index the result
open(SRC, "$SrcFile");
binmode(SRC);
for($curbytes=0; <SRC> ; $curbytes+=$curlen) {
$curlen=length($_);
next if (!/\S/);
if (/\-{16}\s(\S+)/) {
my $section = $1;
&StoreProjectIndex($SECTION, \%ProjectSlots);
%ProjectSlots=();
$SECTION = $section;
&StoreInfo($SECTION);
next;
}
if (/^(\S+)\s\-\s(\S+)\\([^\\])([^\\]*)\s*$/) {
push @{$ProjectSlots{$3}}, "$2\\$3$4,$1,$curbytes";
}
}
&StoreProjectIndex;
close(SRC);
}
sub ParseProjectsNT {
my ($ProjectsNTFileName, $HashPtr) = @_;
my $NecessaryPattern = &ComposeNecessaryPattern($Project, $Group, "\\S*" . $ServerPort . "\\S*", $DepotName);
my $fh_in;
my $START = 0;
unless ( $fh_in = new IO::File $ProjectsNTFileName, "r" ) {
errmsg( "Failed to open $ProjectsNTFileName for read" );
return;
}
while(<$fh_in>) {
next if (!/\S/);
$START = 1 if (/$const_SD_project_title/i);
next if (/^\s*\#/);
if (($START eq 1) && (/$NecessaryPattern/i)) {
next if ((defined $ProjectRoot) && ($' !~ /$ProjectRoot/i));
($ProjectValue, $GroupValue, $ServerPortValue, $DeportValue) = ($1, $2, $3, $4);
# print "$ProjectValue, $GroupValue, $ServerPortValue, $DeportValue\n";
$HashPtr->{uc$ProjectValue} = [$GroupValue, $ServerPortValue, $DeportValue, $ProjectRoot];
}
}
undef $fh_in;
}
sub StoreInfo {
my ($project) = shift;
my $fh_info;
my $filename;
&SuccessExecute("md $SrcDir\\$project") if (!-d "$SrcDir\\$project");
$filename = "$SrcDir\\$project\\$project\.txt";
unless ( $fh_info = new IO::File $filename, "w" ) {
errmsg( "Failed to open file $filename for write" );
return;
}
print $fh_info "$Projects{$project}[0] $Projects{$project}[1]\n";
undef $fh_info;
}
sub StoreProjectIndex {
my ($project, $PSptr) = @_;
my $FirstChar;
for $FirstChar (sort keys %$PSptr) {
my $fh_out;
my $filename;
$filename = "$SrcDir\\$project\\Files_" . $FirstChar . ".offset";
unless ( $fh_out = new IO::File $filename, "w" ) {
errmsg( "Failed to open file $filename for write" );
return;
}
binmode($fh_out);
map({&OutputAddress($fh_out, (split(/\,/, $_))[2])} sort @{$PSptr->{$FirstChar}});
undef $fh_out;
}
}
sub StoreFileTimeDateStamp {
my $result = &ReadFileTimeStamp($SrcFile);
my $srctime;
unless ( $srctime = new IO::File $SrcTimeStampFile, "w" ) {
errmsg( "Failed to open file $SrcTimeStampFile for write" );
return;
}
print $srctime "$result\n";
undef $srctime;
}
sub ReadFileTimeStamp {
my ($HH, $MM, $DD, $hh, $mm) = (localtime((lstat($_))[9]))[5,4,3,2,1];
return sprintf("%04d/%02d/%02d:%02d:%02d", $HH + 1900, $MM + 1, $DD, $hh, $mm);
}
sub ValidateOffsetFile {
my ($SRC_filename, $SRC_Root) = @_;
my ($filespec, $vsrctime, $vsrc, $vsrc_ref);
my ($address, $offset, $result, $lastresult);
unless ( $vsrctime = new IO::File $SrcTimeStampFile, "r" ) {
errmsg( "Failed to open file $SrcTimeStampFile for read" );
return;
}
$lastresult = <$vsrctime>;
undef $vsrctime;
chomp $lastresult;
$result = &ReadFileTimeStamp($SRC_filename);
return "FAIL" if ($result ne $lastresult);
unless ( $vsrc = new IO::File $SRC_filename, "r" ) {
errmsg( "Failed to open file $SRC_filename for read" );
return;
}
binmode($vsrc);
for $filespec (`dir /s /b $SRC_Root\\*.offset`) {
chomp $filespec;
unless ( $vsrc_ref = new IO::File $filespec, "r" ) {
errmsg( "Failed to open file $filespec for read" );
return;
}
binmode($vsrc_ref);
while(read($vsrc_ref, $offset, 4)) {
($address) = unpack("L",$offset);
seek($vsrc, $address, 0);
read($vsrc, $result, 7);
if ($result ne "//depot") {
close($vsrc_ref);
close($vsrc);
print "Error - $filespec($address) $result\n";
return "FAIL";
}
}
close($vsrc_ref);
}
undef $vsrc;
return "SUCCESS";
}
sub SuccessExecute {
my $cmd = shift;
if ($ProcessSuccess eq "TRUE") {
my $r = system($cmd);
$r >>= 8;
if ($r > 0) {
errmsg($cmd);
$ProcessSuccess="FALSE";
}
}
}
sub OutputAddress {
my ($fh, $address) = @_;
my ($len);
for ($len=0;$len<4;$len++) {
print $fh chr($address & 0xFF);
$address>>=8;
}
}
sub FileName {
my ($filespec) = shift;
chomp $filespec;
$filespec=~/\\([^\\]+)$/;
return $1;
}
sub ComposeNecessaryPattern {
return join("\\s+", map({(defined $_)?"($_)":"(\\S+)"} @_));
}