Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
########################################################################
281 dpurdie 2
# Copyright ( C ) 2008-2009 ERG Limited, All rights reserved
227 dpurdie 3
#
263 dpurdie 4
# Module name   : jats_rewrite.pl
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
227 dpurdie 7
# Environment(s): jats
8
#
9
# Description   : Rewrite a build.pl file
10
#                 Use an external configuration file to provide a common
11
#                 source of configuration information
12
#
263 dpurdie 13
# Usage         : See POD
227 dpurdie 14
#
15
#......................................................................#
16
 
255 dpurdie 17
require 5.006_001;
227 dpurdie 18
use strict;
19
use warnings;
20
 
21
use JatsError;
22
use BuildName;
23
use Getopt::Long;
24
use Pod::Usage;                             # required for help support
25
 
26
 
27
################################################################################
28
#   Option variables
29
#
30
 
281 dpurdie 31
my $VERSION = "1.4.0";                      # Update this
227 dpurdie 32
my $opt_verbose = 0;
33
my $opt_datafile = "";
34
my $opt_ofile  = "auto.pl";
35
my $opt_infile = "build.pl";
36
my $opt_help = 0;
37
my $opt_errors = 0;
38
my $opt_xml;
39
my $opt_oldproject;
40
my $opt_newproject;
263 dpurdie 41
my $opt_noconfig;
281 dpurdie 42
my $opt_validate;
227 dpurdie 43
 
44
#
45
#   Globals
46
#
47
my %component =  ();
48
my %component_use =  ();
49
my $not_use_count = 0;
50
my $suffix_count = 0;
281 dpurdie 51
my @pkg_errors;
52
my @pkg_errors_val;
53
my $max_pkglen = 10;
227 dpurdie 54
 
247 dpurdie 55
#
56
#   Known extended fields
57
#   Only these values may be configured with the value=tag syntax
58
#   These may not be used as package names
59
#
60
my %fields = (
61
    'releasemanager.releasename' => undef,
62
    'releasemanager.projectname' => undef,
63
);
227 dpurdie 64
 
65
my $result = GetOptions (
281 dpurdie 66
                "help:+"        => \$opt_help,          # flag, multiple use allowed
67
                "manual:3"      => \$opt_help,          # flag
68
                "verbose:+"     => \$opt_verbose,       # flag
69
                "config=s"      => \$opt_datafile,      # string
70
                "noconfig"      => \$opt_noconfig,      # flag
71
                "outfile=s"     => \$opt_ofile,         # string
72
                "infile=s"      => \$opt_infile,        # string
73
                "errors"        => \$opt_errors,        # flag
74
                "xml!"          => \$opt_xml,           # flag
75
                "oldproject=s"  => \$opt_oldproject,    # string
76
                "newproject=s"  => \$opt_newproject,    # string
77
                "validate"      => \$opt_validate,      # flag
227 dpurdie 78
                );
79
 
80
#
81
#   Process help and manual options
82
#
83
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
84
pod2usage(-verbose => 1)  if ($opt_help == 2 );
263 dpurdie 85
pod2usage(-verbose => 2)  if ($opt_help > 2);
227 dpurdie 86
 
87
#
88
#   Configure the error reporting process now that we have the user options
89
#
90
ErrorConfig( 'name'    =>'REWRITE',
91
             'verbose' => $opt_verbose );
92
 
93
Error ("Must specify both Old and New project tags")
94
    if ( $opt_newproject xor $opt_oldproject );
95
 
263 dpurdie 96
Error ("Conflicting options -config=file and -noconfig")
97
    if ( $opt_datafile && $opt_noconfig );
98
 
227 dpurdie 99
Error ("No configuration file specified")
263 dpurdie 100
    unless ( $opt_datafile || $opt_newproject || $opt_noconfig );
227 dpurdie 101
 
102
Error ("Input and output file are the same" )
103
    if ( $opt_infile eq $opt_ofile );
104
 
105
#
106
#   Auto detect XML files
107
#
108
$opt_xml = 1
109
    if ( $opt_infile =~ m~\.xml$~i );
110
 
111
#
112
#   Process config and input files
113
#
114
read_config_file()          if $opt_datafile;
115
process_build_file()        unless( $opt_xml);
116
process_xml_build_file()    if ( $opt_xml);
117
 
118
Verbose ("Number of project extensions changed: $suffix_count")
119
    if ( $ opt_newproject );
120
 
121
Warning("No project extensions changed")
122
    if ( !$suffix_count && $opt_newproject);
123
 
