source: branches/profile/SOURCE_TOOLS/build_info.pl

Last change on this file was 11819, checked in by westram, 10 years ago
  • append 32bit suffix to version info
  • Property svn:executable set to *
File size: 14.6 KB
Line 
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6# create/update build info into
7#     ../TEMPLATES/arb_build.h
8# and
9#     ../TEMPLATES/svn_revision.h
10
11# --------------------------------------------------------------------------------
12
13my $dumpFiles = 1;
14
15my $RC_BRANCH     = 'rc';
16my $STABLE_BRANCH = 'stable';
17
18# --------------------------------------------------------------------------------
19
20my $ARBHOME = $ENV{ARBHOME};
21if (not defined $ARBHOME) { die "ARBHOME undefined"; }
22if ((not -d $ARBHOME) or (not -f $ARBHOME.'/arb_LICENSE.txt')) {
23  die "ARBHOME ('$ARBHOME') must point to ARB build directory";
24}
25
26my $TEMPLATES    = $ARBHOME.'/TEMPLATES';       if (not -d $TEMPLATES)    { die "no such directory '$TEMPLATES'"; }
27my $SOURCE_TOOLS = $ARBHOME.'/SOURCE_TOOLS';    if (not -d $SOURCE_TOOLS) { die "no such directory '$SOURCE_TOOLS'"; }
28my $mv_if_diff   = $SOURCE_TOOLS.'/mv_if_diff'; if (not -x $mv_if_diff)   { die "no such script '$mv_if_diff'"; }
29
30# upgrade version?
31my $inc_major = $SOURCE_TOOLS.'/inc_major.stamp';
32my $inc_minor = $SOURCE_TOOLS.'/inc_minor.stamp';
33my $inc_candi = $SOURCE_TOOLS.'/inc_candi.stamp';
34my $inc_patch = $SOURCE_TOOLS.'/inc_patch.stamp';
35
36# --------------------------------------------------------------------------------
37
38sub execAndGetFirstNonemptyLine($) {
39  my ($infocmd) = @_;
40  # returns first nonempty line from infocmd-output
41  # or undef (if output is empty)
42  # or dies (if command fails)
43
44  my $content = undef;
45  print "[executing '$infocmd']\n";
46  open(INFO,$infocmd.'|') || die "failed to fork '$infocmd' (Reason: $!)";
47 LINE: foreach (<INFO>) {
48    if ($_ ne '') {
49      chomp;
50      $content = $_;
51      last LINE;
52    }
53  }
54  close(INFO) || die "failed to execute '$infocmd' (Reason: $!)";;
55  if (defined $content) { print "output='$content'\n"; }
56  else { print "no output :-(\n"; }
57  return $content;
58}
59
60sub getHost() {
61  my $arbbuildhost = $ENV{ARBBUILDHOST};
62  my @hosts = ();
63  if (defined $arbbuildhost) { push @hosts, $arbbuildhost; }
64  else {
65    my $host = $ENV{HOST};
66    my $hostname = $ENV{HOSTNAME};
67
68    if (defined $host) { push @hosts, $host; }
69    if (defined $hostname) { push @hosts, $hostname; }
70  }
71  if (scalar(@hosts)==0) {
72    my $hostnameout = undef;
73    eval { $hostnameout = execAndGetFirstNonemptyLine('hostname'); };
74    if ($@) { print "Warning: buildhost is unknown ($@)\n"; }
75    if (not defined $hostnameout) { $hostnameout = 'unknown'; }
76
77    my $domainname = undef;
78    eval { $domainname = execAndGetFirstNonemptyLine('domainname'); };
79    if ($@) { print "Warning: domain is unknown ($@)\n"; $domainname = undef; }
80    if ((not defined $domainname) or ($domainname eq '(none)')) { $domainname = 'somewhere'; }
81
82    push @hosts, $hostnameout.'.'.$domainname;
83  }
84
85  @hosts = sort { length($b) <=> length($a); } @hosts; # sort longest first
86  return $hosts[0];
87}
88
89sub getUser() {
90  my $user = $ENV{ARBBUILDUSER};
91  if (not defined $user) { $user = $ENV{USER}; }
92  if (not defined $user) {
93    eval { $user = execAndGetFirstNonemptyLine('whoami'); };
94    if ($@) { print "Warning: user is unknown ($@)\n"; $user = undef; }
95  }
96  if (not defined $user) { $user = 'unknownUser'; }
97  return $user;
98}
99
100sub guessSvnBranchInsideJenkins() {
101  my $root = undef;
102  my $url = $ENV{SVN_URL}; # is set inside jenkins
103
104  if (defined $url) {
105    if ($url eq '') { $url = undef; }
106    else {
107      my $suffix = undef;
108      if ($url =~ /^(http:\/\/svn\.mikro\.biologie\.tu-muenchen\.de\/svn)\//o) {
109        $suffix = $';
110        $root = $1;
111      }
112      elsif ($url =~ /^(svn\+ssh:\/\/.*svn\.arb-home\.de\/svn\/ARB)\//o) {
113        $suffix = $';
114        $root = $1;
115      }
116      if (not defined $suffix) { die "Unexpected value in SVN_URL ('$url')"; }
117      die "root unset (url='$url')" if not defined $root;
118    }
119  }
120  return ($root,$url);
121}
122
123sub getRevision() {
124  my $jrevision = $ENV{SVN_REVISION}; # is set inside jenkins
125  if (defined $jrevision and $jrevision eq '') { $jrevision = undef; }
126
127  my $revision = undef;
128  eval {
129    $revision = execAndGetFirstNonemptyLine("svnversion -c -n '$ARBHOME'");
130    if (defined $revision and $revision =~ /^2:/) { $revision = $'; }
131  };
132  if ($@) {
133    if (defined $jrevision) {
134      print "Accepting svn failure (apparently running inside jenkins)\n";
135      $revision = $jrevision;
136    }
137    else { die $@."\n"; }
138  }
139
140  if (not defined $revision) { die "Failed to detect revision number"; }
141  if (defined $jrevision) {
142    if ($jrevision ne $revision) {
143      die "Conflicting revision numbers (jrevision='$jrevision', revision='$revision')";
144    }
145  }
146  return $revision;
147}
148
149sub getBranchOrTag() {
150  # returns any of
151  #   (0,trunk)
152  #   (0,branchname)
153  #   (1,tagname)
154  # or dies
155
156  my ($jroot,$jurl) = guessSvnBranchInsideJenkins();
157  my ($root,$url)   = (undef,undef);
158  eval {
159    my $infocmd = "svn info '$ARBHOME'";
160    print "[executing '$infocmd']\n";
161    open(INFO,$infocmd.'|') || die "failed to fork '$infocmd' (Reason: $!)";
162    foreach (<INFO>) {
163      chomp;
164      print "info[b]='$_'\n";
165      if (/^Repository\sRoot:\s+/o) { $root = $'; }
166      elsif (/^URL:\s+/o) { $url = $'; }
167    }
168    close(INFO) || die "failed to execute '$infocmd' (Reason: $!)";;
169  };
170  if ($@) {
171    if (defined $jroot and defined $jurl) {
172      print "Accepting svn failure (apparently running inside jenkins)\n";
173      ($root,$url) = ($jroot,$jurl);
174    }
175    else { die $@."\n"; }
176  }
177
178  if (not defined $root) { die "Failed to detect repository root"; }
179  if (not defined $url)  { die "Failed to detect repository URL"; }
180
181  if (defined $jroot) {
182    if (not defined $jurl)  { die "\$jroot defined, \$jurl undefined (bug in guessSvnBranchInsideJenkins?)"; }
183    if ($jroot ne $root) { die "Conflicting SVN root detection:\n1='$root'\n2='$jroot'"; }
184    if ($jurl  ne $url)  { die "Conflicting SVN url detection:\n1='$url'\n2='$jurl'"; }
185  }
186  elsif (defined $jurl) { die "\$jurl defined, \$jroot undefined (bug in guessSvnBranchInsideJenkins?)"; }
187
188  my $rootlen = length($root);
189  my $url_prefix = substr($url,0,$rootlen);
190  if ($url_prefix ne $root) { die "Expected '$url_prefix' to match '$root'"; }
191
192  my $rest = substr($url,$rootlen+1);
193  my $is_tag = 0;
194  if ($rest =~ /^branches\//) {
195    $rest = $';
196  }
197  elsif ($rest =~ /^tags\//) {
198    $rest = $';
199    $is_tag = 1;
200  }
201  return ($is_tag,$rest);
202}
203
204sub getBranchOrTagFromHeader($) {
205  my ($header) = @_;
206  open(HEADER,'<'.$header) || die "Failed to read '$header' (Reason: $!)";
207  my ($revision,$is_tag,$branch) = (undef,undef);
208  foreach (<HEADER>) {
209    chomp;
210    if (/^\#define\s+ARB_SVN_BRANCH\s+\"([^\"]+)\"/o) { $branch = $1; }
211    elsif (/^\#define\s+ARB_SVN_BRANCH_IS_TAG\s+([01])/o) { $is_tag = $1; }
212    elsif (/^\#define\s+ARB_SVN_REVISION\s+\"([^\"]+)\"/o) { $revision = $1; }
213  }
214  close(HEADER);
215
216  if (not defined $branch) { die "Failed to parse branch from $header"; }
217  if (not defined $is_tag) { die "Failed to parse is_tag from $header"; }
218  if (not defined $revision) { die "Failed to parse revision from $header"; }
219  if ($is_tag != 0 and $is_tag != 1) { die "Invalid value is_tag='$is_tag'"; }
220  return ($revision,$is_tag,$branch);
221}
222
223sub dumpFile($) {
224  my ($file) = @_;
225  print "---------------------------------------- [start $file]\n";
226  system("cat $file");
227  print "---------------------------------------- [end $file]\n";
228}
229
230sub update($\@) {
231  my ($file,$content_r) = @_;
232  my $tmp = $file.'.tmp';
233
234  open(TMP,'>'.$tmp) || die "can't write to '$tmp' (Reason: $!)";
235  foreach (@$content_r) { print TMP $_."\n"; }
236  close(TMP);
237  `$mv_if_diff '$tmp' '$file'`;
238  if ($dumpFiles) { dumpFile($file); }
239}
240
241sub file2hash($\%$) {
242  my ($file,$hash_r,$expectFile) = @_;
243  if (open(FILE,'<'.$file)) {
244    foreach (<FILE>) {
245      chomp;
246      if (/^([^=]+)=(.*)$/o) { $$hash_r{$1}=$2; }
247    }
248    close(FILE);
249  }
250  elsif ($expectFile==1) {
251    die "can't read '$file' (Reason: $!)";
252  }
253}
254
255sub hash2file(\%$) {
256  my ($hash_r,$file) = @_;
257  open(FILE,'>'.$file) or die "can't write '$file' (Reason: $!)";
258  foreach (sort keys %$hash_r) {
259    print FILE "$_=".$$hash_r{$_}."\n";
260  }
261  close(FILE);
262}
263
264# --------------------------------------------------------------------------------
265
266my $arb_build_h    = $TEMPLATES.'/arb_build.h';
267my $svn_revision_h = $TEMPLATES.'/svn_revision.h';
268
269my $in_SVN = (-d $ARBHOME.'/.svn');
270
271# update revision info?
272my ($revision,$is_tag,$branch) = (undef,undef,undef);
273if ($in_SVN) {
274  # in SVN checkout -> update revision info
275  $revision = getRevision();
276  ($is_tag,$branch) = getBranchOrTag();
277
278  # $branch = $RC_BRANCH; # @@@ fake
279  # $branch = $STABLE_BRANCH; # @@@ fake
280  # $branch = 'gtk_only'; # @@@ fake
281  # ($is_tag,$branch) = (1, 'arb-5.20.1'); # @@@ fake
282  # ($is_tag,$branch) = (1, 'arb-5.19'); # @@@ fake
283  # ($is_tag,$branch) = (1, 'evalSomething'); # @@@ fake
284  # ($is_tag,$branch) = (1, 'arb-5.20'); # @@@ fake
285  # ($is_tag,$branch) = (1, 'arb-5.20-rc1'); # @@@ fake
286  # ($is_tag,$branch) = (1, 'arb-5.20-rc2'); # @@@ fake
287
288  my @svn_revision = (
289                      '#define ARB_SVN_REVISION      "'.$revision.'"',
290                      '#define ARB_SVN_BRANCH        "'.$branch.'"',
291                      '#define ARB_SVN_BRANCH_IS_TAG '.$is_tag,
292                     );
293
294  update($svn_revision_h,@svn_revision);
295}
296else {
297  if (not -f $svn_revision_h) {
298    die "Missing file '$svn_revision_h'";
299  }
300  # use revision info as in source tarball
301  ($revision,$is_tag,$branch) = getBranchOrTagFromHeader($svn_revision_h);
302}
303
304my $date = `date '+%d.%b.%Y'`;
305chomp($date);
306my $year = undef;
307if ($date =~ /\.([^\.]+)$/o) {
308  $year = $1;
309}
310else {
311  die "error parsing year from '$date'";
312}
313
314# read version info
315my $version_info = $SOURCE_TOOLS.'/version_info';
316my %version_info = ();
317file2hash($version_info,%version_info,1);
318
319if (not defined $version_info{CANDIDATE}) { $version_info{CANDIDATE} = 1; }
320if (not defined $version_info{PATCHLEVEL}) { $version_info{PATCHLEVEL} = 0; }
321
322if (-f $inc_major or -f $inc_minor or -f $inc_candi or -f $inc_patch) { # version/rc-candidate/patchlevel upgrade requested?
323  eval {
324    print "\n";
325    if ($in_SVN) {
326      if ($is_tag==1) {
327        die "Upgrading version information not possible in tag-checkout! (tag of this WC = '$branch')";
328      }
329      if (-f $inc_candi) {
330        if ($branch ne $RC_BRANCH) {
331          die "Upgrading RC-candidate number only possible in branch '$RC_BRANCH' (you are in '$branch')";
332        }
333        my $oldRC = $version_info{CANDIDATE};
334        if (not defined $oldRC) { die "No CANDIDATE defined"; }
335        $version_info{CANDIDATE}++;
336        my $newRC = $version_info{CANDIDATE};
337        print "RC-candidate number upgraded from $oldRC to $newRC\n";
338      }
339      elsif (-f $inc_patch) {
340        if ($branch ne $STABLE_BRANCH) {
341          die "Upgrading patchlevel only possible in branch '$STABLE_BRANCH' (you are in '$branch')";
342        }
343        my $oldPL = $version_info{PATCHLEVEL};
344        if (not defined $oldPL) { die "No PATCHLEVEL defined"; }
345        $version_info{PATCHLEVEL}++;
346        my $newPL = $version_info{PATCHLEVEL};
347        print "patchlevel upgraded from $oldPL to $newPL\n";
348      }
349      else {
350        if ($is_tag==1 or $branch ne 'trunk') {
351          die "Upgrading version only possible in 'trunk' (you are in '$branch')";
352        }
353        my $oldVersion = $version_info{MAJOR}.'.'.$version_info{MINOR};
354        if (-f $inc_major) {
355          $version_info{MAJOR}++;
356          $version_info{MINOR} = 0;
357        }
358        else {
359          $version_info{MINOR}++;
360        }
361        $version_info{CANDIDATE} = 1; # first release candidate will be rc1
362        $version_info{PATCHLEVEL} = 0; # no patchlevel (yet)
363        my $newVersion = $version_info{MAJOR}.'.'.$version_info{MINOR};
364        print "Version upgraded from $oldVersion to $newVersion\n";
365      }
366
367      $version_info{last_upgrade}=time; # upgrade timestamp
368      hash2file(%version_info,$version_info);
369    }
370    else {
371      die "Upgrading version only possible in SVN WC";
372    }
373    print "\n";
374  };
375  my $failed = $@;
376
377  # always remove requests
378  -f $inc_major && unlink($inc_major);
379  -f $inc_minor && unlink($inc_minor);
380  -f $inc_candi && unlink($inc_candi);
381  -f $inc_patch && unlink($inc_patch);
382
383  if ($failed) { die "$failed\n"; }
384}
385
386# create valid svn-tag for this version
387
388my $svn_tag              = undef;
389my $short_version        = undef;
390my $always_show_revision = 1;
391
392my $orgbranch = $branch; # real branch or branch estimated from tag
393if ($is_tag==1) {
394  if ($branch =~ /^arb-[0-9]+\.[0-9]+/o) {
395    if ($branch =~ /-rc[0-9]+$/o) { $orgbranch = $RC_BRANCH; }
396    else                          { $orgbranch = $STABLE_BRANCH; }
397  }
398  else {
399    $orgbranch = 'unknown';
400  }
401}
402
403if ($orgbranch eq $STABLE_BRANCH or $orgbranch eq $RC_BRANCH) {
404  $always_show_revision = 0;
405  $svn_tag = 'arb-'.$version_info{MAJOR}.'.'.$version_info{MINOR};
406  if ($orgbranch eq $RC_BRANCH) {
407    $svn_tag .= '-rc'.$version_info{CANDIDATE};
408  }
409  else {
410    if ($version_info{PATCHLEVEL} > 0) { $svn_tag .= '.'.$version_info{PATCHLEVEL}; }
411  }
412  $short_version = $svn_tag;
413
414  if ($is_tag==1) {
415    # check real SVN-tag vs generated SVN-tag
416    if ($branch ne $svn_tag) {
417      die "Version info and SVN-branch-tag mismatch:\n".
418        "(version suggests svn-tag = '$svn_tag'\n".
419        " real             svn-tag = '$branch')";
420    }
421  }
422  print "SVN_URL='$ENV{SVN_URL}'\n";
423  print "SVN_REVISION='$ENV{SVN_REVISION}'\n";
424}
425elsif ($is_tag==1) {
426  $short_version = 'arb-special-'.$branch; # use custom tag
427}
428else {
429  $short_version = 'arb-devel';
430  if ($branch ne 'trunk') { $short_version .= '-'.$branch; }
431  $short_version .= '-'.$version_info{MAJOR}.'.'.$version_info{MINOR};
432}
433
434defined $short_version || die "expected known short_version!";
435defined $revision || die "expected known revision!";
436my $long_version  = $short_version.'.rev'.$revision;
437
438if ($always_show_revision==1) {
439  $short_version = $long_version;
440}
441
442my $ARB_64 = $ENV{ARB_64};
443if (not defined $ARB_64) {
444  my $config_makefile = $ARBHOME.'/config.makefile';
445  if (open(CONFIG, '<'.$config_makefile)) {
446    $ARB_64 = 1; # default to 64 bit -- see ../Makefile@64bit
447    foreach (<CONFIG>) {
448      if (/^\s*ARB_64\s*:=\s*([01]).*/) {
449        $ARB_64 = $1;
450      }
451    }
452    close(CONFIG);
453  }
454  else {
455    die "Either environment variable ARB_64 has to be defined or $config_makefile has to exist!";
456  }
457}
458
459if (not $ARB_64) {
460  $short_version .= '-32bit';
461  $long_version  .= '-32bit';
462}
463
464my @arb_build = (
465                 '#define ARB_VERSION            "'.$short_version.'"',
466                 '#define ARB_VERSION_DETAILED   "'.$long_version.'"',
467
468                 '#define ARB_BUILD_DATE         "'.$date.'"',
469                 '#define ARB_BUILD_YEAR         "'.$year.'"',
470
471                 '#define ARB_BUILD_HOST         "'.getHost().'"',
472                 '#define ARB_BUILD_USER         "'.getUser().'"',
473                );
474
475update($arb_build_h,@arb_build);
476
Note: See TracBrowser for help on using the repository browser.