Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

312 lines
7.2 KiB

  1. @echo off
  2. REM ------------------------------------------------------------------
  3. REM
  4. REM ChangesToBuild.cmd
  5. REM Outputs SD changes since last build completed
  6. REM
  7. REM Copyright (c) Microsoft Corporation. All rights reserved.
  8. REM
  9. REM ------------------------------------------------------------------
  10. if defined _CPCMAGIC goto CPCBegin
  11. perl -x "%~f0" %*
  12. goto :EOF
  13. #!perl
  14. #line 15
  15. use strict;
  16. use File::Copy;
  17. use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
  18. use lib $ENV{RAZZLETOOLPATH};
  19. use PbuildEnv;
  20. use ParseArgs;
  21. use Logmsg;
  22. sub Usage { print<<USAGE; exit(1) }
  23. Outputs SD changes since last build completed. This can be
  24. run repeatedly on a single build without losing change information.
  25. Results are stored in $ENV{_NTTREE}\\build_logs\\sdchanges.txt
  26. USAGE
  27. my $output_file;
  28. parseargs('?' => \&Usage);
  29. my $gLastError;
  30. my $change_list = "$ENV{_NTTREE}\\build_logs\\sdchanges.txt";
  31. my $baseline = "$ENV{SDXROOT}\\bldchanges.base";
  32. my $baseline_new = "$ENV{SDXROOT}\\bldchanges.cur";
  33. # Get latest change info
  34. my %head_changes = GetHeadChanges();
  35. if ( $gLastError ) {errmsg( $gLastError )}
  36. if ( !%head_changes ) {exit 1}
  37. # Check for existence of baseline changes
  38. my %base_changes;
  39. if ( -e $baseline_new )
  40. {
  41. my %cur_changes = GetBaseline($baseline_new);
  42. if ( %cur_changes )
  43. {
  44. # Now determine if we are checking from a new build
  45. if ( $head_changes{build_num} != $cur_changes{build_num} ||
  46. $head_changes{build_date} != $cur_changes{build_date} )
  47. {
  48. logmsg( "Updating comparative baseline ..." );
  49. if ( -e $baseline &&
  50. !unlink $baseline )
  51. {
  52. errmsg( "Unable to remove old baseline ($!)" );
  53. }
  54. if ( !copy($baseline_new, $baseline) )
  55. {
  56. errmsg( "Unable to copy new baseline ($!)" );
  57. }
  58. %base_changes = %cur_changes;
  59. }
  60. elsif ( -e $baseline )
  61. {
  62. %base_changes = GetBaseline($baseline);
  63. errmsg( $gLastError ) if ( $gLastError );
  64. if ( !%base_changes ) {exit 1}
  65. }
  66. }
  67. else
  68. {
  69. errmsg( "Problem retrieving baseline change numbers:" );
  70. errmsg( $gLastError );
  71. exit 1;
  72. }
  73. }
  74. if ( !WriteBaseline( \%head_changes, $baseline_new ) )
  75. {
  76. errmsg( "Problem writing current change base:" );
  77. errmsg( $gLastError );
  78. }
  79. if ( %base_changes )
  80. {
  81. my %change_lists = GetChangesFromLast( \%base_changes );
  82. if ( $gLastError ) { errmsg $gLastError }
  83. if ( !%change_lists ) { exit 1 };
  84. # Record our data
  85. if ( !WriteChanges( \%change_lists, $change_list ) )
  86. {
  87. errmsg( "Problem writing changes:" );
  88. errmsg( $gLastError );
  89. exit 1;
  90. }
  91. logmsg( "Results found in $change_list" );
  92. exit 0;
  93. }
  94. else
  95. {
  96. logmsg( "No baseline -- creating for next use..." );
  97. exit 0;
  98. }
  99. sub GetHeadChanges
  100. {
  101. my %head_changes;
  102. $gLastError = '';
  103. my ($depot, $change_for_depot);
  104. # store build info into hash to start
  105. my ($build_num, $build_date) = GetCurrentBuild();
  106. if ( !$build_num ) { return }
  107. $head_changes{build_num} = $build_num;
  108. $head_changes{build_date} = $build_date;
  109. foreach ( qx(cmd /c sdx changes -m1 ...#have) )
  110. {
  111. chomp;
  112. if ( /^-+\s(\w+)$/ )
  113. {
  114. if ( !$change_for_depot )
  115. {
  116. # This isn't really an error all the time as there
  117. # could have been no changes since last build in
  118. # this depot
  119. # $gLastError .= "No change found for depot $depot\n";
  120. }
  121. $depot = lc$1;
  122. }
  123. elsif ( /^Change\s(\d+)\s/ )
  124. {
  125. if ( !defined $depot )
  126. {
  127. $gLastError .= "Unrecognized depot for change: $_\n"
  128. }
  129. else
  130. {
  131. $change_for_depot = 1;
  132. $head_changes{$depot} = $1;
  133. }
  134. }
  135. }
  136. if ( $! )
  137. {
  138. $gLastError .= "Problem calling SDX ($!)\n"
  139. }
  140. elsif ( $? )
  141. {
  142. $gLastError .= "SDX returned an error (". ($?>>8). "\n";
  143. }
  144. return %head_changes;
  145. }
  146. sub GetBaseline
  147. {
  148. my $base_store = shift;
  149. my %base_changes;
  150. $gLastError = '';
  151. if ( !open STORE, $base_store )
  152. {
  153. $gLastError .= "Unable to open $base_store ($!)\n";
  154. return;
  155. }
  156. foreach ( <STORE> )
  157. {
  158. chomp;
  159. if ( /^(.*):(\d+)$/ )
  160. {
  161. $base_changes{lc$1} = $2;
  162. }
  163. else
  164. {
  165. $gLastError .= "Unrecognized line: $_\n";
  166. }
  167. }
  168. close STORE;
  169. return %base_changes;
  170. }
  171. sub WriteBaseline
  172. {
  173. my $base_changes = shift;
  174. my $base_store = shift;
  175. $gLastError = '';
  176. if ( !open STORE, ">$base_store" )
  177. {
  178. $gLastError .= "Unable to write to $base_store ($!)\n";
  179. return;
  180. }
  181. print STORE "build_num:$base_changes->{build_num}\n";
  182. print STORE "build_date:$base_changes->{build_date}\n";
  183. foreach ( sort keys %$base_changes )
  184. {
  185. if ( 'build_num' eq $_ ||
  186. 'build_date' eq $_ ) {next}
  187. print STORE "$_:$base_changes->{$_}\n";
  188. }
  189. close STORE;
  190. return 1;
  191. }
  192. sub GetChangesFromLast
  193. {
  194. my $last_changes = shift;
  195. $gLastError = '';
  196. my %post_changes;
  197. foreach (keys %$last_changes)
  198. {
  199. if ( 'build_num' eq $_ ||
  200. 'build_date' eq $_ ) { next }
  201. if ( !chdir ('root' ne $_?"$ENV{SDXROOT}\\$_":$ENV{SDXROOT}) )
  202. {
  203. $gLastError .= "Unable to locate $ENV{SDXROOT}\\$_ ($!)\n";
  204. next;
  205. }
  206. my $change_number = $last_changes->{$_};
  207. my @changes = qx(sd changes ...\@$change_number,#have);
  208. if ( $! )
  209. {
  210. $gLastError .= "Problem calling SD in $_ ($!)\n"
  211. }
  212. elsif ( $? )
  213. {
  214. $gLastError .= "SD returned error (". ($?>>8). ") in $_\n";
  215. }
  216. # We don't want to include the base change number
  217. if ( $changes[$#changes] =~ /^Change\s$change_number\s/ ) { pop @changes; }
  218. $post_changes{$_} = join '', @changes;
  219. }
  220. return %post_changes;
  221. }
  222. sub
  223. WriteChanges
  224. {
  225. my $changes = shift;
  226. my $changes_store = shift;
  227. $gLastError = '';
  228. if ( !open STORE, ">$changes_store" )
  229. {
  230. $gLastError .= "Unable to write to $changes_store ($!)\n";
  231. return;
  232. }
  233. foreach ( sort keys %$changes )
  234. {
  235. print STORE "---------------- $_\n";
  236. print STORE "$changes->{$_}\n"
  237. }
  238. return 1;
  239. }
  240. sub GetCurrentBuild
  241. {
  242. $gLastError = '';
  243. if ( !open BLDNUM, "$ENV{SDXROOT}\\__bldnum__" )
  244. {
  245. $gLastError .= "Unable to open $ENV{SDXROOT}\\__bldnum__\n";
  246. return;
  247. }
  248. my $bldnum = <BLDNUM>;
  249. close BLDNUM;
  250. if ( !open BLDDATE, "$ENV{SDXROOT}\\__blddate__" )
  251. {
  252. $gLastError .= "Unable to open $ENV{SDXROOT}\\__blddate__\n";
  253. return;
  254. }
  255. my $blddate = <BLDDATE>;
  256. close BLDDATE;
  257. chomp $blddate; chomp $bldnum;
  258. if ( !($bldnum =~ s/BUILDNUMBER=(\d+).*/$1/) )
  259. {
  260. $gLastError .= "Error parsing build number: $bldnum\n";
  261. return;
  262. }
  263. if ( !($blddate =~ s/BUILDDATE=(\d+)-(\d+).*/$1$2/) )
  264. {
  265. $gLastError .= "Error parsing build date: $blddate\n";
  266. return;
  267. }
  268. return ($bldnum, $blddate);
  269. }