281 dpurdie 124
if ( @pkg_errors || @pkg_errors_val)
125
{
126
    ReportError ("Errors encountered in the following packages:");
127
    ReportError ( @pkg_errors );
128
    ReportError ( @pkg_errors_val );
129
    ReportError ( "Package Names and Versions in build files may not match Release Manager");
130
}
131
 
132
ReportError("Unused packages found: $not_use_count")
227 dpurdie 133
    if ( $opt_errors && $not_use_count && $opt_datafile);
134
 
135
 
281 dpurdie 136
ErrorDoExit();
227 dpurdie 137
exit 0;
138
 
139
#-------------------------------------------------------------------------------
140
# Function        : read_config_file
141
#
142
# Description     : Read and store config file information
143
#
144
# Inputs          :
145
#
146
# Returns         :
147
#
148
 
149
sub read_config_file
150
{
151
    open ( FILE, "<$opt_datafile" ) or Error ("Config file ($opt_datafile) not found" );
152
    while ( <FILE> )
153
    {
154
        #
155
        #   Clean up lines
156
        #   Skip comments and blank lines
157
        #   Remove leading and training white space
158
        #
159
        chomp;
160
        s~^\s*~~;
161
        s~#.*$~~;
162
        s~\s*$~~;
163
        next if ( length( $_) <= 0 );
164
 
165
#        Verbose ($_);
166
 
167
        #
247 dpurdie 168
        #   Extract special fields
169
        #   These are not dependent packages and are not mandatory
170
        #   These are of the form tag = name
171
        #
172
        if ( m{(\S+)\s*=\s*(.+)} )
173
        {
174
            Error ("Unsupported named field")  unless ( exists $fields{$1} );
175
            $fields{$1} = $2;
176
            Verbose ("Field: $1, \"$2\"");
177
            next;
178
        }
179
 
180
        #
227 dpurdie 181
        #   Process LinkPkgArchive and BuildPkgArchive statements
182
        #   These allow simple updating of the config file from Release manager
183
        #
184
        if ( m/LinkPkgArchive/ or m/BuildPkgArchive/ )
185
        {
186
            m/'(.*)'[^']*'(.*)'/;
187
 
188
            my $comp = $1;
189
            my $ver = $2;
190
 
191
#print "Got Archive stuff: $_ : $comp, $ver\n";
192
 
193
            Error "Version not specified for: $comp" unless ( $ver );
194
            Warning "Suspect version format for: $comp ($ver)" unless ( $ver =~ m~^\w+\.\w+\.\w+.\w+$~ || $ver =~ m~^\w+\.\w+\.\w+$~ );
195
 
196
            save_package( $comp, $ver );
197
            next;
198
        }
199
 
200
 
201
 
202
        #
203
        #   Process line as
204
        #       component version
205
        #
206
        my ( $comp, $ver, $opt ) = split( /[\s,]+/, $_, 3);
207
        Error "Version not specified for: $comp" unless ( $ver );
208
        Warning "Suspect version format for: $comp ($ver)" unless ( $ver =~ m~^\w+\.\w+\.\w+.\w+$~ || $ver =~ m~^\w+\.\w+\.\w+$~ );
209
        save_package( $comp, $ver );
210
    }
211
    close FILE;
212
 
213
#    DebugDumpData ("component", \%component );
214
}
215
 
216
#-------------------------------------------------------------------------------
217
# Function        : print_update
218
#
219
# Description     : Generate a display line tracking the changes made
220
#
221
# Inputs          :
222
#                   $title          - Update Type
223
#                   $name           - Package name
224
#                   $version        - Original version of package
225
#                   $new_version    - New version
226
#
227
# Returns         :
228
#
229
sub print_update
230
{
231
    my ($title, $name, $version, $new_version ) = @_;
232
    my $diff = ( $version ne $new_version ) ? '*' : '';
233
 
234
    #
235
    #   Always display diffs
236
    #   Display all if verbose
237
    #
238
    if ( $diff || $opt_verbose  )
239
    {
240
        $title = 'Package' unless ( $title );
281 dpurdie 241
        Message( sprintf("%-8s: %-${max_pkglen}s, Version: %-15s %1.1s-> %-15s\n", $title, $name ,$version, $diff, $new_version));
227 dpurdie 242
    }
243
}
244
 
245
#-------------------------------------------------------------------------------
246
# Function        : process_build_file
247
#
248
# Description     : Rewrite one file
249
#                   build.pl -> build-new.pl
250
#
251
# Inputs          :
252
#
253
# Returns         :
254
#
255
sub process_build_file
256
{
257
    Verbose ("Processing build file: $opt_infile");
258
 
259
    #
260
    #   Unlink any OLD output file
261
    #
262
    unlink $opt_ofile;
263
 
264
    #
265
    #   Open the input and output files
266
    #
267
    open ( INFILE, "<$opt_infile" ) || Error( "Cannot open $opt_infile" );
268
    open ( OUTFILE, ">$opt_ofile" ) || Error( "Cannot create $opt_ofile" );
269
 
270
    my $build_info;
271
 
272
    my $release_name;
273
    my $release_version;
274
 
275
    while ( <INFILE> )
276
    {
263 dpurdie 277
        next if ( $opt_noconfig );       # Nothing to do
227 dpurdie 278
        next if ( m~^\s*#~ );            # Skip comments
279
        #
280
        #   Process BuildName
281
        #
282
        if ( m~\s*BuildName[\s\(]~ )
283
        {
284
            #   Build names come in many flavours
285
            #   Must support a number of different formats
286
            #       "name nn.nn.nn prj"
287
            #       "name nn.nn.nn.prj"
288
            #
289
            #       "name nn.nn.nn prj", "nn.nn.nn"
290
            #       "name nn.nn.nn.prj", "nn.nn.nn"
291
            #
292
            #       "name", "nn.nn.nn.prj"
293
            #
294
            m~\(\s*(.*?)\s*\)~;
295
            my @args = split /\s*,\s*/, $1;
296
            $build_info = parseBuildName( @args );
297
 
298
            my $new_ver = get_package ( $build_info->{BUILDNAME_PACKAGE}, $build_info->{BUILDVERSION} );
299
            my $build_args = genBuildName( $build_info, $new_ver );
300
 
301
            #
302
            #   Rewrite the body of the directive
303
            #
304
            s~\(\s*(.*?)\s*\)~( $build_args )~;
305
            print_update( '', $build_info->{BUILDNAME_PACKAGE}, $build_info->{BUILDVERSION}, $new_ver );
306
 
307
        }
308
 
309
        #
310
        #   Process BuildPreviousVersion
311
        #   Save the current version information in this directive
312
        #
313
        if ( m/^\s*BuildPreviousVersion/ )
314
        {
315
            Error ("BuildPreviousVersion directive before BuildName") unless ( $build_info );
316
            m/['"](.*?)['"]/;
317
            my $prev = $1;
281 dpurdie 318
            my $new_ver = $opt_validate ? $prev : $build_info->{BUILDVERSION};
227 dpurdie 319
 
320
            s/['"](.*?)['"]/'$build_info->{BUILDVERSION}'/;
281 dpurdie 321
            print_update( 'PrevVer', '', $prev, $new_ver );
227 dpurdie 322
        }
323
 
324
        #
325
        #   Process BuildPkgArchive and LinkPkgArchive
326
        if ( m/^\s*LinkPkgArchive/ or m/^\s*BuildPkgArchive/ )
327
        {
328
            m/['"](.*?)['"][^'"]*['"](.*?)['"]/;
329
 
330
            my $comp = $1;
331
            my $ver = $2;
332
            my $new_ver = get_package ( $comp, $ver );
333
            s/['"](.*?)['"]([^'"]*)['"](.*?)['"]/'$comp'$2'$new_ver'/;
334
            print_update ('', $comp ,$ver, $new_ver );
335
        }
336
 
337
 
338
    } continue
339
    {
340
        #
341
        #   Always output the resultant line
342
        #
343
        print OUTFILE $_;
344
    }
345
 
346
    #
347
    #   Cleanup
348
    #
349
    close INFILE;
350
    close OUTFILE;
351
    display_unused();
352
}
353
 
354
#-------------------------------------------------------------------------------
355
# Function        : process_xml_build_file
356
#
357
# Description     : Rewrite one depends.xml file
358
#                   depends.xml -> auto.xml
359
#
360
#                   A very cheap and nasty XML (not)parser
361
#                   It assumes that entries are all on one line so that we can
362
#                   do trivial substitutions
363
#
364
#                   Processes
365
#                       <using ... >
247 dpurdie 366
#                       <property name="packagename" value="...">
367
#                       <property name="packageversion" value="...">
368
#                       <property name="releasemanager.releasename" value="...">
369
#                       <property name="releasemanager.projectname" value="...">
227 dpurdie 370
#                       <import file=...>
371
#
247 dpurdie 372
#                  Note: This function handles a wider scope of XML files
373
#                        than it really needs to. All thats needed is
249 dpurdie 374
#                        the <property name= value=> fields.
227 dpurdie 375
#
376
# Inputs          :
377
#
378
# Returns         :
379
#
380
sub process_xml_build_file
381
{
382
    Verbose ("$opt_infile");
383
 
384
    #
385
    #   Unlink any OLD output file
386
    #
387
    unlink $opt_ofile;
388
 
389
    #
390
    #   Open the input and output files
391
    #
392
    open ( INFILE, "<$opt_infile" ) || Error( "Cannot open $opt_infile" );
393
    open ( OUTFILE, ">$opt_ofile" ) || Error( "Cannot create $opt_ofile" );
394
 
395
    my $release_name;
396
    my $release_version;
397
 
398
    while ( <INFILE> )
399
    {
263 dpurdie 400
        next if ( $opt_noconfig );       # Nothing to do
227 dpurdie 401
        #
402
        #   Process "project" statement
403
        #
404
        if ( m~<project~ )
405
        {
406
            #   Extract the package name
407
            #   this to determine the required version of the package
408
            #
249 dpurdie 409
            if ( m~name="([^"]*)"~ )
233 dpurdie 410
            {
411
                $release_name = $1;
412
                Error ("Empty 'name' attribute not found in 'project'") unless ( $release_name );
413
                Verbose2 ("Project: $release_name");
414
            }
227 dpurdie 415
        }
416
 
417
        #
418
        #   Process "property" statements
419
        #
420
        elsif ( m~<property~ )
421
        {
422
            #
247 dpurdie 423
            #   Extract name and value
424
            #   Both must exist
227 dpurdie 425
            #
247 dpurdie 426
            my $name;
427
            my $value;
227 dpurdie 428
 
249 dpurdie 429
            if ( m~name="([^"]*)"~  )
247 dpurdie 430
            {
431
                $name = $1;
432
            }
433
            else
434
            {
435
                Error ("Name attribute not found in 'property'");
436
            }
437
 
249 dpurdie 438
            if ( m~value="([^"]*)"~ )
247 dpurdie 439
            {
440
                $value = $1;
441
            }
442
            else
443
            {
444
                Error ("Value attribute not found in $name 'property'");
445
            }
446
            Verbose2 ("Property: $name, Value: $value");
447
 
227 dpurdie 448
            #
247 dpurdie 449
            #   Examine th property name
450
            #   Some of the them are special, others will be package names
227 dpurdie 451
            #
452
            if ( $name eq 'packagename' )
453
            {
247 dpurdie 454
                $release_name = $value;
227 dpurdie 455
                Error ("Value attribute not found in packagename 'property'") unless ( $release_name );
456
            }
457
            elsif ( $name eq 'packageversion' )
458
            {
247 dpurdie 459
                $release_version = $value;
227 dpurdie 460
 
461
                #
462
                #   Ensure that we already have the package name
463
                #
464
                Error ("packageversion before packagename") unless ( $release_name );
465
 
466
                my $new_ver = get_package ( $release_name, $release_version );
249 dpurdie 467
                s~(.*)value="([^"]*)"~$1value=\"$new_ver\"~;
227 dpurdie 468
                print_update( '', $release_name ,$release_version, $new_ver );
469
            }
247 dpurdie 470
            elsif ( defined $fields{$name} )
227 dpurdie 471
            {
472
                #
247 dpurdie 473
                #   Use tagged values in preference to packages
474
                #   There are very few tagged values.
227 dpurdie 475
                #
247 dpurdie 476
                my $new_value = $fields{$name};
477
                Error ("Release attribute not found: $name") unless ( $new_value );
478
 
249 dpurdie 479
                s~(.*)value="([^"]*)"~$1value=\"$new_value\"~;
247 dpurdie 480
                print_update( 'Release', $name ,$value, $new_value );
227 dpurdie 481
            }
482
            else
483
            {
247 dpurdie 484
                my $new_ver = get_package ( $name, $value );
249 dpurdie 485
                s~(.*)value="([^"]*)"~$1value=\"$new_ver\"~;
247 dpurdie 486
                print_update( '', $name ,$value, $new_ver );
227 dpurdie 487
            }
