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]";
129
    print "Testing $src_dir\n";
130
    Error ("Package not found: $src_dir" ) unless ( -d $src_dir );
131
    print "Found source package\n";
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
{
178
    print "Delete temp directory\n";
179
    rmtree( $temp_dir );
180
}
181
 
182
mkpath ($temp_dir,1);
183
Error( "Cannot create directory: $temp_dir") unless( -d $temp_dir);
184
 
185
mkpath ($dest_dir,1);
186
Error( "Cannot create target directory") unless ( -d $dest_dir);
187
 
188
print "Transfer package to local directory\n";
189
File::Find::find( \&CopyDir, $src_dir );
190
 
191
 
192
#
193
#   Create a build.pl file based on a template
194
#
195
print "Create build.pl\n";
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
#
235
print "Create src/makefile.pl\n";
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
 
292
print "Import to clearcase vob: $opt_vob\n";
293
my $cmd = "clearfsimport.exe -nsetevent -rec -rmname";
294
   $cmd .= " -preview " if $opt_test;
295
   $cmd .= " -mklabel $opt_label ";
296
   $cmd .= " -c \"Package snapshot $ARGV[0]_$ARGV[1]\"";
297
   $cmd .= " gen_cots/$opt_subdir $opt_vob$target_path\n";
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
#
319
#   Massage the vob name and remove the drive letter
320
#
321
$opt_vob =~ s~^[A-Za-z]:[\\/]~/~;
322
$opt_vob = '/' . $opt_vob;
323
$opt_vob =~ tr~\\/~/~s;
324
 
325
#
326
#   Lock the label
327
#
328
print "Locking label: $opt_label\n";
329
ClearCmd ("lock lbtype:$opt_label\@/$vob_name" ) unless $opt_test;
330
Error ("Program Terminated") if ( @error_list );
331
 
332
#
333
#   Remove the created directory
334
#
335
if ( $opt_keep )
336
{
337
    print "KEEP temp directory: $temp_dir\n";
338
}
339
else
340
{
341
    print "Delete temp directory\n";
342
    rmtree( $temp_dir );
343
}
344
 
345
#
346
#   All done
347
#
348
print "\n";
349
print "Release Manager information\n";
350
print "Package path : /$vob_name/$ARGV[0] \n";
351
print "Label        : $opt_label\n";
352
 
353
Warning ("Test Mode: Not changes made to the VOB") if ( $opt_test );
354
exit 0;
355
 
356
 
357
#-------------------------------------------------------------------------------
358
# Function        : CopyDir
359
#
360
# Description     : Find callback function used to copy the archive
361
#
362
# Inputs          :
363
#
364
# Returns         :
365
#
366
sub CopyDir
367
{
368
    my $item = $File::Find::name;
369
    my $base = File::Basename::basename($item);
370
 
371
    #
372
    #   Skip generated files
373
    #
374
    return if ( $base =~ m/^descpkg$/ );
375
    return if ( $base =~ m/^RELEASE_NOTES_/ );
376
    return if ( $base =~ m/^built\./ );
377
 
378
    #
379
    #   Don't process directories
380
    #
381
    return if ( -d $item );
382
 
383
    #
384
    #   Calculate target directory
385
    #
386
    my $target = $item;
387
    $target =~ s~^$src_dir~$dest_dir/$DESTDIR~;
388
 
389
    #
390
    #   Determinate top level package directories
391
    #
392
    my $rootdir = $item;
393
    $rootdir =~ s~^$src_dir/~~;
394
    $rootdir =~ s~/.*~~;
395
 
396
    if ( $rootdir eq $base )
397
    {
398
        $files{$base} = 1;
399
    } else {
400
        $subdirs{$rootdir} = 1;
401
    }
402
 
403
    my $tdir = $target;
404
    $tdir =~ s~/[^/]+$~~;
405
 
406
#    print "================$item, $base, $tdir, $target, $rootdir\n";
407
 
408
    mkpath ($tdir, 0) unless ( -d $tdir );
409
 
410
    Verbose( "Transfer: $target");
411
    File::Copy::copy( "$item", "$target") || Error("Copy Fault: $item, $target");
412
 
413
}
414
 
415
#-------------------------------------------------------------------------------
416
# Function        : locate_vob
417
#
418
# Description     : Locate the target VOB
419
#                   This is a bit tricky as itmakes a few assumptions
420
#                       1) That clearcase dynamic views are mounted through the "o" drive
421
#                          This appears to be a standard(ish) configuration.
422
#
423
#                       2) There must be a dynamic view on the machine that does have the
424
#                          required VOB mounted
425
#
426
#                   Note: Assumes that the user is NOT trying to place the package
427
#                         into a subdir of the VOB.
428
#
429
# Inputs          : None
430
#
431
# Returns         : Global: $opt_vob
432
#
433
 
