Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
227 dpurdie 1
#! perl
2
########################################################################
3
# Copyright ( C ) 2004 ERG Limited, All rights reserved
4
#
5
# Module name   : jats.sh
6
# Module type   : Makefile system
7
# Compiler(s)   : n/a
8
# Environment(s): jats
9
#
10
# Description   : Create a COTS package
11
#
12
# Usage:
13
#
14
# Version   Who      Date        Description
15
#
16
#......................................................................#
17
 
18
require 5.6.1;
19
use Cwd;
20
use strict;
21
use warnings;
22
use JatsError;
23
use FileUtils;
24
use File::Basename;
25
use File::Find;
26
use File::Copy;
27
use File::Path;
28
 
29
use Pod::Usage;                             # required for help support
30
use Getopt::Long;
31
use Cwd;
32
 
33
#-------------------------------------------------------------------------------
34
#   Global variables
35
#
36
my $VERSION = "1.0.0";                      # Update this
37
my $GBE_DPKG = $ENV{ GBE_DPKG };
38
my $CWD_DIR = cwd;
39
my %subdirs;
40
my %files;
41
my $DESTDIR = 'src';           # 'src'
42
my $last_result;
43
my @error_list;
44
my $vob_dir  = '';
45
my $vob_name = '';
46
my $src_dir;
47
 
48
#
49
#   Options
50
#
51
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
52
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
53
my $opt_help = 0;
54
my $opt_manual = 0;
55
my $opt_label;
56
my $opt_vob = 'COTS';
57
my $opt_test;
58
my $opt_keep;
59
my $opt_delete;
60
my $opt_subdir;
61
my $opt_image;
62
 
63
 
64
#-------------------------------------------------------------------------------
65
# Function        : Mainline Entry Point
66
#
67
# Description     :
68
#
69
# Inputs          :
70
#
71
my $result = GetOptions (
72
                "help+"         => \$opt_help,              # flag, multiple use allowed
73
                "manual"        => \$opt_manual,            # flag
74
                "verbose+"      => \$opt_verbose,           # flag, multiple use allowed
75
                "label=s"       => \$opt_label,             # String
76
                "vob=s"         => \$opt_vob,               # String
77
                "test"          => \$opt_test,              # Flag
78
                "keep"          => \$opt_keep,              # Flag
79
                "delete"        => \$opt_delete,            # Flag
80
                "subdir=s"      => \$opt_subdir,            # string
81
                "image=s"       => \$opt_image,             # string
82
 
83
                );
84
 
85
                #
86
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
87
                #
88
 