488
        }
489
 
490
        #
491
        #   Process "using" statements
492
        #
493
        elsif ( m~<using~ )
494
        {
495
            #
496
            #   Extract the package name and version
497
            #   and use this to determine the required version of the package
498
            #
249 dpurdie 499
            m~name="([^"]*)"~;
227 dpurdie 500
            my $name = $1;
501
            Error ("Name attribute not found in 'using'") unless ( $name );
502
            Verbose2 ("Using: $name");
503
 
504
            #
505
            #   Extract the version
506
            #
249 dpurdie 507
            m~version="([^"]*)"~;
227 dpurdie 508
            $release_version = $1;
509
            Error ("Version attribute not found in package 'using' : $name") unless ( $release_version );
510
 
511
            my $new_ver = get_package ( $name, $release_version );
249 dpurdie 512
            s~(.*)version="([^"]*)"~$1version=\"$new_ver\"~;
227 dpurdie 513
            print_update( '', $name ,$release_version, $new_ver );
514
        }
515
 
516
        #
517
        #   Import File
247 dpurdie 518
        #   Only used to import ant-using
227 dpurdie 519
        #
520
        elsif ( m~<import~ )
521
        {
522
            #
523
            #   Extract the file
524
            #
249 dpurdie 525
            m~file="([^"]*)"~;