434
sub locate_vob
435
{
436
    #
437
    #   If the user has specified an absolute path then use the users VOB
438
    #
439
    $opt_vob =~ tr~\\/~/~s;
440
    if ( $opt_vob =~ m~[A-Za-z]\:/~ || $opt_vob =~ m~/~ )
441
    {
442
        Error ("User VOB does not exist: $opt_vob") unless ( -d $opt_vob );
443
 
444
        $opt_vob =~ m~(.*/)(.*)~;
445
        $vob_dir = $1;
446
        $vob_name = $2;
447
        return;
448
    }
449
 
450
    #
451
    #   Scan for a dynamic view
452
    #
453
    print "Scanning for suitable dynamic view\n";
454
    my @search_list = glob ("O:/*");
455
    my $found_vob;
456
    foreach my $dir ( @search_list )
457
    {
458
        my $test_vob = "$dir/$opt_vob";
459
        Verbose ("Testing vob: $test_vob" );
460
        next if ( $dir =~ m~solaris~i );
461
        if ( -d $test_vob )
462
        {
463
            $found_vob = $dir;
464
            last;
465
        }
466
    }
467
    Error ("Cannot find a suitable view with the $opt_vob VOB mounted") unless ( $found_vob );
468
 
469
    $vob_dir = $found_vob;
470
    $vob_name = $opt_vob;
471
    $opt_vob = "$vob_dir/$vob_name";
472
    print "Using VOB: $opt_vob\n";
473
}
474
 
475
 
476
#-------------------------------------------------------------------------------
477
# Function        : ClearCmd
478
#
479
# Description     : Similar to the system command
480
#                   Does allow standard output and standard error to be captured
481
#                   to a log file
482
#
483
#                   Used since I was having problems with calling other programs
484
#                   and control-C. It could hang the terminal session.
485
#
486
# Inputs          :
487
#
488
# Returns         :
489
#
490
sub ClearCmd
491
{
492
    my( $cmd ) = @_;
493
    Verbose2 "cleartool $cmd";
494
 
495
        @error_list = ();
496
        open(CMD, "cleartool $cmd  2>&1 |")    || Error "can't run command: $!";
497
        while (<CMD>)
498
        {
499
            chomp;
500
            $last_result = $_;
501
            Verbose ( "cleartool resp:" . $_);
502
            push @error_list, $_ if ( m~Error:~ );
503
        }
504
        close(CMD);
505
 
506
    Verbose2 "Exit Status: $?";
507
    return $? / 256;
508
}
509
 
510
 
511
 
512
#-------------------------------------------------------------------------------
513
# Function        : display_error_list
514
#
515
# Description     : Display the error list
516
#                   This function is registered as an Error callback function
517
#                   it will be called on error exit
518
#
519
# Inputs          :
520
#
521
# Returns         :
522
#
523
sub display_error_list
524
{
525
    foreach ( @error_list )
526
    {
527
        print "$_\n";
528
    }
529
}
530
 
531
 
532
__DATA__
533
# Copyright (C) 1998-2006 ERG Limited, All rights reserved
534
#
535
# Module name   : build.pl
536
# Module type   : Makefile system
537
# Environment(s): n/a
538
#
539
# Description:    build.pl for package __PACKAGENAME__
540
#.........................................................................#
541
 
542
#..     Build system
543
#
544
$MAKELIB_PL     = "$ENV{ GBE_TOOLS }/makelib.pl";
545
$BUILDLIB_PL    = "$ENV{ GBE_TOOLS }/buildlib.pl";
546
 
547
require         "$BUILDLIB_PL";
548
require         "$MAKELIB_PL";
549
 
550
#..     Product configuration
551
#
552
BuildPlatforms   ( 'GENERIC' );
553
 
554
__BUILDNAME__ BuildName       ( '__PACKAGENAME__', '__PACKAGEVERSION__' );
555
BuildInterface  ( 'interface' );
556
 
557
#
558
#   Specify subdirectories to process
559
#
560
BuildSubDir    ( 'src' );
561
 
562
#
563
#   Generate Files
564
BuildDescpkg   ();
565
BuildMake      ();
566
__ENDBUILD
567
# Copyright (C) 1998-2006 ERG Limited, All rights reserved
568
#
569
# Module name   : Makefile.pl
570
# Module type   : Makefile system
571
# Compiler(s)   : ANSI C
572
# Environment(s): n/a
573
#
574
# Description:    makefile.pl for package __PACKAGENAME__
575
#
576
#.........................................................................#
577
 