89
#
90
#   Process help and manual options
91
#
92
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
93
pod2usage(-verbose => 1) if ($opt_help == 2 );
94
pod2usage(-verbose => 2) if ($opt_manual || ($opt_help > 2));
95
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ( $#ARGV < 0 );
96
 
97
#
98
#   Configure the error reporting process now that we have the user options
99
#
100
ErrorConfig( 'name'    =>'gen_cots',
101
             'verbose' => $opt_verbose,
102
            );
103
 
104
#
105
#   Init the file uitilites
106
#
107
InitFileUtils();
108
Error ("This utility only runs on WINDOWS, not $::ScmHost") unless ( $::ScmHost eq 'WIN' );
109
Error ("No DPK_ARCHIVE") unless ( $GBE_DPKG );
110
Error ("Must specify a target VOB") unless ( $opt_vob );
111
Error ("Need two arguments: package and version") unless ( $#ARGV eq 1 );
112
 
113
#
114
#   Determine base image
115
#   Either from dpkg_archive or user image
116
#
117
if ( $opt_image )
118
{
119
    $src_dir =  AbsPath($opt_image);
120
    Error("Image directory is not present: $src_dir") unless ( -d $src_dir );
121
}
122
else
123
{
124
    #
125
    #   Ensure that the package source in dpkg_archive can be found
126
    #
127
 
128
    $src_dir = "$GBE_DPKG/$ARGV[0]/$ARGV[1]";
241 dpurdie 129
    Message ( "Testing $src_dir" );
227 dpurdie 130
    Error ("Package not found: $src_dir" ) unless ( -d $src_dir );
241 dpurdie 131
    Message ("Found source package");
227 dpurdie 132
}
133
 
134
#
135
#   Ensure target directory is not present
136
#
137
$opt_subdir = $ARGV[0] unless ( $opt_subdir );
138
my $temp_dir = "$CWD_DIR/gen_cots";
139
my $dest_dir = "$temp_dir/$opt_subdir";
140
Error ("Temp dest dir already exists: $dest_dir" ) if ( !$opt_delete && -r $dest_dir );
141
 
142
#
143
#   Validate / locate the target VOB
144
#
145
locate_vob();
146
 
147
#
148
#   Generate a label, if the user has not already specified one
149
#
150
$opt_label = "$ARGV[0]_$ARGV[1]"
151
    unless ( $opt_label );
152
 
153
#
154
#   Ensure that the label is not locked
155
#   The user will not be able to move the label if it is already locked
156
#
157
my $label_exists = 0;
158
Verbose ("Check label exists");
159
ClearCmd ("describe -short lbtype:$opt_label@/$vob_name" ) unless $opt_test;
160
$label_exists = 1 unless( $opt_test || grep ( /Label type not found/, @error_list ));
161
Verbose ("Check label: $label_exists");
162
 
163
if ( $label_exists )
164
{
165
    Verbose ("Check label not locked");
166
    ClearCmd ("describe -fmt %[locked]p lbtype:$opt_label@/$vob_name" );
167
    unless ( $last_result && $last_result =~ m~unlocked~ )
168
    {
169
        Error("Label is locked: $opt_label");
170
    }
171
}
172
 
173
#
174
#   Transfer source to target and remove generated files
175
#
176
if ( $opt_delete && -d $temp_dir )
177
{
241 dpurdie 178
    Message ("Delete temp directory");
227 dpurdie 179
    rmtree( $temp_dir );
180
}
181
 
241 dpurdie 182
mkpath ($temp_dir,$opt_verbose);
227 dpurdie 183
Error( "Cannot create directory: $temp_dir") unless( -d $temp_dir);
184
 
241 dpurdie 185
mkpath ($dest_dir,$opt_verbose);
227 dpurdie 186
Error( "Cannot create target directory") unless ( -d $dest_dir);
187
 
241 dpurdie 188
Message ("Transfer package to local directory");
227 dpurdie 189
File::Find::find( \&CopyDir, $src_dir );
190
 
191
 
192
#
193
#   Create a build.pl file based on a template
194
#
241 dpurdie 195
Message ("Create build.pl");
227 dpurdie 196
open (BUILD, ">", "$dest_dir/build.pl" );
197
while ( <DATA> )
198
{
199
    chomp;
200
    last if ( /^__ENDBUILD/ );
201
 
202
    #
203
    #   Substitute values
204
    #
205
    s~__PACKAGENAME__~$ARGV[0]~g;
206
    s~__PACKAGEVERSION__~$ARGV[1]~g;
207
    if ( m/__BUILDNAME__/ )
208
    {
209
        if ( $ARGV[1] =~ m~^\d+\.\d+\.\d+[\s.]+(\w+)$~ )
210
        {
211
            print BUILD "BuildName       ( '$ARGV[0]', '$ARGV[1]' );\n";
212
        }
213
        elsif ( $ARGV[1] =~ m~^(.*)\.+(\D+)$~ )
214
        {
215
            my $ver = $1;
216
            my $prj = $2;
217
            print BUILD "BuildName       ( '$ARGV[0]', '$ver', '$prj', '--RelaxedVersion' );\n";
218
        }
219
        else
220
        {
221
            print BUILD "BuildName       ( '$ARGV[0]', '$ARGV[1]', '--RelaxedVersion' );\n";
222
            print "Buildname: '$ARGV[0]', '$ARGV[1]'\n";
223
        }
224
 
225
        next;
226
    }
227
 
228
    print BUILD "$_\n";
229
}
230
close (BUILD);
231
 
232
#
233
#   Create a makefile.pl based on a template
234
#
241 dpurdie 235
Message ("Create src/makefile.pl");
227 dpurdie 236
mkdir "$dest_dir/src";
237
open (MAKE, ">", "$dest_dir/src/makefile.pl" );
238
while ( <DATA> )
239
{
240
    chomp;
241
    last if ( /^__ENDMAKE/ );
242
 
243
    #
244
    #   Substitute values
245
    #
246
    s~__PACKAGENAME__~$ARGV[0]~g;
247
    s~__PACKAGEVERSION__~$ARGV[1]~g;
248
    if ( /__PACKAGEFILE__/ )
249
    {
250
        unless ( $DESTDIR )
251
        {
252
            foreach my $file ( sort keys %files )
253
            {
254
 
255
                print MAKE "PackageFile ( '*', '../$file', '--StripDir' );\n";
256
            }
257
        } else {
258
            foreach my $file ( sort keys %files )
259
            {
260
 
261
                print MAKE "PackageFile ( '*', '$file' );\n";
262
            }
263
        }
264
        foreach my $subdir ( sort keys %subdirs )
265
        {
266
            print MAKE "PackageFile ( '*', '--DirTree=$subdir' );\n";
267
        }
268
        next;
269
    }
270
    print MAKE "$_\n";
271
}
272
close (MAKE);
273
 
274
 
275
#
276
#   Determine the target directory within the VOB
277
#   This is the source directory tree, with the last element removed
278
#
279
my $target_path = "";
280
if ( $opt_subdir =~ m~/~ )
281
{
282
    $target_path = $opt_subdir;
283
    $target_path =~ s~/[^/]*$~~;
284
    $target_path = "/$target_path";
285
}
286
 
287
#
288
#   Transfer the image into the target VOB
289
#   The clearcase command will adjust the target directory to match the source
290
#
291
 
241 dpurdie 292
Message ("Import to clearcase vob: $opt_vob");
227 dpurdie 293
my $cmd = "clearfsimport.exe -nsetevent -rec -rmname";
241 dpurdie 294
   $cmd .= " -preview" if $opt_test;
295
   $cmd .= " -mklabel $opt_label";
227 dpurdie 296
   $cmd .= " -c \"Package snapshot $ARGV[0]_$ARGV[1]\"";
241 dpurdie 297
   $cmd .= " gen_cots/$opt_subdir $opt_vob$target_path";
227 dpurdie 298
 
299
Verbose($cmd);
300
@error_list = ();
301
open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
302
while (<CMD>)
303
{
304
    #
305
    #   Filter output from the user
306
    #
307
    chomp;
308
    Verbose($_);
309
    push @error_list, $_ if ( m~Error:~ );
310
}
311
close(CMD);
312
if ( @error_list )
313
{
314
    display_error_list();
315
    Error("Problem encountered saving package image");
316
}
317
 
318
#
241 dpurdie 319
#   Apply label to all directories upto the root of the VOB
320
#   The label will have been applied to the TIP
227 dpurdie 321
#
241 dpurdie 322
Verbose ("Label package path");
323
my $lpath = $opt_vob;
324
foreach ( split ('/', $target_path) )
325
{
326
    $lpath = $lpath . '/' . $_;
327
    Verbose ("Label package path: $lpath");
328
    ClearCmd ("mklabel -replace $opt_label $lpath" ) unless $opt_test;
329
    Error ("Program Terminated") if ( @error_list );
330
}
227 dpurdie 331
 
332
#
333
#   Lock the label
334
#
241 dpurdie 335
Message ("Locking label: $opt_label");
227 dpurdie 336
ClearCmd ("lock lbtype:$opt_label\@/$vob_name" ) unless $opt_test;
337
Error ("Program Terminated") if ( @error_list );
338
 
339
#
340
#   Remove the created directory
341
#
342
if ( $opt_keep )
343
{
241 dpurdie 344
    Warning ("KEEP temp directory: $temp_dir");
227 dpurdie 345
}
346
else
347
{
241 dpurdie 348
    Message ("Delete temp directory");
227 dpurdie 349
    rmtree( $temp_dir );
350
}
351
 
352
#
353
#   All done
354
#
241 dpurdie 355
Message ("\n");
356
Message ("Release Manager information");
357
Message ("Package path : /$vob_name/$opt_subdir");
358
Message ("Label        : $opt_label");
227 dpurdie 359
 
360
Warning ("Test Mode: Not changes made to the VOB") if ( $opt_test );
361
exit 0;
362
 
363
 
364
#-------------------------------------------------------------------------------
365
# Function        : CopyDir
366
#
367
# Description     : Find callback function used to copy the archive
368
#
369
# Inputs          :
370
#
371
# Returns         :
372
#
373
sub CopyDir
374
{
375
    my $item = $File::Find::name;
376
    my $base = File::Basename::basename($item);
377
 
378
    #
379
    #   Skip generated files
380
    #
381
    return if ( $base =~ m/^descpkg$/ );
382
    return if ( $base =~ m/^RELEASE_NOTES_/ );
383
    return if ( $base =~ m/^built\./ );
384
 
385
    #
386
    #   Don't process directories
387
    #
388
    return if ( -d $item );
389
 
390
    #
391
    #   Calculate target directory
392
    #
241 dpurdie 393
    my $sdl = length ($src_dir);
394
    my $target = $dest_dir . '/' . $DESTDIR . substr ( $item, $sdl );
227 dpurdie 395
 
396
    #
397
    #   Determinate top level package directories
398
    #
241 dpurdie 399
    my $rootdir = substr ( $item, 1 + $sdl );
227 dpurdie 400
    $rootdir =~ s~/.*~~;
401
 
402
    if ( $rootdir eq $base )
403
    {
404
        $files{$base} = 1;
405
    } else {
406
        $subdirs{$rootdir} = 1;
407
    }
408
 
409
    my $tdir = $target;
410
    $tdir =~ s~/[^/]+$~~;
411
 
412
#    print "================$item, $base, $tdir, $target, $rootdir\n";
413
 
414
    mkpath ($tdir, 0) unless ( -d $tdir );
415
 
416
    Verbose( "Transfer: $target");
417
    File::Copy::copy( "$item", "$target") || Error("Copy Fault: $item, $target");
418
 
419
}
420
 
421
#-------------------------------------------------------------------------------
422
# Function        : locate_vob
423
#
424
# Description     : Locate the target VOB
425
#                   This is a bit tricky as itmakes a few assumptions
426
#                       1) That clearcase dynamic views are mounted through the "o" drive
427
#                          This appears to be a standard(ish) configuration.
428
#
429
#                       2) There must be a dynamic view on the machine that does have the
430
#                          required VOB mounted
431
#
432
#                   Note: Assumes that the user is NOT trying to place the package
433
#                         into a subdir of the VOB.
434
#
435
# Inputs          : None
436
#
437
# Returns         : Global: $opt_vob
438
#
439
 
440
sub locate_vob
441
{
442
    #
443
    #   If the user has specified an absolute path then use the users VOB
444
    #
445
    $opt_vob =~ tr~\\/~/~s;
446
    if ( $opt_vob =~ m~[A-Za-z]\:/~ || $opt_vob =~ m~/~ )
447
    {
448
        Error ("User VOB does not exist: $opt_vob") unless ( -d $opt_vob );
449
 
450
        $opt_vob =~ m~(.*/)(.*)~;
451
        $vob_dir = $1;
452
        $vob_name = $2;
453
        return;
454
    }
455
 
456
    #
457
    #   Scan for a dynamic view
458
    #
241 dpurdie 459
    Message ("Scanning for suitable dynamic view");
227 dpurdie 460
    my @search_list = glob ("O:/*");
461
    my $found_vob;
462
    foreach my $dir ( @search_list )
463
    {
464
        my $test_vob = "$dir/$opt_vob";
465
        Verbose ("Testing vob: $test_vob" );
241 dpurdie 466
        next if ( $dir =~ m~solaris~i );                    # Take the hint
467
        next if ( $dir =~ '/administration_view$' );        # Known read-only VOB
468
 
227 dpurdie 469
        if ( -d $test_vob )
470
        {
471
            $found_vob = $dir;
472
            last;
473
        }
474
    }
475
    Error ("Cannot find a suitable view with the $opt_vob VOB mounted") unless ( $found_vob );
476
 
477
    $vob_dir = $found_vob;
478
    $vob_name = $opt_vob;
479
    $opt_vob = "$vob_dir/$vob_name";
241 dpurdie 480
    Message ("Using VOB: $opt_vob");
227 dpurdie 481
}
482
 
483
 
484
#-------------------------------------------------------------------------------
485
# Function        : ClearCmd
486
#
487
# Description     : Similar to the system command
488
#                   Does allow standard output and standard error to be captured
489
#                   to a log file
490
#
491
#                   Used since I was having problems with calling other programs
492
#                   and control-C. It could hang the terminal session.
493
#
494
# Inputs          :
495
#
496
# Returns         :
497
#
498
sub ClearCmd
499
{
500
    my( $cmd ) = @_;
501
    Verbose2 "cleartool $cmd";
502
 
503
        @error_list = ();
504
        open(CMD, "cleartool $cmd  2>&1 |")    || Error "can't run command: $!";
505
        while (<CMD>)
506
        {
507
            chomp;
508
            $last_result = $_;
509
            Verbose ( "cleartool resp:" . $_);
510
            push @error_list, $_ if ( m~Error:~ );
511
        }
512
        close(CMD);
513
 
514
    Verbose2 "Exit Status: $?";
515
    return $? / 256;
516
}
517
 
518
 
519
 
520
#-------------------------------------------------------------------------------
521
# Function        : display_error_list
522
#
523
# Description     : Display the error list
241 dpurdie 524
#                   The exit process will be handled by the caller
227 dpurdie 525
#
526
# Inputs          :
527
#
528
# Returns         :
529
#
530
sub display_error_list
531
{
532
    foreach ( @error_list )
533
    {
241 dpurdie 534
        ReportError ("$_");
227 dpurdie 535
    }
536
}
537
 
538
 
539
__DATA__
540
# Copyright (C) 1998-2006 ERG Limited, All rights reserved
541
#
542
# Module name   : build.pl
543
# Module type   : Makefile system
544
# Environment(s): n/a
545
#
546
# Description:    build.pl for package __PACKAGENAME__
547
#.........................................................................#
548
 
549
#..     Build system
550
#
551
$MAKELIB_PL     = "$ENV{ GBE_TOOLS }/makelib.pl";
552
$BUILDLIB_PL    = "$ENV{ GBE_TOOLS }/buildlib.pl";
553
 
554
require         "$BUILDLIB_PL";
555
require         "$MAKELIB_PL";
556
 
557
#..     Product configuration
558
#
559
BuildPlatforms   ( 'GENERIC' );
560
 
561
__BUILDNAME__ BuildName       ( '__PACKAGENAME__', '__PACKAGEVERSION__' );
562
BuildInterface  ( 'interface' );
563
 
564
#
565
#   Specify subdirectories to process
566
#
567
BuildSubDir    ( 'src' );
568
 
569
#
570
#   Generate Files
571
BuildDescpkg   ();
572
BuildMake      ();
573
__ENDBUILD
574
# Copyright (C) 1998-2006 ERG Limited, All rights reserved
575
#
576
# Module name   : Makefile.pl
577
# Module type   : Makefile system
578
# Compiler(s)   : ANSI C
579
# Environment(s): n/a
580
#
581
# Description:    makefile.pl for package __PACKAGENAME__
582
#
583
#.........................................................................#
584
 
585
die "Usage: Makefile.pl rootdir Makelib.pl\n"
586
    unless( $#ARGV+1 >= 2 );
587
require "$ARGV[1]";
588
 
589
#
590
# Build platform definitions ..
591
#
592
Platform( '*' );
593
 
594
############################################################################
595
#   Define the source files
596
#
597
 
598
#.............................................................................
599
# Packaging definitions
600
#
601
__PACKAGEFILE__ PackageFile ( '*', '--DirTree=jar' );
602
 
603
#..
604
#
605
Src         ( '*'   , 'descpkg' );
606
PackageFile ( '*'   , 'descpkg' );
607
 
608
#.............................................................................
609
# Finally generate the makefile
610
#
611
MakefileGenerate();
612
 
613
#..  Successful termination
614
1;
615
__ENDMAKE
616
 
617
#-------------------------------------------------------------------------------
618
#   Documentation
619
#
620
 
621
=pod
622
 
623
=head1 NAME
624
 
625
gen_cots - Create a buildable package from dpkg_archive and place it under
626
version control
627
 
628
=head1 SYNOPSIS
629
 
630
jats gen_cots package version
631
 
632
 
633
 Options:
634
    -help              - brief help message
635
    -help -help        - Detailed help message
636
    -man               - Full documentation
637
    -label=name        - Specify a label for the versions source
638
    -vob=vvv           - VOB to use, my be a full path. default is COTS
639
    -subdir=nnn        - Named subdir in VOB
640
    -test              - Do not perform any clearcase operations
641
    -keep              - Keep the creating dpkg_archive image
642
    -delete            - Unconditional delete the temp directory before use
643
    -image=path        - Path to alternate source image
644
 
645
=head1 OPTIONS
646
 
647
=over 8
648
 
649
=item B<-help>
650
 
651
Print a brief help message and exits.
652
 
653
=item B<-help -help>
654
 
655
Print a detailed help message with an explanation for each option.
656
 
657
=item B<-man>
658
 
659
Prints the manual page and exits.
660
 
661
=item B<-label=name>
662
 
663
This option specifies an alternate label for the checked in source. The
664
default label is based on package and version.
665
 
666
=item B<-vob=vvv>
667
 
668
This option specifies the VOB into which the saved package will be placed.
669
 
670
There are two ways that this option may be used.
671
 
672
=over 8
673
 
674
=item 1
675
 
676
Simply name the VOB. (ie: COTS) The script will locate a dynamic view on the
677
users machine that contains the view. This is done by scanning dynic views in
678
the "O:" drive.
679
 
680
=item 2
681
 
682
The full path to a VOB, including driver is provided. (ie: z:/COTS). This will
683
prevent the script from locating the VOB. It will use the named view.
684
 
685
=back
686
 
687
If this option is not provided, then the script will use the COTS vob in the
688
first dynamic view located on the "O:" drive.
689
 
690
=item B<-subdir=name>
691
 
692
This option specifies the name of a subdirectory in which the package will be created.
693
The default name it taken from the package name.
694
 
695
=item B<-test>
696
 
697
This option will suppress the clearcase operations.
698
No files will be checked in and the label will not be locked.
699
 
700
=item B<-keep>
701
 
702
If this option is selected then the program will retain the working directory
703
that it has created.
704
 
705
=item B<-delete>
706
 
707
If this option is selected then the temp work directory will be deleted before
708
the script attempts to use it.
709
 
710
 
711
=item B<-image=path>
712
 
713
If this option is specified then the package will be created using the
714
specified source path, otherwise the package will be extracted from dpkg_acrhive.
715
 
716
This option allows a locally created image to be stored as a COTS package
717
before it is placed in dpkg_archive.
718
 
719
=back
720
 
721
=head1 DESCRIPTION
722
 
723
This program will create a version controlled and JATS buildable package from
724
a dpkg_archive package version.
725
 
726
In doing this the program will:
727
 
728
=over 8
729
 
730
=item   *
731
 
732
Create a temporary directory in the users current directory. This will
733
be used to contain a copy of the package.
734
 
735
=item   *
736
 
737
Transfer the named package and version into the temp directory. The files will
738
be transferred in the a 'src' directory within the temp directory.
739
 
740
=item   *
741
 
742
Create JATS build.pl and makefile.pls to support the creation of the
743
package. The build.pl file will contain the package name and the package
744
version.
745
 
746
=item   *
747
 
748
Transfer the entire image into the named VOB. The files will be labeled
749
and the VOB view modified to mimic the temp directory view.
750
 
751
 
752
=item   *
753
 
754
Lock the label used to mark the files.
755
 
756
=item   *
757
 
758
Remove the temp work space.
759
 
760
=item   *
761
 
762
Display information to be entered into Release Manager.
763
 
764
=back
765
 
766
=head1 EXAMPLE
767
 
768
jats etool gen_cots -vob=z:/COTS mos_api 5.6.0.cr
769
 
770
This will take the version 5.6.0.cr of the mos_api package from dpkg_acrchive
771
place it under version control within the COTS vob and add files to allow the
772
dpkg_archive package to be recreated in an JATS buildable manner.
773
 
774
 
775
=cut
776