227 dpurdie 526
            my $file = $1;
527
            Error ("File attribute not found in 'import'") unless ( $file );
528
 
529
            #
530
            #   Extract the package name and version from the file
531
            #   Will be of the form /package/version/filename
532
            #
533
            $file =~ m~(.*?)/([^/]+)/([^/]+)/([^/]+)$~;
534
            my $prefix = $1;
535
            my $pname = $2;
536
            my $pver = $3;
537
            my $fname = $4;
538
            Error ("Package details not found in import file") unless ( $fname );
539
 
540
            my $new_ver = get_package ( $pname, $pver );
541
 
542
            #
543
            #   Rewrite the body of the directive
544
            #
249 dpurdie 545
            s~(.*)file="([^"]*)"~$1file=\"$prefix/$pname/$new_ver/$fname\"~;
227 dpurdie 546
            print_update( '', $pname ,$pver, $new_ver );
547
        }
548
 
549
    } continue
550
    {
551
        #
552
        #   Always output the resultant line
553
        #
554
        print OUTFILE $_;
555
    }
556
 
557
    #
558
    #   Cleanup
559
    #
560
    close INFILE;
561
    close OUTFILE;
562
    display_unused();
563
}
564
 
565
#-------------------------------------------------------------------------------
566
# Function        : display_unused
567
#
568
# Description     : Generate warnings about config items that were not used
569
#
570
# Inputs          :
571
#
572
# Returns         :
573
#
574
sub display_unused
575
{
576
    foreach my $comp ( sort keys %component_use )
577
    {
578
        foreach my $suf ( keys %{$component_use{$comp}} )
579
        {
580
            my $ver = get_version( $comp, $suf );
581
            Warning("Unused package: ${comp}_${ver}");
582
            $not_use_count++;
583
        }
584
    }
585
}
586
 