578
die "Usage: Makefile.pl rootdir Makelib.pl\n"
579
    unless( $#ARGV+1 >= 2 );
580
require "$ARGV[1]";
581
 
582
#
583
# Build platform definitions ..
584
#
585
Platform( '*' );
586
 
587
############################################################################
588
#   Define the source files
589
#
590
 
591
#.............................................................................
592
# Packaging definitions
593
#
594
__PACKAGEFILE__ PackageFile ( '*', '--DirTree=jar' );
595
 
596
#..
597
#
598
Src         ( '*'   , 'descpkg' );
599
PackageFile ( '*'   , 'descpkg' );
600
 
601
#.............................................................................
602
# Finally generate the makefile
603
#
604
MakefileGenerate();
605
 
606
#..  Successful termination
607
1;
608
__ENDMAKE
609
 
610
#-------------------------------------------------------------------------------
611
#   Documentation
612
#
613
 
614
=pod
615
 
616
=head1 NAME
617
 
618
gen_cots - Create a buildable package from dpkg_archive and place it under
619
version control
620
 
621
=head1 SYNOPSIS
622
 
623
jats gen_cots package version
624
 
625
 
626
 Options:
627
    -help              - brief help message
628
    -help -help        - Detailed help message
629
    -man               - Full documentation
630
    -label=name        - Specify a label for the versions source
631
    -vob=vvv           - VOB to use, my be a full path. default is COTS
632
    -subdir=nnn        - Named subdir in VOB
633
    -test              - Do not perform any clearcase operations
634
    -keep              - Keep the creating dpkg_archive image
635
    -delete            - Unconditional delete the temp directory before use
636
    -image=path        - Path to alternate source image
637
 
638
=head1 OPTIONS
639
 
640
=over 8
641
 
642
=item B<-help>
643
 
644
Print a brief help message and exits.
645
 
646
=item B<-help -help>
647
 
648
Print a detailed help message with an explanation for each option.
649
 
650
=item B<-man>
651
 
652
Prints the manual page and exits.
653
 
654
=item B<-label=name>
655
 
656
This option specifies an alternate label for the checked in source. The
657
default label is based on package and version.
658
 
659
=item B<-vob=vvv>
660
 
661
This option specifies the VOB into which the saved package will be placed.
662
 
663
There are two ways that this option may be used.
664
 
665
=over 8
666
 
667
=item 1
668
 
669
Simply name the VOB. (ie: COTS) The script will locate a dynamic view on the
670
users machine that contains the view. This is done by scanning dynic views in
671
the "O:" drive.
672
 
673
=item 2
674
 
675
The full path to a VOB, including driver is provided. (ie: z:/COTS). This will
676
prevent the script from locating the VOB. It will use the named view.
677
 
678
=back
679
 
680
If this option is not provided, then the script will use the COTS vob in the
681
first dynamic view located on the "O:" drive.
682
 
683
=item B<-subdir=name>
684
 
685
This option specifies the name of a subdirectory in which the package will be created.
686
The default name it taken from the package name.
687
 
688
=item B<-test>
689
 
690
This option will suppress the clearcase operations.
691
No files will be checked in and the label will not be locked.
692
 
693
=item B<-keep>
694
 
695
If this option is selected then the program will retain the working directory
696
that it has created.
697
 
698
=item B<-delete>
699
 
700
If this option is selected then the temp work directory will be deleted before
701
the script attempts to use it.
702
 
703
 
704
=item B<-image=path>
705
 
706
If this option is specified then the package will be created using the
707
specified source path, otherwise the package will be extracted from dpkg_acrhive.
708
 
709
This option allows a locally created image to be stored as a COTS package
710
before it is placed in dpkg_archive.
711
 
712
=back
713
 
714
=head1 DESCRIPTION
715
 
716
This program will create a version controlled and JATS buildable package from
717
a dpkg_archive package version.
718
 
719
In doing this the program will:
720
 
721
=over 8
722
 
723
=item   *
724
 
725
Create a temporary directory in the users current directory. This will
726
be used to contain a copy of the package.
727
 
728
=item   *
729
 
730
Transfer the named package and version into the temp directory. The files will
731
be transferred in the a 'src' directory within the temp directory.
732
 
733
=item   *
734
 
735
Create JATS build.pl and makefile.pls to support the creation of the
736
package. The build.pl file will contain the package name and the package
737
version.
738
 
739
=item   *
740
 
741
Transfer the entire image into the named VOB. The files will be labeled
742
and the VOB view modified to mimic the temp directory view.
743
 
744
 
745
=item   *
746
 
747
Lock the label used to mark the files.
748
 
749
=item   *
750
 
751
Remove the temp work space.
752
 
753
=item   *
754
 
755
Display information to be entered into Release Manager.
756
 
757
=back
758
 
759
=head1 EXAMPLE
760
 
761
jats etool gen_cots -vob=z:/COTS mos_api 5.6.0.cr
762
 
763
This will take the version 5.6.0.cr of the mos_api package from dpkg_acrchive
764
place it under version control within the COTS vob and add files to allow the
765
dpkg_archive package to be recreated in an JATS buildable manner.
766
 
767
 
768
=cut
769