587
#-------------------------------------------------------------------------------
588
# Function        : save_package
589
#
590
# Description     : Save the package name and version
591
#
592
# Inputs          : $package
593
#                   $version
594
#
595
# Returns         : Nothing
596
#
597
sub save_package
598
{
599
    my ($package, $version) = @_;
600
 
601
    #
281 dpurdie 602
    #   Determine longest package name
603
    #
604
    my $len = length $package;
605
    $max_pkglen = $len
606
        if ( $len > $max_pkglen );
607
 
608
    #
227 dpurdie 609
    #   Split the suffix off the version
610
    #
611
    my ($rel, $suf ) = extract_version( $package, $version);
612
 
613
    Error ("Multiple definitions for $package $version" )
614
        if ( $component{$package}{$suf} );
615
 
247 dpurdie 616
    Error ("Package Name is a reserved key field: $package" )
617
        if ( exists $fields{$package} );
618
 
227 dpurdie 619
    $component{$package}{$suf} = $rel;
620
    $component_use{$package}{$suf} = $rel;
621
 
622
    Verbose2 ("Package: $package, $version, $rel, $suf");
623
 
624
}
625
 
626
#-------------------------------------------------------------------------------
627
# Function        : get_package
628
#
281 dpurdie 629
# Description     : Get the package version
630
#                   Validates package-version if required
227 dpurdie 631
#
281 dpurdie 632
#                   Does not generate errors, but will generate error information
633
#                   to be reported later.
634
#
227 dpurdie 635
# Inputs          : $package
636
#                   $version ( suffix is used only )
637
#
638
# Returns         : Replacement version
639
#
640
 
641
sub get_package
642
{
643
    my ($package, $version) = @_;
644
 
645
    #
646
    #   Split the suffix off the version
647
    #       Suffixes are not numeric
648
    #   Must allow for
649
    #       9.9.9
650
    #       9.9.cots
651
    #       9.9.9.cots
652
    #
653
    my ($rel, $suf ) = extract_version( $package, $version);
654
 
655
    Verbose2 ("Get Package: $package, $version, $rel, $suf");
656
 
657
    #
658
    #   If the CFG file has 'new' project extensions then we
659
    #   must transform them before attempting to look up the versions
660
    #
661
    if ( $opt_oldproject && $suf eq $opt_oldproject )
662
    {
663
        $suf = $opt_newproject;
664
        $suffix_count++;
665
    }
666
 
667
    #
668
    #   If a datafile was provided, then the packages MUST be present
669
    #
670
    if ( $opt_datafile )
671
    {
281 dpurdie 672
        unless ( exists $component{$package} )
673
        {
674
            push @pkg_errors, "No definitions for package '$package'";
675
            return $version;
676
        }
227 dpurdie 677
 
678
    #    print Data::Dumper->Dump ( [\%component], ["Component" ]);
679
 
281 dpurdie 680
        unless ( exists $component{$package}{$suf} )
681
        {
682
            push @pkg_errors, "No definitions for '$package' '$version' '$suf'";
683
            return $version;
684
        }
227 dpurdie 685
    }
686
 
687
    #
688
    #   remove used packages from the "use" hash
689
    #
690
    delete $component_use{$package}{$suf};
691
    delete $component_use{$package} unless ( keys %{$component_use{$package}} );
692
 
693
    #
694
    #   Was the suffix real
695
    #
281 dpurdie 696
    my $new_version = get_version( $package, $suf, $rel );
697
    if ( $opt_validate )
698
    {
699
        if ( $new_version ne $version )
700
        {
701
            push @pkg_errors_val, sprintf("Validation mismatch: %-${max_pkglen}s, %-15s != %-15s", $package ,$version,  $new_version);
702
            return $version;
703
        }
704
    }
705
    return $new_version;
227 dpurdie 706
}
707
 
708
#-------------------------------------------------------------------------------
709
# Function        : extract_version
710
#
711
# Description     : Extracts a version and project suffix from a string
712
#
713
# Inputs          : $1  - Package name
714
#                   $2  - Package Version Input string
715
#
716
# Returns         : $1  - Vesrion part
717
#                   $2  - Suffix (project) part
718
#
719
sub extract_version
720
{
721
    my ($package, $version) = @_;
722
 
723
    my $rel;
724
    my $suf;
725
 
726
    if ( $version =~ m~^(.*?)([\.\s]([^0-9]+))$~ )
727
    {
728
        $rel = $1;
729
        $suf = $3;
730
        $suf = '' unless ( $suf );
731
    }
732
    else
733
    {
734
        $rel = $version;
735
        $suf = '';
736
    }
737
 
738
    return ( $rel, $suf );
739
}
740
 
741
#-------------------------------------------------------------------------------
742
# Function        : get_version
743
#
744
# Description     : Create a nice package version
745
#
746
# Inputs          : $package
747
#                   $suf
748
#
749
# Returns         :
750
#
751
sub get_version
752
{
753
    my ($package,$suf, $version) = @_;
754
 
755
    if ( exists( $component{$package}{$suf} ) )
756
    {
757
        $version = $component{$package}{$suf};
758
    }
759
 
760
    if ( $opt_oldproject && $suf eq $opt_oldproject )
761
    {
762
        $suf = $opt_newproject;
763
        $suffix_count++;
764
    }
765
 
766
    $version .= '.' . $suf if ( length( $suf) );
767
    return  $version;
768
 
769
}
770
 
771
#-------------------------------------------------------------------------------
772
# Function        : genBuildName
773
#
774
# Description     : Generate a BuildName argument string
775
#
776
# Inputs          : build_info      - Hash of buildname arguments
777
#                   new_ver         - New version
778
#
779
# Returns         : A string of quoted BuildName arguemnts
780
#
781
sub genBuildName
782
{
783
    my ( $build_info, $new_ver ) = @_;
784
    my @args;
785
 
786
    #
787
    #   Remove the project part from the new version name
788
    #
789
    my $prj = $build_info->{BUILDNAME_PROJECT};
790
 
791
    $prj = $opt_newproject
792
        if ( $opt_oldproject && $prj eq $opt_oldproject );
793
 
794
    $new_ver =~ s~\.$prj$~~ if ( $prj );
795
 
796
    #
797
    #   Determine the format of the BuildName
798
    #
799
    if ( $build_info->{RELAXED_VERSION} )
800
    {
801
        #
802
        #   Relaxed format
803
        #
804
        push @args, $build_info->{BUILDNAME_PACKAGE};
805
        push @args, $new_ver;
806
        push @args, $prj if ( $prj );
807
        push @args, '--RelaxedVersion';
808
    }
809
    else
810
    {
811
        #
812
        #   Generate two field version as some of the deployment scripts
813
        #   need this format.
814
        #
815
        push @args, "$build_info->{BUILDNAME_PACKAGE} $new_ver $prj";
816
    }
817
 
818
    #
819
    #   Common arguments
820
    #
821
    push @args, "--PatchNum=$build_info->{DEPLOY_PATCH}"
822
        if ( $build_info->{DEPLOY_PATCH} );
823
 
824
    push @args, @{$build_info->{EXTRA_ARGS}} if exists ($build_info->{EXTRA_ARGS});
825
 
826
 
827
    #
828
    #   Format the arguments
829
    #
830
    return join ", ", map { "'$_'" } @args;
831
}
832
 
833
#-------------------------------------------------------------------------------
834
#   Documentation
835
#
836
 
837
=pod
838
 
839
=head1 NAME
840
 
841
jats_rewrite - Rewrite a build.pl file
842
 
843
=head1 SYNOPSIS
844
 
845
  jats etool jats_rewrite [options]
846
 
847
 Options:
848
    -help               - brief help message
849
    -help -help         - Detailed help message
850
    -man                - Full documentation
851
    -verbose            - Verbose operation
852
    -config xxx         - Configuration file. Full file name
263 dpurdie 853
    -noconfig           - No configuration file
227 dpurdie 854
    -oldproject         - Old project extension (optional)
855
    -newproject         - New project extension (optional)
856
    -infile xxx         - Input file (build.pl)
857
    -outfile xxx        - Output file (auto.pl)
858
    -errors             - Generate errors for unused config items
859
    -xml                - Process a build.xml file
281 dpurdie 860
    -validate           - Validate dependencies only
227 dpurdie 861
 
862
=head1 OPTIONS
863
 
864
=over 8
865
 
866
=item B<-help>
867
 
868
Print a brief help message and exits.
869
 
870
=item B<-help -help>
871
 
872
Print a detailed help message with an explanation for each option.
873
 
874
=item B<-man>
875
 
876
Prints the manual page and exits.
877
 
878
=item B<-verbose>
879
 
247 dpurdie 880
Increases program output. This option may be specified multiple times
227 dpurdie 881
 
882
=item B<-config=xxx>
883
 
884
This option specifies the name of a configuration file that will provide the
885
transformation between of version numbers. The format of the config file is
886
described later.
887
 
888
The option is not required if -newproject and -oldproject are specified
889
 
263 dpurdie 890
=item B<-noconfig>
891
 
281 dpurdie 892
This option indicates that no config file is present and that the output file
263 dpurdie 893
is to be created without reference to the configuration.
894
 
227 dpurdie 895
=item B<-oldproject=xxx>
896
 
897
This option, in conjunction with B<-oldproject=xxx> allows the project
247 dpurdie 898
extensions to be modified. ie: .syd projects can be converted into .bej
227 dpurdie 899
projects.
900
 
247 dpurdie 901
If this option is present then the config data file is not required, although
227 dpurdie 902
it will be sued if it is present.
903
 
904
=item B<-newproject=xxx>
905
 
906
See B<-oldproject=xxx>
907
 
908
 
909
=item B<-infile=xxx>
910
 
911
The name of the input file. The default file is build.pl
912
 
913
=item B<-outfile=xxx>
914
 
915
The name of the output file. The default is auto.pl, even if an XML file is
916
being processed.
917
 
918
=item B<-errors>
919
 
920
This option will force the program to generate an error message if there are
921
packages in the config file that were not used by the re-write process.
922
 
923
=item B<-xml>
924
 
925
Process a build.xml file instead of a build.pl file.
247 dpurdie 926
This option will be set internally if the infile extension is '.xml'
227 dpurdie 927
 
281 dpurdie 928
=item B<-validate>
929
 
930
This option will validate the build files against the configuration file. This
931
option is used by build tools to validate dependency information.
932
 
227 dpurdie 933
=back
934
 
935
=head1 DESCRIPTION
936
 
247 dpurdie 937
This utility is used within the automated build system to rewrite build files
938
so that they contain suitable version numbers.
227 dpurdie 939
 
247 dpurdie 940
The program takes a configuration file, described below, that contains package
941
and version information for the build.
942
 
943
The program takes a JATS build.pl file, or an ANT style dependency file, and
944
will create a file that is similar, but contains modified package-version
945
information.
946
 
947
The build tools are designed to use this I<auto> file, in preference to the
948
original build file.
949
 
950
=head2 Format of the Configuration File
951
 
227 dpurdie 952
The format of the configuration file is defined below.
953
 
247 dpurdie 954
The file is a line oriented text file.
227 dpurdie 955
 
247 dpurdie 956
Comments begin with a # and go the end of the line.
227 dpurdie 957
 
247 dpurdie 958
There are three types of configuration line:
227 dpurdie 959
 
247 dpurdie 960
=over 8
961
 
962
=item Assigned Items
963
 
964
These are of the form: B<tag = value> and are used to specify the value of
965
the following B<special> properties:
966
 
967
=over 8
968
 
969
=item releasemanager.projectname
970
 
971
The name of the Release Manager project used for the build.
972
 
973
=item releasemanager.releasename
974
 
975
The name of the Release Manager release, within the project, used for the build.
976
 
977
=back
978
 
979
These may be used to brand installer programs with Release Information.
980
Currently the use of these tags is only supported by the XML build files.
981
 
982
=item Package Version
983
 
984
Specifies the version of a package to use as two, space separated words of the
985
form C<package_name package_version> where package version is of the form:
986
 
987
=over 8
988
 
989
=item   * nn.nn.nnnn.aaa
990
 
991
=item   * nn.nn.nnnn
992
 
993
=item   * Other
994
 
995
=back
996
 
997
=item LinkPkgArchive or BuildPkgArchive
998
 
999
These are standard JATS LinkPkgArchive or BuildPkgArchive statements.
1000
 
1001
=back
1002
 
1003
=head2 XML File Rewrite
1004
 
1005
This program will process an ERG style ANT build dependency definition file
1006
and replace the values of the properties seen within the file.
1007
 
1008
The following properties are special within the rewrite process:
1009
 
1010
=over 8
1011
 
1012
=item	packagename
1013
 
1014
This is the name of the package. It is not modified, but it
1015
is used in conjunction with the C<packageversion> to identify the package, such
1016
that the packageversion can be updated. This property is mandatory and must
1017
appear before the C<packageversion>.
1018
 
1019
=item	packageversion
1020
 
1021
This is the version of the package. It can be rewritten by this program. This
1022
property is mandatory.
1023
 
1024
=item	releasemanager.projectname
1025
 
1026
If this property is found the value will be replaced with an B<Assigned Item> of the
1027
same name.
1028
 
1029
=item	releasemanager.releasename
1030
 
1031
If this property is found the value will be replaced with an B<Assigned Item> of the
1032
same name.
1033
 
1034
=back
1035
 
1036
Properties that are not B<special> will be treated as the name of a package and
1037
the value will be updated to reflect the required version of the package.
1038
 
1039
The XML rewrite process does not, and cannot handle, instances of packages
1040
that have the same name, but different project suffixes. This is a limitation of
1041
the ERG ANT build system and not a limitation of this utility.
1042
 
1043
=head2 JATS Build File Rewrite
1044
 
1045
This program will process a JATS style build.pl file and modify some
1046
directives to update the file.
1047
 
1048
The following directives will be processed:
1049
 
1050
=over 8
1051
 
1052
=item BuildName
1053
 
1054
The existing version in the BuildName directive will be retained and may be used
1055
in any BuildPreviousVersion directive that is seen.
1056
 
1057
=item BuildPreviousVersion
1058
 
1059
This will be updated to contain the version from the BuildName. This is
1060
intended to be used by deployment scripts.
1061
 
1062
=item LinkPkgArchive
1063
 
1064
The version will be updated to reflect the configured package versions. The
1065
project suffix, if present, will be used to identify the correct package.
1066
 
1067
=item BuildPkgArchive
1068
 
1069
The version will be updated to reflect the configured package versions. The
1070
project suffix, if present, will be used to identify the correct package.
1071
 
1072
=back
1073
 
1074
The JATS build file rewrite process, unlike the ANT process, does handle, instances of packages
1075
that have the same name, but different project suffixes. This allows the use
1076
of packages such as C<sysbasetypes.cr> and C<sysbasetypes.prj> within the one
1077
package.
1078
 
1079
Currently the JATS build file rewrite process does pass the
1080
releasemanager.projectname and the releasemanager.releasename items through to
1081
the underlying system. If present in the config file they will be unused. This
1082
is not an error.
1083
 
227 dpurdie 1084
=cut
1085