Subversion Repositories DevTools

Rev

Rev 1454 | Rev 2029 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
267 dpurdie 1
########################################################################
1348 dpurdie 2
# Copyright (C) 1998-2012 Vix Technology, All rights reserved
267 dpurdie 3
#
4
# Module name   : jats_svnrelease.pl
5
# Module type   : Jats Utility
6
# Compiler(s)   : Perl
7
# Environment(s): Jats
8
#
9
# Description   : A script to build a package from a SubVersion
10
#                 The script will:
11
#                   Create a workspace
12
#                   Checkout the files
13
#                   Locate the build file
14
#                   Build the packages
15
#                   Install packages
16
#                   Remove the view
17
#
18
#               The script can do a lot of other things too.
19
#
20
# Notes         : A lot of this code is common to jats_ccrelease.pl
21
#                 Will need to refactor if both are to be used
22
#
23
#......................................................................#
24
 
25
require 5.006_001;
26
use strict;
27
use warnings;
28
use JatsError;
29
use JatsSystem;
30
use FileUtils;
31
use JatsBuildFiles;
32
use ArrayHashUtils;
33
use JatsSvn;
34
 
35
use Pod::Usage;                             # required for help support
36
use Getopt::Long;
37
use File::Find;
38
use File::Copy;
39
use File::Path;
40
use Cwd;
41
 
42
my $VERSION = "1.0.0";                      # Update this
43
 
44
#
45
#   Options
46
#
47
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
48
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
49
my $opt_help = 0;                           # User help level
50
my @opt_spec;                               # Labels used as a base for the view
51
my $opt_dpkg = 1;                           # Transfer built package to dpkg_archive
52
my $opt_copy = 0;                           # Copy built package to user
53
my $opt_reuse = 0;                          # Re-user view if it exists
54
my $opt_viewname;                           # View Name
1348 dpurdie 55
my $opt_extract = 0;                        # Just create a static view
267 dpurdie 56
my $opt_extract_files;                      # Just extract files to user - no view
1348 dpurdie 57
my $opt_devModeStr;                         # Development mode string
58
my $opt_devMode = '';                       # Development mode (cleaned up)
267 dpurdie 59
my $opt_delete = 0;                         # Just delete the view. 2 to force
60
my @opt_build;                              # build files to use (kludge)
61
my $opt_test;                               # Test the build process - no copy
62
my $opt_cache;                              # Cache external packages
63
my $opt_keep = 0;                           # Keep view if successful
64
my $opt_beta;                               # Create beta release
65
my $opt_merge;                              # Merge release
66
my $opt_path;                               # Path for view spec
67
my $opt_runtests = 1;                       # Run unit tests after build
68
my $opt_branch;                             # Create config spec with branch
69
my $opt_debug_build = 0;                    # Build Debug Only
70
my $opt_prod_build = 0;                     # Build ion Only
71
my $opt_view_root = $ENV{'GBE_VIEWBASE'};   # Root of the view
72
my $opt_prefix = 1;                         # Prefix the view tag with user-name
351 dpurdie 73
my $opt_tag;                                # View tag insert (build or export or user)
341 dpurdie 74
my $bad_label_name = 0;                     # Badly formed label
267 dpurdie 75
 
76
#
77
#   Globals - Provided by the JATS environment
78
#
79
my $USER            = $ENV{'USER'};
80
my $UNIX            = $ENV{'GBE_UNIX'};
81
my $GBE_SANDBOX     = $ENV{'GBE_SANDBOX'};
82
my $GBE_ABT         = $ENV{'GBE_ABT'} || '0';
279 dpurdie 83
my $MACHINENAME     = $ENV{'GBE_HOSTNAME'};
343 dpurdie 84
my $GBE_VIEWBASE    = $ENV{'GBE_VIEWBASE'};   # Root of the view
267 dpurdie 85
 
86
#
87
#   Globals
88
#
343 dpurdie 89
my $VIEWDIR_ROOT;                           # Root of the static view
267 dpurdie 90
my $VIEWDIR;                                # Absolute path to the view
91
my $VIEWPATH;                               # Path relative to clearcase
1348 dpurdie 92
my $view_prefix     = "${USER}_";           # Default WorkSpace prefix
93
my $user_cwd;                               # Initial User Directory
94
my $error = 0;                              # Build Error Flag/Counter
267 dpurdie 95
my $label_count = 0;                        # Number of labels to create the view
96
my @label_not_pegged;                       # List of unpegged labels
1348 dpurdie 97
my @messageText;                            # Messages to be displayed AFTER extraction
98
my $workSpace;                              # Path to created workspace (or extact)
99
my $svnSession;                             # Primary Subversion Session
1356 dpurdie 100
my $noReleaseWs = 0;                        # Do not officially release from this
1348 dpurdie 101
my $checkDelta = 1;                         # Check Diffs between Tag and Head
102
                                            #   0 - Don't do anything
103
                                            #   1 - Warn about diffs
104
                                            #   2 - Error if diffs
1357 dpurdie 105
my $traceBack = 2;                          # Trace Back error control. As above
267 dpurdie 106
 
1348 dpurdie 107
#
108
#   Data about the package-version
109
#
110
my $srcPathPkg;                             # Root of the package
111
my $devBranch;                              # Development Branch - within the package
112
my $devBranchPeg;                           # May be pegged
113
my $devBranchHead;                          # Revision of the HEAD of the development branch
114
my $tagLabel;                               # Label in 'tags'
115
my $tagPeg;                                 # May be pegged
116
my $tagLabelBranch;                         # Tagged from this branch: Discovered
117
my $tagLabelBranchPeg;                      # Tagged from this branch at this peg: Discovered
118
my $ttbType;                                # trunk, tags or branches
119
my $urlType;                                # 'jats' or 'url'
120
my $initialUrl;                             # Initial URL of target
267 dpurdie 121
 
122
#-------------------------------------------------------------------------------
123
# Function        : Mainline Entry Point
124
#
1348 dpurdie 125
# Description     : Main entry point
267 dpurdie 126
#
1348 dpurdie 127
# Inputs          : ARGV[]      - See documentation below
267 dpurdie 128
#
129
 
130
#
131
#   Alter some option defaults if we are creating a view within a sandbox
132
#
133
if ( $GBE_SANDBOX )
134
{
343 dpurdie 135
   $GBE_VIEWBASE = $GBE_SANDBOX;
267 dpurdie 136
   $opt_prefix = 0;
137
}
138
 
139
#
140
#   Parse the user options
141
#
142
my $result = GetOptions (
1348 dpurdie 143
                'help:+'        => \$opt_help,                  # flag, multiple use allowed
144
                'manual:3'      => \$opt_help,                  # flag
145
                'v|verbose:+'   => \$opt_verbose,               # flag, multiple use allowed
146
                'label=s'       => \@opt_spec,                  # Array of build specs
147
                'view=s'        => \$opt_viewname,              # String
148
                'dpkg!'         => \$opt_dpkg,                  # [no]flag
149
                'copy!'         => \$opt_copy,                  # [no]flag
150
                'reuse!'        => \$opt_reuse,                 # [no]flag
151
                'extract:+'     => \$opt_extract,               # flag
152
                'extractfiles'  => \$opt_extract_files,         # flag
153
                'delete:+'      => \$opt_delete,                # flag
154
                'build=s'       => \@opt_build,                 # An array of build
155
                'test!'         => \$opt_test,                  # [no]flag
156
                'cache'         => \$opt_cache,                 # flag
157
                'keep!'         => \$opt_keep,                  # [no]flag
158
                'beta!'         => \$opt_beta,                  # [no]flag
159
                'merge'         => \$opt_merge,                 # [no]flag
160
                'path=s'        => \$opt_path,                  # string
161
                'runtests!'     => \$opt_runtests,              # [no]flag
162
                'branch=s'      => \$opt_branch,                # String
163
                'mkbranch=s'    => \$opt_branch,                # String
164
                'prodOnly'      => \$opt_prod_build,            # flag
165
                'debugOnly'     => \$opt_debug_build,           # flag
166
                'root=s'        => \$GBE_VIEWBASE,              # string
167
                'prefix!'       => \$opt_prefix,                # flag
168
                'tag=s'         => \$opt_tag,                   # string
169
                'devMode=s'     => \$opt_devModeStr,            # string
267 dpurdie 170
                );
171
 
172
                #
173
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
174
                #
175
 
176
#
177
#   Process help and manual options
178
#
179
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
180
pod2usage(-verbose => 1)  if ($opt_help == 2 );
181
pod2usage(-verbose => 2)  if ($opt_help > 2 );
182
 
183
InitFileUtils();
184
#
185
#   Configure the error reporting process now that we have the user options
186
#
187
ErrorConfig( 'name'    => 'SVNRELEASE',
188
             'verbose' => $opt_verbose );
189
 
190
#
191
#   Validate user options
192
#   Use either -label or one command line argument
193
#
1348 dpurdie 194
Error ("Cannot mix -extractfiles and -branch")
195
    if ( $opt_branch && $opt_extract_files );
267 dpurdie 196
Error ("Unexpected command line arguments present.","Cannot mix -label and command line label" )
197
    if ( $#opt_spec >= 0 && $#ARGV >= 0);
198
 
199
push @opt_spec, @ARGV;
200
 
201
unless(  @opt_spec  )
202
{
1348 dpurdie 203
    Error ("Need a workspace or a label. -help for options") if ( $opt_delete  && ! $opt_viewname );
204
    Error ("Need a Subversion Reference or URL. -help for options") unless $opt_delete;
267 dpurdie 205
}
206
 
1348 dpurdie 207
#   Determine extraction mode
208
#       Working- Default
209
#               Extract point on development branch were tag was taken
210
#               Update build files
211
#               Warn about files that have changed
267 dpurdie 212
#
1348 dpurdie 213
#       Tag   - Extract point on development branch were tag was taken
214
#               Update build files
215
#               Error if tag is not the tip
267 dpurdie 216
#
1348 dpurdie 217
#       Tip   - Extact tip of the development branch
218
#               Warn about files that have changed between head and tagPoint
219
#
220
#       Exact - What the user specified
221
#               May be a tag and thus not usable
222
#
223
if ( $opt_devModeStr )
267 dpurdie 224
{
1348 dpurdie 225
    if ( $opt_devModeStr =~ m/^(Tip)|(BranchTip)$/i) {
226
        $opt_devMode = 'tip';
227
        $checkDelta = 1;
1356 dpurdie 228
        $noReleaseWs = 1;
1348 dpurdie 229
    } elsif ( $opt_devModeStr =~ m/^(Tag)|(TagPoint)$/i) {
230
        $opt_devMode = 'tag';
231
        $checkDelta = 2;
232
        $checkDelta = 1 if ( $opt_branch );
233
        $noReleaseWs = 0;
234
    } elsif ( $opt_devModeStr =~ m/^(Work)|(Working)$/i) {
235
        $opt_devMode = '';
236
        $checkDelta = 1;
1356 dpurdie 237
        $noReleaseWs = 0;
1348 dpurdie 238
    } elsif ( $opt_devModeStr =~ m/^Exact$/i) {
239
        $opt_devMode = 'exact';
240
        $checkDelta = 1;
241
        $noReleaseWs = 0;
1360 dpurdie 242
        Error ('Cannot mix -branch and -devMode=' . $opt_devModeStr ) if ( $opt_branch );
243
    } elsif ( $opt_devModeStr =~ m/^escrow$/i) {
244
        # JATS internal use only. Not advertised
1357 dpurdie 245
        $opt_devMode = 'exact';
246
        $checkDelta = 0;
247
        $noReleaseWs = 0;
248
        $traceBack = 1;
1360 dpurdie 249
        Error ('Cannot mix -branch and -devMode=' . $opt_devModeStr ) if ( $opt_branch );
1348 dpurdie 250
    } else {
251
        Error ("Unknown development mode: $opt_devModeStr");
252
    }
267 dpurdie 253
}
254
 
255
#
1348 dpurdie 256
#   The buildtool works in a known environment
257
#
258
if ( $GBE_ABT )
259
{
1360 dpurdie 260
    $noReleaseWs = 0;       # Can always release
261
    $checkDelta = 0;        # Do not care. Often expected to have changes.
262
    $traceBack = 2;         # Must check traceback. Validate RM data
1348 dpurdie 263
}
264
 
265
#
267 dpurdie 266
#   Limit the user to ONE label/tag/
267
#   Reason: Under Subversion its not possible to 'pinch' files from another
268
#           package. Don't need to create a workspace with multiple labels
269
#
270
#           It was a bad practice under clearcase
271
#
272
if ( $#opt_spec >= 1 )
273
{
274
    Error ("Multiple labels not supported",
275
           "Use one label to describe a package" );
276
}
1348 dpurdie 277
parseSubversionRef($opt_spec[0]);
278
Error ("INTERNAL: initialUrl not set") unless ( $initialUrl );
279
Error ("Cannot interprete the URL or Subversion Reference: $opt_spec[0]") unless ( $srcPathPkg  );
267 dpurdie 280
 
281
#
1348 dpurdie 282
#   Check branch name
383 dpurdie 283
#
284
if ( $opt_branch )
285
{
286
    $opt_branch = SvnIsaSimpleLabel($opt_branch);
287
}
288
 
289
#
267 dpurdie 290
#   User has specified both debug and production
291
#   Then set both to 0 : ie default
292
#
293
if ( $opt_debug_build + $opt_prod_build > 1 )
294
{
295
    $opt_debug_build = 0;
296
    $opt_prod_build = 0;
297
}
298
 
299
#
300
#   User has requested test mode
301
#       - Don't copy
1348 dpurdie 302
#       - Don't package
267 dpurdie 303
#
304
if ( $opt_test )
305
{
306
    $opt_dpkg = 0;
307
    $opt_copy = 0;
308
}
309
 
310
#
311
#   Determine the machine type
312
#
313
Verbose ("Machine Type: UNIX=$UNIX");
314
 
315
Error ("Machine Name not determined")
316
    unless ( $MACHINENAME );
317
$user_cwd = getcwd;
318
 
319
Error ("USER name not determined" )
320
    unless ( $USER );
321
 
322
#
343 dpurdie 323
#   Clean up the view root directory
267 dpurdie 324
#
343 dpurdie 325
$VIEWDIR_ROOT = Realpath($GBE_VIEWBASE) || $GBE_VIEWBASE;
267 dpurdie 326
 
327
Verbose ("Viewpath: $VIEWDIR_ROOT");
328
Error ("Cannot locate view root directory: $VIEWDIR_ROOT" ) unless (-d $VIEWDIR_ROOT);
329
 
330
#
331
#   Remove any user name from the front of the view name
332
#   Simplifies the deletion process as the user can provide
333
#   the directory name
334
#
1348 dpurdie 335
$view_prefix = '' unless ( $opt_prefix );
267 dpurdie 336
 
337
#
338
#   Create a class to describe the complete SVN label
1348 dpurdie 339
#   This will parse the label and create a number of nice elements that will
340
#   be used in determing the name of the workspace
267 dpurdie 341
#
1348 dpurdie 342
$svnSession = NewSessionByUrl ( $initialUrl, 1 );
343
#DebugDumpData("New Session", $svnSession );
267 dpurdie 344
 
345
#
1348 dpurdie 346
#   Test for a pegged label
347
#
348
push @label_not_pegged, $svnSession->Full
349
    unless ( $svnSession->Peg );
350
 
351
#
267 dpurdie 352
#   Setup user specified workspace
353
#   Include the user name to ensure that the view name is unique-ish
354
#   Keep the name as short as possible as some compilers display a fixed
355
#   length filename in error messages and this name is part of the path
356
#
357
#   Base the viewname on the view label. This will simplify the creation
358
#   of multiple views and reduce the risk of unexpected deletion
359
#
1454 dpurdie 360
$opt_viewname = calcViewName();
267 dpurdie 361
$opt_viewname =~ s~^$view_prefix~~ if (defined($opt_viewname) && $view_prefix && $opt_delete );
362
 
363
#
364
#   Create a clearcase view to be used for the view
365
#
366
$VIEWPATH = "$view_prefix$opt_viewname";
367
$VIEWDIR = "$VIEWDIR_ROOT/$VIEWPATH";
299 dpurdie 368
$VIEWDIR =~ tr~\\/~/~s;
267 dpurdie 369
Verbose( "Hostname: $MACHINENAME" );
370
Verbose( "Viewpath: $VIEWPATH" );
371
Verbose( "Viewdir : $VIEWDIR" );
372
 
373
#
374
#   If the user has specified a "source path", then we must ensure that it is
375
#   valid. It will be used to create the WorkSpace
376
#
377
#   Ensure that the path is a defined variable. If used prepend a / to simplify
378
#   concatenation.
379
#
380
Verbose("Validate Source Path");
381
if ( $opt_path )
382
{
383
    $opt_path =~ tr~\\/~/~s;
384
    $opt_path =~ s~/$~~;
385
    $opt_path =~ s~^/~~;
386
 
387
    Error( "Source Path has drive specifier" ) if ( $opt_path =~ m~^[A-Za-z]\:~ );
388
    $opt_path = '/'.$opt_path ;
389
}
390
else
391
{
392
    $opt_path = '';
393
}
1348 dpurdie 394
$workSpace = $VIEWDIR . $opt_path;
395
Verbose( "workSpace : $workSpace" );
267 dpurdie 396
 
397
#
398
#   If the view currently exists then it will be deleted if allowed
399
#
400
delete_view()
299 dpurdie 401
    unless ( $opt_reuse );
267 dpurdie 402
 
403
#
404
#   If the user is simply deleting the view then all has been done
405
#
406
exit 0
407
    if ( $opt_delete );
408
 
409
#
1348 dpurdie 410
#   Ensure that the label is present within the specified Repository
267 dpurdie 411
#
412
Verbose("Ensure Labels can be found in a Repository");
1348 dpurdie 413
Verbose ("Testing label: ". $svnSession->Full );
267 dpurdie 414
$label_count++;
415
 
1348 dpurdie 416
$svnSession->SvnValidateTarget (
267 dpurdie 417
                    'cmd'    => 'SvnRelease',
1348 dpurdie 418
                    'target' => $svnSession->Full,
267 dpurdie 419
                    'require' => 1,
420
                    );
1348 dpurdie 421
 
267 dpurdie 422
#
1348 dpurdie 423
#   If the user did not provide a peg then examine
424
#   the 'tag' in the repo and determine when it was created
425
#   This will not work to well if the user is allowed to move the tag
267 dpurdie 426
#
1348 dpurdie 427
unless ( $svnSession->Peg() )
428
{
429
    $svnSession->SvnInfo( $svnSession->Full, 'InfoRepo' );
430
    my $peg = $svnSession->{'InfoRepo'}{'Last Changed Rev'};
267 dpurdie 431
 
1348 dpurdie 432
    $svnSession->{'PEG'} = '@' . $peg;
433
    if ( $tagLabel ) {
434
        $tagPeg = $peg;
435
    } elsif ( $devBranch ) {
436
        $devBranchPeg = $peg;
437
    }
438
}
439
#debugDumpRefInfo('Get Peg');
440
 
267 dpurdie 441
#
1348 dpurdie 442
#   Trace back from the tag to the point at which it was copied
443
#   This should be the same as the user provided development branch
444
#   but it may not be the same if the user is changing the branch
445
#
1357 dpurdie 446
if ( $tagLabel && $traceBack )
1348 dpurdie 447
{
448
    my $btData;
1349 dpurdie 449
    my $labelBranch = $svnSession->backTrackSvnLabel(
450
                            join ('@', $tagLabel, $tagPeg)
451
                          , 'data' => \$btData
452
                          , 'onlysimple' => 0,
453
                          , 'printdata' => 0 );
454
    $svnSession->{SavedBackTrack} = $btData;
455
    unless ( $btData->{isaBranch} )
1348 dpurdie 456
    {
457
        Warning("Cannot trace package label back to a development branch");
458
    }
459
    else
460
    {
461
        Error ("INTERNAL: Cannot parse result of backTrackSvnLabel: $labelBranch")
1349 dpurdie 462
            unless ($btData->{devBranch} =~ m~^(.*)@(\d+)$~);
1348 dpurdie 463
        $tagLabelBranch = $1;
464
        $tagLabelBranchPeg = $2;
465
 
466
        #
1349 dpurdie 467
        #   Verify that the Development Branch matches that provided by the user
1348 dpurdie 468
        #
469
        if ( $devBranch && ($devBranch ne $tagLabelBranch) )
470
        {
471
            # If the user is creating a branch, then allow this mismatch
472
            #
473
            unless ( $opt_branch && ($devBranch =~ m~/$opt_branch$~) )
474
            {
1357 dpurdie 475
                my @msgText;
476
                push ( @msgText,
477
                        "The package Tag was not taken from the development branch",
478
                        "Development Branch: $devBranch\@$tagPeg",
479
                        "Tag traced back to: $tagLabelBranch\@$tagLabelBranchPeg" );
480
                if ( $traceBack == 1) {
481
                    push @messageText, @msgText;
482
                } else {
483
                    Error ( @msgText );
484
                }
1348 dpurdie 485
            }
486
        }
487
        $devBranchPeg = $tagLabelBranchPeg unless ( $devBranchPeg );
488
 
489
        #   Ensure that the TAG has not been modified since it was taken
490
        #   The extraction algorithm assumes that the tag directory is
491
        #   immutable.
492
        #
1349 dpurdie 493
        #   The build daemon will actually modify the build file during
494
        #   a ripple - this is catered for.
495
        #
496
        #   If other files have been modifed then it should be an error
497
        #
498
        if ( $btData->{changeSets} > 1 )
1348 dpurdie 499
        {
500
            Error ("Tag has been modified since created") if ( $GBE_ABT );
501
            Warning ("Tag has been modified since created");
1349 dpurdie 502
            $noReleaseWs = 1;
1348 dpurdie 503
        }
504
    }
505
}
506
#debugDumpRefInfo('BackTrack Label');
507
 
508
#
509
#   Examine the HEAD of the development branch and determine if there
510
#   have been any changes since the tag was taken
511
#
512
determineChangedFiles();
513
 
514
################################################################################
515
#   Create a workspace based on the tag
516
#   It will be back tracked to the branch that was tagged:
517
#       - Ripple build tags look better in version tree
518
#       - User can develop in the workspace as its not linked to an immutable 'tags'
519
#
520
#   So far we have:
521
#       $initialUrl         - Url to the version that the user specified
522
#       $initialUrlBranch   - Url to the branch from which the initialUrl was taken
523
#                             Iff based on a Tag
524
#       $urlDevBranchHead   - Head of the Development Branch
525
#
526
 
527
$initialUrl = substr( $initialUrl, 1 + length($srcPathPkg));
528
 
529
my $initialUrlBranch;
530
if ( $tagLabelBranch )
531
{
532
    $initialUrlBranch  = $tagLabelBranch;
533
    $initialUrlBranch .= '@' . $tagLabelBranchPeg;
534
}
535
 
536
my $urlDevBranchHead;
537
if ( $devBranch )
538
{
539
    $urlDevBranchHead  = $devBranch;
540
}
541
else
542
{
543
    $urlDevBranchHead  = $tagLabelBranch;
544
}
545
 
546
#
547
#   Debug information
548
#
549
if ( IsVerbose(1) ) {
550
    debugDumpRefInfo('Creating workspaces');
551
    Verbose ('------------');
552
    Verbose ("initialUrl       :", $initialUrl);
553
    Verbose ("initialUrlBranch :", $initialUrlBranch );
554
    Verbose ("urlDevBranchHead :", $urlDevBranchHead );
555
    Verbose ("opt_viewname     :", $opt_viewname );
556
#    DebugDumpData("svn_label", $svnSession );
557
}
558
 
559
#
267 dpurdie 560
#   If we are only extracting files then ...
561
#
562
if ( $opt_extract_files )
563
{
1357 dpurdie 564
    Warning(@messageText );
267 dpurdie 565
    extract_files_from_view();
566
    exit (0);
567
}
568
 
569
#
570
#   Create a new workspace
1348 dpurdie 571
#       This is not done if the user is reusing an existing workspace
572
#       AND the existing workspace exists.
267 dpurdie 573
#
574
if (! -d $VIEWDIR || ! $opt_reuse )
575
{
1348 dpurdie 576
    Message( "Create the workspace" . ($GBE_SANDBOX ? " in a SANDBOX" : ''));
267 dpurdie 577
 
1348 dpurdie 578
    my $branch;
579
    my $view_tag;
580
    my $update_tagsChanges;
581
    if ( $opt_devMode eq 'tip' ) {
582
        $view_tag =  $urlDevBranchHead;
583
    } elsif ( $opt_devMode eq 'exact' ) {
584
        $view_tag =  $initialUrl;
585
    } else {
586
        $view_tag = $initialUrlBranch || $initialUrl;
587
        $update_tagsChanges = 1;
588
    }
589
    Message ("Creating Workspace based on: $view_tag");
590
    $view_tag = $svnSession->FullPath() . '/' .$view_tag;
591
    Verbose("Creating Workspace:", $view_tag);
592
 
267 dpurdie 593
    #
1270 dpurdie 594
    #   If a branch is required ...
1348 dpurdie 595
    #   Ensure that the branch is NOT in the Repository
267 dpurdie 596
    #
597
    if ( $opt_branch )
598
    {
1348 dpurdie 599
        $branch = $svnSession->BranchName($opt_branch, 'branches' );
600
        $svnSession->SvnValidateTarget (
601
                        'cmd'    => 'SvnRelease: Validate Branch',
1270 dpurdie 602
                        'target' => $branch,
1348 dpurdie 603
                        'available' => 1,
1270 dpurdie 604
                        );
267 dpurdie 605
    }
1348 dpurdie 606
 
1270 dpurdie 607
    #
608
    #   Create the workspace
609
    #
1348 dpurdie 610
    $svnSession->SvnCo ( $view_tag, $workSpace );
267 dpurdie 611
    Error ("Cannot locate the created Workspace")
1348 dpurdie 612
        unless ( -d $workSpace);
613
    importTagChanges()
614
        if ($update_tagsChanges);
267 dpurdie 615
 
616
    #
1348 dpurdie 617
    #   If we need to create a branch then
618
    #       Copy the WS to URL
619
    #       Switch to new URL
620
    #   The bulk of the copy will be done on the server-side
621
    #   and not over the network. This is  good.
622
    #
623
    if ( $opt_branch )
624
    {
625
        #
626
        #   Branch does not exist
627
        #   Create it be copying the base view
628
        #
629
        Message ("Creating branch: $opt_branch");
630
        my $branch_tag = $svnSession->SvnCopy (
631
                        'old' => $workSpace,
632
                        'new' => $branch,
633
                        'comment' => 'Created by Jats SvnRelease branch request',
634
                        'replace' => 0 );
635
 
636
        Verbose ("Switching to new branch: $opt_branch");
637
        $branch_tag = SvnPath2Url($branch_tag);
638
        $svnSession->SvnSwitch ($branch_tag,
639
                               $workSpace,
640
                               '--NoPrint' );
641
    }
642
 
643
    #
267 dpurdie 644
    #   Create a local package archive
645
    #   May be needed for multipackage builds and it will prevent JATS from
646
    #   finding any outside the view
647
    #
648
    mkdir ( $VIEWDIR . '/local_dpkg_archive')
649
        unless ($GBE_SANDBOX);
1348 dpurdie 650
 
651
    #
652
    #   Display messages AFTER the extraction text
1357 dpurdie 653
    #   Will ensure that the user has a chance to see them
1348 dpurdie 654
    #
655
    Warning(@messageText );
656
 
267 dpurdie 657
}
658
 
285 dpurdie 659
#   Place a tag-file in the user-specified source path
660
#   This will be used by the build-tool to locate the 'source-path' of the
661
#   view, primarily for determining metrics.
267 dpurdie 662
#
1348 dpurdie 663
#   Calculate where the dynamic view will be
285 dpurdie 664
#   This differ between UNIX/WINDOWS
665
#
351 dpurdie 666
if ( $GBE_ABT)
285 dpurdie 667
{
1348 dpurdie 668
    Message("Create Build tagfile");
669
    TouchFile ( "$workSpace/.jats.packageroot" )
670
        if ( -d $workSpace )
285 dpurdie 671
}
672
 
673
#
267 dpurdie 674
#   Locate the JATS build files within the populated view
675
#
1348 dpurdie 676
chdir ($VIEWDIR) or Error("Cannot chdir to $VIEWDIR");
267 dpurdie 677
Message( "Locating build files");
678
 
679
my $bscanner = BuildFileScanner( $VIEWDIR, 'build.pl', '--LocateAll' );
680
$bscanner->scan();
681
my @build_list = $bscanner->getInfo();
682
foreach my $be ( @build_list )
683
{
1348 dpurdie 684
    Message(DisplayPath ("Build file: $be->{dir} Name: $be->{file}"));
267 dpurdie 685
}
686
 
687
#
688
#   If we are extracting the view then we are done
689
#   Display useful information for the user
690
#
691
if ( $opt_extract )
692
{
693
    Message  DisplayPath "View in: $VIEWDIR";
694
    Warning ("No build files found" )   if ( $#build_list < 0 );
695
    Warning( "Multiple build files found" )if ( $#build_list > 0 );
696
    Message ("Not all labels are pegged") if ( @label_not_pegged  );
697
    Message ("All labels are pegged") unless ( @label_not_pegged  );
698
    Message ("Badly formed label name" ) if ( $bad_label_name );
1348 dpurdie 699
    Message ("Development Mode: $opt_devModeStr") if ( $opt_devModeStr );
267 dpurdie 700
    Message ("Development Sandbox") if ( $GBE_SANDBOX );
1349 dpurdie 701
    Message ("Cannot release from this workspace") if ($noReleaseWs);
267 dpurdie 702
 
703
    exit 0;
704
}
705
 
706
Error ("No build files found")  if ( $#build_list < 0 );
707
 
708
#
709
#   Determine the list of builds to perform
710
#   Ensure that the user-requested build files are present
711
#
712
#   The user specifies the build file, via the mangled package name
713
#   This is package_name . project extension (daf_utils.cr)
714
#
715
if ( $#opt_build  >= 0)
716
{
717
    Verbose( "Check and locate the build files");
718
    @build_list = ();
719
    foreach my $bentry ( @opt_build )
720
    {
721
        if ($bscanner->match( $bentry) )
722
        {
723
            UniquePush (\@build_list, $bscanner->getMatchList() );
724
            Verbose ("Found: $bentry");
725
        }
726
        else
727
        {
728
            Error ("Cannot locate requested build files for: $bentry")
729
        }
730
    }
731
}
732
 
733
#
734
#   Sanity test if we will transfer the generated package to dpkg_archive
735
#   There are some limits
736
#       1) Must have built from one label
737
#       2) That label must be locked
738
#       3) Only one build file
739
#       4) The view must not have been reused
740
#       5) The view has a branch rule
741
#       6) Cannot release from a sandbox
742
#
743
my @elist;
744
push @elist, "Package built from multiple labels" unless ( $label_count == 1 );
745
push @elist, "Package built from an unpegged label" if ( @label_not_pegged  );
746
push @elist, "Package built with multiple build files" if ( scalar @build_list > 1 );
747
push @elist, "Package from a reused view" if ( $opt_reuse && ! $opt_beta );
748
push @elist, "Package from a development sandbox" if ( $GBE_SANDBOX );
1348 dpurdie 749
push @elist, "Package from a development workspace" if ($noReleaseWs);
267 dpurdie 750
push @elist, "View contains a branch" if ( $opt_branch );
751
push @elist, "User has specified build files" if ( $#opt_build > 0 );
752
push @elist, "Badly formed label name" if ( $bad_label_name );
753
 
754
if ( @elist )
755
{
756
    Warning ("Cannot officially release the package.", @elist);
757
    Error ("Build terminated as it cannot be released") if ($opt_dpkg && ! $opt_beta);
758
}
759
Warning ("Beta Release") if $opt_beta;
760
 
761
#
762
#   Process each of the build files in the specified order
763
#
764
foreach my $be (@build_list)
765
{
766
 
767
    #
768
    #   We need to change to the build directory
769
    #   Moreover we need the local name of the build directory.
770
    #   Windows does not handle a UNC pathname to well (at all)
771
    #
772
    my $build_dir = $be->{dir};
773
    chdir ("$build_dir") or Error( "Cannot chdir to build directory: $build_dir");
774
 
775
    if ( $be->{file} =~ m/^build.pl$/ )
776
    {
777
        Message ("Using JATS: $build_dir");
778
        #
779
        #   Invoke JATS to build the package and make the package
780
        #
781
        my @build_args = qw(--expert --cache);
782
        push @build_args, '--cache' if $opt_cache;
783
 
784
        my $make_type = 'all';
785
        $make_type = 'all_prod'  if ( $opt_prod_build );
786
        $make_type = 'all_debug' if ( $opt_debug_build );
787
 
788
 
789
        JatsCmd('build', @build_args)               and Error("Package did not build");
790
        JatsCmd('make', $make_type, 'NODEPEND=1')   and Error("Package did not make");
791
        JatsCmd('install');
792
 
793
        if ( $opt_runtests )
794
        {
321 dpurdie 795
            JatsCmd('make', 'run_unit_tests')      and Error("Tests did not run correctly");
267 dpurdie 796
        }
797
    }
798
    else
799
    {
800
        #
801
        #   Ant build files
802
        #
803
        my $pname =  $be->{file};
804
        Message ("Using ANT: $build_dir, $pname");
805
        $pname =~ s~depends.xml$~.xml~;
806
        copy($be->{file}, "auto.xml");
807
        JatsCmd('-buildfile', $pname, 'ant', 'build')        and Error("Package did not build");
808
        JatsCmd('-buildfile', $pname, 'ant', 'make_package') and Error("Package did not make_package");
809
    }
810
}
811
 
812
#
813
#   Copy the generated packages
814
#       1) dpkg_archive
815
#       2) Users local directory
816
#
817
foreach my $be (@build_list)
818
{
819
    my $build_dir = $be->{dir};
820
    chdir ("$build_dir") or Error( "Cannot chdir to build directory: $build_dir");
821
    if ( $opt_dpkg )
822
    {
823
        Message ("Using: $build_dir");
279 dpurdie 824
        my @create_opts = "-o";
825
        push @create_opts ,"-m" if ( $opt_merge );
826
        JatsCmd('-here', 'create_dpkg', @create_opts, '-pname', $be->{name}, '-pversion', $be->{version}) and $error++;
267 dpurdie 827
    }
828
 
829
    if ( $opt_copy )
830
    {
831
        Message ("Copy package to $user_cwd");
832
        copy_directory( 'pkg', $user_cwd, '' );
833
    }
834
 
835
    #
836
    #   Test structure of the package
837
    #   Ensure that it has a descpkg file
838
    #   Validate the package name and version
839
    #   More important for ANT projects than JATS as JATS has a sanity test
840
    #
841
    if ( $opt_test )
842
    {
843
        JatsCmd('-here', 'create_dpkg', '-test', '-pname', $be->{name}, '-pversion', $be->{version}) and $error++;
844
    }
845
 
846
}
847
Error ("Package not transferred")
848
    if ( $error );
849
 
1348 dpurdie 850
chdir ($user_cwd) or Error( "Cannot chdir to $user_cwd");
267 dpurdie 851
 
852
#
853
#   Delete the view
854
#
855
if ( ! $opt_reuse && ! $error && ! $opt_keep )
856
{
857
    delete_view();
858
}
859
else
860
{
861
    Message( "View left in: $VIEWDIR" );
862
}
863
 
864
Message ("End program");
865
exit 0;
866
 
867
#-------------------------------------------------------------------------------
868
# Function        : delete_view
869
#
870
# Description     : Delete a view
871
#
872
# Inputs          : None
873
#                   $VIEWDIR - path of the view
874
#
875
# Returns         :
876
#
877
sub delete_view
878
{
879
    my $cofound = 0;
880
    my $uuid;
881
    #
299 dpurdie 882
    #   Simple delete
267 dpurdie 883
    #
299 dpurdie 884
    if ( $opt_extract_files )
267 dpurdie 885
    {
299 dpurdie 886
        if ( -d $VIEWDIR )
887
        {
888
            Message("Remove extracted files: $VIEWDIR");
361 dpurdie 889
            RmDirTree( $VIEWDIR );
299 dpurdie 890
        }
891
    }
892
    else
893
    {
267 dpurdie 894
        #
1348 dpurdie 895
        #   If the view physically exists then attempt to physically remove it
267 dpurdie 896
        #
299 dpurdie 897
        if ( -d $VIEWDIR )
898
        {
899
            #
900
            #   Determine if there are any checked out files in the view
901
            #
902
            Message("Remove the view: $VIEWDIR");
903
            Verbose("Look for checked out files");
267 dpurdie 904
 
905
 
1348 dpurdie 906
            SvnRmView ('path'     => $workSpace,
907
                       'force'    => ($opt_delete > 1) || ($opt_extract > 1),
299 dpurdie 908
                       'modified' => [ 'local_dpkg_archive' ] );
909
        }
361 dpurdie 910
        Error ("View was not deleted. Will Delete view directory")
1348 dpurdie 911
            if ( -d $workSpace );
361 dpurdie 912
        RmDirTree( $VIEWDIR ) if $opt_path;
267 dpurdie 913
    }
299 dpurdie 914
 
267 dpurdie 915
    Error ("View was not deleted")
299 dpurdie 916
        if ( -d $VIEWDIR );
267 dpurdie 917
}
918
 
919
#-------------------------------------------------------------------------------
920
# Function        : copy_directory
921
#
922
# Description     : Copy a directory tree
923
#
924
# Inputs          : Source directory
925
#                   Target directory
926
#                   Strip
927
#
928
#                   Should be full pathnames
929
#
930
# Returns         :
931
#
932
my $copy_error;
933
my $copy_count;
934
sub copy_directory
935
{
936
    our ($src_dir, $dest_dir, $strip) = @_;
937
    our $slength = length ($strip);
938
 
939
    #
940
    #   Prevent File::Find from generating warnings
941
    #
942
    no warnings 'File::Find';
943
 
944
 
945
    #
946
    #   Helper routine to copy files
947
    #
948
    sub copy_file_wanted
949
    {
950
        #
951
        #   Do not copy directories
952
        #   Just make the directory entry. May result in empty directories
953
        #
954
        if ( -d $_ )
955
        {
956
            my $tdir = "$dest_dir/" . substr( $File::Find::dir, $slength);
957
            $tdir .= "/$_";
958
            File::Path::mkpath( $tdir )
959
                unless ( -d $tdir);
960
            return;
961
        }
962
 
963
        #
964
        #   When used to copy file from within a clearcase dynamic view the
965
        #   files may not actually exist. This will generate an error later
1348 dpurdie 966
        #   so check for existence of file file now.
267 dpurdie 967
        #
968
        return unless ( -e $_ );
969
 
970
        #
971
        #   Have been chdir'ed to the source directory
972
        #   when invoked
973
        #
974
        my $tdir = "$dest_dir/" . substr( $File::Find::dir, $slength);
975
        my $tfile = "$tdir/$_";
976
        my $sfile = "$File::Find::dir/$_";
977
        Verbose ("Copy: $sfile -> $tfile");
978
 
979
        File::Path::mkpath( $tdir )
980
            unless ( -d $tdir);
981
 
982
        unlink ( $tfile )
983
            if ( -f $tfile );
984
 
985
        if( ! File::Copy::copy ( $_ , $tfile ) )
986
        {
987
            $copy_error++;
988
            Message "Error copying $sfile";
989
        }
990
        else
991
        {
992
            my $perm = (stat $_)[2] & 07777;
993
            chmod($perm, $tfile);
994
 
995
            $copy_count++;
996
        }
997
    }
998
 
999
    #
1000
    #   Locate all files to copy
1001
    #
1002
    $copy_error = 0;
1003
    $copy_count = 0;
1004
    File::Find::find ( \&copy_file_wanted, $src_dir );
1005
    return $copy_error;
1006
}
1007
 
1008
#-------------------------------------------------------------------------------
1009
# Function        : count_files
1010
#
1011
# Description     : Count files in a workspace
1012
#                   Ignore .svn stuff
1013
#
1014
# Inputs          : Source directory
1015
#
1016
# Returns         :
1017
#
1018
sub count_files
1019
{
1020
    my ($src_dir) = @_;
1021
 
1022
    #
1023
    #   Prevent File::Find from generating warnings
1024
    #
1025
    no warnings 'File::Find';
1026
 
1027
 
1028
    #
1029
    #   Helper routine to copy files
1030
    #
1031
    sub count_file_wanted
1032
    {
1033
        #
1034
        #   Do not count dirs, only files
1035
        #
1036
        return if ( -d $_ );
1037
        $copy_count++;
1038
    }
1039
 
1040
    #
1041
    #   Locate all files
1042
    #
1043
    $copy_count = 0;
1044
    File::Find::find ( \&count_file_wanted, $src_dir );
1045
}
1046
 
1047
 
1048
#-------------------------------------------------------------------------------
1049
# Function        : extract_files_from_view
1050
#
1051
# Description     : This function will
1348 dpurdie 1052
#                       Extract the files from the required source
1053
#                       This is a simple operation under subversion
267 dpurdie 1054
#
1055
#                   Its used in the creation of escrow directories
1056
#
1057
# Inputs          : None
1058
#                   All done via globals
1059
#
1060
# Returns         : 
1061
#
1062
sub extract_files_from_view
1063
{
1064
    #
1065
    #   Determine the target directory for the extracted files
1066
    #       Delete the output subdir
1067
    #       Create the config spec in that directory
1068
    #
1069
    Verbose("Extracting files into $VIEWDIR");
1070
    if ( -d $VIEWDIR )
1071
    {
1072
        Verbose "Delete Directory: $VIEWDIR\n";
361 dpurdie 1073
        RmDirTree( $VIEWDIR );
267 dpurdie 1074
    }
1075
 
1348 dpurdie 1076
    #
1077
    #   Determine URL to extract
1078
    #       work : Same as exact
1079
    #       exact: Use user provided tag
1080
    #              No need to backtrack to the branch and then
1081
    #              Update files
1082
    #
1083
    #       tag:   Don't update build files
1084
    #              This is different normal mode
1085
    #              Perhaps should change to be the same as exact - just extract
1086
    #              the user provided tag
1087
    #
1088
    #       tip:   Don't update build files
1089
    #
1090
    my $view_tag;
1091
    if ( $opt_devMode eq 'tip' ) {
1092
        $view_tag =  $urlDevBranchHead;
1093
    } elsif ( $opt_devMode eq 'tag' ) {
1094
        $view_tag = $initialUrlBranch;
1095
    } else {
1096
        $view_tag = $initialUrl;
1097
    }
267 dpurdie 1098
 
1348 dpurdie 1099
    $svnSession->SvnCo ( $svnSession->FullPath() . '/' . $view_tag,
1100
                        $VIEWDIR,
1356 dpurdie 1101
                        'export' => 1,
1102
                        'print' => 0 );
1348 dpurdie 1103
 
267 dpurdie 1104
    #
1105
    #   Count this files in the view
1348 dpurdie 1106
    #   Done so that its clear when we have a empty workspace in escrow extractions
267 dpurdie 1107
    #
1108
    Verbose ("Examine View contents");
1109
    count_files ( $VIEWDIR );
1110
    Message ("View files in: $VIEWDIR, Files: $copy_count" );
1348 dpurdie 1111
}
267 dpurdie 1112
 
1348 dpurdie 1113
#-------------------------------------------------------------------------------
1114
# Function        : importTagChanges
1115
#
1116
# Description     : import changes from a 'tag' into the target workspace
1117
#                   Use with a workspace as well as an exported target
1118
#
1119
# Background      :
1120
#   The workspace has been created on the branch from which the tag was taken
1121
#   BUT this may not be the same as the tag because:
1122
#       1) Developer is not respecting the use of tags
1123
#       2) The automated build system will place the rippled build files
1124
#          within the tag.
1125
#   The most effective way that I have found of getting the modified build
1126
#   files into the workspace is to:
1127
#       Parse the log of the tag
1128
#       Determine files that have been modified as a part of the tag
1129
#       export them into the workspace
1130
#
1131
#   If we are creating a workspace that we are about to branch, then
1132
#   we use 'switch' to copy in the new file
1133
#   Otherwise, use a 'co -export'. If we use a switch, then the files
1134
#   that have been switched in cannot be commit if changed as they will
1135
#   be within the 'tags' area.
1136
#
1137
# Inputs          : None
1138
#                   Globals
1139
#
1140
# Returns         : Error code
1141
#
1142
sub importTagChanges
1143
{
1144
    return unless ( $tagLabel );
1349 dpurdie 1145
    my $data = $svnSession->{SavedBackTrack};
1146
    Error ("Internal: importTagChanges expects backtracking to have been performed")
1147
        unless (defined $data);
1148
 
1348 dpurdie 1149
#    DebugDumpData("importTagChanges", $svnSession );
1150
#    DebugDumpData("Data", $data );
1151
 
1152
    #
1153
    #   Process the data from the backtrack log and determine the files
1154
    #   that we need to transfer.
1349 dpurdie 1155
    #       Should only be one - but if the users have been bad
1156
    #       then there may be more.
1348 dpurdie 1157
    #
1356 dpurdie 1158
    if ( $data->{files} )
1348 dpurdie 1159
    {
1356 dpurdie 1160
        foreach my $srcFile ( reverse @{$data->{files}} )
1348 dpurdie 1161
        {
1356 dpurdie 1162
            Verbose("importTagChanges: $srcFile");
1163
            my $sfile = $svnSession->FullPath() . '/' . $srcFile;
1451 dpurdie 1164
 
1165
            #
1166
            #   Calculate path with the repo of the target file
1167
            #
1168
            $srcFile =~ m~tags/.*?(/.*)@\d+~;
1169
            my $tfile = $workSpace . $1;
1170
 
1356 dpurdie 1171
            if ( $opt_branch )
1172
            {
1451 dpurdie 1173
                $svnSession->SvnSwitch ($sfile, $tfile);
1356 dpurdie 1174
            }
1175
            else
1176
            {
1451 dpurdie 1177
                $svnSession->SvnCo ($sfile, $tfile,
1356 dpurdie 1178
                                        'export' => 1,
1179
                                        'force' => 1,
1180
                                        'pretext' => 'Replacing ' );
1181
            }
1348 dpurdie 1182
        }
1183
    }
267 dpurdie 1184
}
1185
 
1186
#-------------------------------------------------------------------------------
1348 dpurdie 1187
# Function        : determineChangedFiles
1188
#
1189
# Description     : Display a list of files that have been changed between
1190
#                   the tagPoint and the head of the branch
1191
#
1192
# Inputs          : Only Globals
1193
#
1194
# Returns         : Will not return if changes are not allowed
1195
#
1196
sub determineChangedFiles
1197
{
1198
    my @msgText;
2028 dpurdie 1199
    my $onlyWarn = ($checkDelta == 1);
267 dpurdie 1200
 
1348 dpurdie 1201
    #
1202
    #   No checking required
1203
    #   Skip the hard bit if running on a build machine
1204
    #
1205
    return unless ( $checkDelta );
267 dpurdie 1206
 
1348 dpurdie 1207
    Debug ('determineChangedFiles');
1208
#debugDumpRefInfo('determineChangedFiles');
1209
 
1210
    #
1211
    #   Examine the HEAD of the development branch and determine if there
1212
    #   have been any changes since the tag was taken
1213
    #
1214
    #   Determine the Repo Revision for the HEAD of the devBranch
1215
    #
1216
    Error ("Internal: No devBranch calculated") unless ( $devBranch || $tagLabelBranch );
1217
 
1218
    my $basePeg = $tagLabelBranchPeg || $devBranchPeg;
1219
    my $baseBranch = $tagLabelBranch || $devBranch;
1220
    Error ("Internal logic. Expecting tagLabelBranchPeg or devBranchPeg to be defined") unless ( $basePeg );
1221
    Error ("Internal logic. Expecting tagLabelBranch or devBranch to be defined") unless ( $baseBranch );
1222
 
1223
    my $svn_check = NewSessionByUrl ( join( '/', $srcPathPkg, $baseBranch), 1 );
1224
    my $rv = $svn_check->SvnInfo( $svn_check->Full, 'InfoRepo' );
1225
    if ( $rv )
1226
    {
1227
        push (@msgText, "Cannot read information for the head of the development branch",
1228
                        "Branch may not exist: $baseBranch");
2028 dpurdie 1229
        $onlyWarn = 1;
1348 dpurdie 1230
    }
1231
    else
1232
    {
1233
        $devBranchHead = $svn_check->{'InfoRepo'}{'Last Changed Rev'};
1234
        Verbose2("devBranchHead: $devBranchHead");
1235
    #debugDumpRefInfo('Dev Branch Head');
1236
 
1237
 
1238
        #
1239
        #   If the Rev of the HEAD is greater than the point at which we
1240
        #   are interested then changes may have occured. Otherwise we know
1241
        #   that changes cannot have occured
1242
        #
1243
        if ( $devBranchHead <= $basePeg )
1244
        {
1245
            return;
1246
        }
1247
 
1248
        if ( $tagLabelBranchPeg )
1249
        {
1250
            push @msgText,  "Development Branch has changed since Tag was taken",
1251
                            "Head last changed in Rev: $devBranchHead",
1252
                            "Tag traced back to Rev  : $basePeg";
1253
        } else
1254
        {
1255
            push @msgText,  "Development Branch has changed since specified version",
1256
                            "Head last changed in Rev: $devBranchHead",
1257
                            "Specified branch Rev    : $basePeg";
1258
        }
1259
 
1260
 
1261
        my $diffBase = $svn_check->FullPath() . '/' . $baseBranch;
1262
        $svn_check->{tmp}{path_length} = length($diffBase);
1263
        $svn_check->{tmp}{count}  = 0;
1264
        @{$svn_check->{tmp}{files}}  = ();
1265
 
1266
        $rv = $svn_check->SvnCmd ( 'diff', '--summarize',
1267
                                   $diffBase,
1268
                                   '--revision', $basePeg . ':HEAD',
1269
                                   {
1270
                                        'process' => \&ProcessDiff,
1271
                                        'credentials' => 1,
1272
                                        'nosavedata' => 1,
1273
                                   }
1274
                                );
1275
        #
1276
        #   Prepare message to be displayed
1277
        #   Prepend text to the list of files
1278
        #
1279
 
1280
        $rv = $svn_check->{tmp}{count};
1281
        return unless ( $rv );
1282
        push (@msgText, "No files changed") unless ( $rv );
1283
        push (@msgText, "Changed file count: $rv") if ( $rv );
1284
        push (@msgText, "More than 10 files have changed. First 10 are:") if ( $rv > 10);
1285
        push (@msgText, @{$svn_check->{tmp}{files}} );
1286
    }
1287
 
2028 dpurdie 1288
    if ($onlyWarn) {
1348 dpurdie 1289
        push @messageText, @msgText;
1290
    } else {
1291
        Error ( @msgText );
1292
    }
1293
}
1294
 
1295
sub ProcessDiff
1296
{
1297
    my $self = shift;
1298
    my $data = shift;
1299
 
1300
    #
1301
    #   Extract filename from line
1302
    #       First 8 chars are status
1303
    #       Remove WS path too
1304
    #
1305
    my $path_length = $self->{tmp}{path_length} + 1 + 8;
1306
    if ( length $data >= $path_length )
1307
    {
1308
        my $file = substr ( $data, $path_length );
1309
        push @{$self->{tmp}{files}}, '  Changed: ' .  $file
1310
            if ( $self->{tmp}{count}++ < 10 );
1311
    }
1312
 
1313
    return 0;
1314
}
1315
 
267 dpurdie 1316
#-------------------------------------------------------------------------------
1348 dpurdie 1317
# Function        : parseSubversionRef
1318
#
1319
# Description     : Parse the user-provided Subversion Ref
1320
#
1321
#                   Convert label with embedded VCS information into a 'normal' form.
1322
#                   Form:
1323
#                       SVN::<SourcePath>::<Label>
1324
#                       SVN::<SourcePath>::<Peg>
1325
#                   
1326
#                   Allow optional 'SVN::' prefix
1327
#                   Allow Full or Symbolic URL
1328
#                       [SVN::]<SourcePath>::<Label>
1329
#                       [SVN::]<SourcePath>::<Peg>
1330
#                       [SVN::]<URL>
1331
#
1332
# Inputs          : $opt_spec               - User Provided Ref
1333
#
1334
# Returns         : Will not retirn on gross error
1335
#                   Values return in global variables
1336
#
1337
sub parseSubversionRef
1338
{
1339
    my ($opt_spec) = @_;
1340
 
1341
    $opt_spec =~ s~^SVN::~~;
1342
    if ( $opt_spec =~ m~(.+)::(.+)~ )
1343
    {
1344
        my $sourcePath = $1;
1345
        my $label = $2;
1346
        $urlType = 'jats';
1347
 
1348
        #
1349
        #   Sanity test of sourcePath
1350
        #
1351
        Error ("Invalid use of a peg: $opt_spec[0]")
1352
            if ( $sourcePath =~ m~\@\d+$~ );
1353
 
1354
        #
1355
        #   Remove anything after a ttb (truck, tags, branch) element
1356
        #   This will be the root of the package within the repo
1357
        #
1358
        if (  $sourcePath =~ m~(.*)/((tags|branches|trunk)(/|$)(.*))~ )
1359
        {
1360
            Error ("Source Path has insufficient items")
1361
                if ( $1 eq '' );
1362
 
1363
            Error ("SourcePath contains invalid items after '$3': '$5'")
1364
                if ( ($3 eq 'tags' || $3 eq 'trunk') && $5 ne '' );
1365
 
1366
            Error ("SourcePath must contain items after 'branches'")
1367
                if ( $3 eq 'branches' && $5 eq '');
1368
 
1369
            $srcPathPkg = $1;
1370
            $ttbType = $3;
1371
            $devBranch = $3;
1372
            $devBranch .= '/' . $5 if ( $5 ne '' );
1373
        }
1374
        else
1375
        {
1376
            Error ("Source Path does not contain tags or trunk or branches component");
1377
        }
1378
 
1379
        #
1380
        #   Pull apart the 2nd argument
1381
        #   May be a raw peg - on the development branch
1382
        #   May be a tag and a peg
1383
        #
1384
        $initialUrl = $srcPathPkg;
1385
        if ( $label =~ m~^@*(\d+)$~ )
1386
        {
1387
            # Full numeric label - is a peg on the development branch
1388
            $devBranchPeg = $1;
1389
            $initialUrl .= '/' . $devBranch . '@' . $devBranchPeg;
1390
        }
1391
        elsif ( $label =~ m~^([^@]+)@(\d+)$~ )
1392
        {
1393
            $tagLabel = 'tags/' . $1;
1394
            $tagPeg = $2;
1395
            $initialUrl .= '/tags/' . $label;
1396
 
1397
        }
1398
        elsif ( $label !~ m~@~ )
1399
        {
1400
            $tagLabel = 'tags/' . $label;
1401
            $initialUrl .= '/tags/' . $label;
1402
        }
1403
        else
1404
        {
1405
            Error ("Subversion Tag badly formed: $label");
1406
        }
1407
    } elsif ($opt_spec =~ m~::~) {
1408
        Error ("Badly formed Subversion Reference: $opt_spec[0]");
1409
 
1410
    }
1411
    else
1412
    {
1413
        # Have a full URL and not a JATS enhanced spec
1414
        # Cannot determine the development branch and the tag
1415
        #
1416
        $urlType = 'url';
1417
        $initialUrl = $opt_spec;
1418
 
1419
        # Extact any peg
1420
        my $peg;
1421
        if ( $opt_spec =~ m~(.*)@(\d+)$~ )
1422
        {
1423
            $opt_spec = $1;
1424
            $peg = $2;
1425
        }
1426
 
1427
        if (  $opt_spec =~ m~(.*)/((tags|branches|trunk)(/|$)(.*))~ )
1428
        {
1429
            Error ("Subversion URL has insufficient items")
1430
                if ( $1 eq '' );
1431
            $srcPathPkg = $1;
1432
            $ttbType = $3;
1433
 
1434
            if ( $ttbType eq 'trunk' ) {
1435
                Error ("Subversion URL must NOT contain items after '$ttbType'")
1436
                    if ( $5 ne '' );
1437
                $devBranch = $2;
1438
                $devBranchPeg = $peg;
1439
 
1440
            } elsif ( $ttbType eq 'tags' ) {
1441
                Error ("Subversion URL must contain items after '$ttbType'")
1442
                    unless ( $5 ne '' );
1443
                $tagLabel = $2;
1444
                $tagPeg = $peg;
1445
 
1446
            } else {
1447
                Error ("Subversion URL must contain items after '$ttbType'")
1448
                    unless ( $5 ne '' );
1449
                $devBranch = $2;
1450
                $devBranchPeg = $peg;
1451
            }
1452
        }
1453
        else
1454
        {
1455
            Error ("Subversion URL does not contain tags or trunk or branches component");
1456
        }
1457
    }
1458
    #debugDumpRefInfo('First Parse');
1459
}
1460
 
1461
#-------------------------------------------------------------------------------
1454 dpurdie 1462
# Function        : calcViewName
1463
#
1464
# Description     : Calculate a nice name for the view
1465
#                   Try to base the name on the tag
1466
#
1467
#                   If the URL looks like a TTB then we can make some guesses
1468
#                   as to the package name and version.
1469
#
1470
#                   Add indication for the Dev Mode
1471
#                   Add indication for a branch
1472
 
1473
#
1474
# Inputs          : Nothing
1475
#
1476
# Returns         : A nice View name
1477
#                   Will not retirn on error
1478
#
1479
sub calcViewName
1480
{
1481
    #
1482
    #   Use the user provided view name if its valid
1483
    #
1484
    if ( $opt_viewname )
1485
    {
1486
        Error ("View Name contains invalid characters" )
1487
            unless ( $opt_viewname =~ m~^[0-9a-z]([-.:0-9a-z_]*[0-9a-z])?$~i );
1488
        return $opt_viewname ;
1489
    }
1490
 
1491
    #
1492
    #   Create a view name based on the provide URL or SVN Reference
1493
    #
1494
    my $version;
1495
    my $name = $srcPathPkg;
1496
    $name =~ s~.*/~~;
1497
 
1498
    if ( $tagLabel )
1499
    {
1500
        $version = $tagLabel;
1501
        $version =~ s~.*/~~;
1502
        $version = $1 if ( $version =~ m~^${name}_(.*)~ );
1503
    }
1504
    elsif ( $devBranch )
1505
    {
1506
        $version = $devBranch;
1507
        $version =~ s~.*/~~;
1508
    }
1509
 
1510
    if ( $version && $name )
1511
    {
1512
        $opt_viewname = join( '_', $name, $version);
1513
    }
1514
    elsif ( $svnSession->Type )
1515
    {
1516
        $opt_viewname = $svnSession->Path;
1517
        $opt_viewname .= '_' . ($svnSession->Version || 'trunk') unless $opt_branch;
1518
 
1519
        #
1520
        #   Tags and Branches 'should' include the package name
1521
        #   This will lead to a duplication of the package name
1522
        #   ie: aaaaa/package/tags/package_version
1523
        #   Attempt to remove these
1524
        #
1525
        if ( $opt_viewname =~ s~[_/]([\-.:0-9a-zA-Z]+)_\1_~_$1_~ )
1526
        {
1527
            Verbose ("Removed duplicate package name: $1 from $opt_viewname");
1528
        }
1529
    }
1530
    else
1531
    {
1532
        $opt_viewname = $svnSession->Path;
1533
        $bad_label_name = 1;
1534
    }
1535
 
1536
    #
1537
    #   Append the peg if provided
1538
    #   Not if creating a 'tip' as its a bit meaningless
1539
    #
1540
    if ( my $peg = $tagPeg || $devBranchPeg )
1541
    {
1542
        unless( $opt_devMode eq 'tip' )
1543
        {
1544
            $opt_viewname .= '_' . $peg;
1545
        }
1546
    }
1547
 
1548
    #
1549
    #   Append information to indicate the exact type of the WorkSpace
1550
    #   Normally mutually exclusive
1551
    #
1552
    $opt_viewname .= '_Tip' if ( $opt_devMode eq 'tip' );
1553
    $opt_viewname .= '_Tag' if ( $opt_devMode eq 'tag' );
1554
    $opt_viewname .= '_Exact' if ( $opt_devMode eq 'exact' );
1555
    $opt_viewname .= '_' . $opt_branch if ( $opt_branch );
1556
 
1557
    #
1558
    #   Create a simple dir name
1559
    #       Remove path sep characters and replace with _
1560
    #       Remove Peg marker (@) as this breaks svn
1561
    #       Replace multiple _ with a single _
1562
    #       Remove trailing _ - caused by URL with a trailing /
1563
    #
1564
    $opt_viewname =~ s~[^\-.:0-9a-zA-Z_]~_~g;
1565
    $opt_viewname =~ tr~_~_~s;
1566
    $opt_viewname =~ s~_+$~~;
1567
    return $opt_viewname;
1568
}
1569
 
1570
#-------------------------------------------------------------------------------
1348 dpurdie 1571
# Function        : debugDumpRefInfo
1572
#
1573
# Description     : Dump the current Ref Information
1574
#
1575
# Inputs          : $text
1576
#
1577
# Returns         : 
1578
#
1579
sub debugDumpRefInfo
1580
{
1581
    Verbose0 ('-' x 40);
1582
    Verbose0 ('debugDumpRefInfo:' , @_ );
1583
    Verbose0 ('ttbType           :', $ttbType);
1584
    Verbose0 ('urlType           :', $urlType);
1585
    Verbose0 ('Base              :', $svnSession->FullPath() ) if $svnSession;
1586
    Verbose0 ('initialUrl        :', $initialUrl);
1587
    Verbose0 ('srcPathPkg        :', $srcPathPkg);
1588
    Verbose0 ('devBranch         :', $devBranch);
1589
    Verbose0 ('devBranchPeg      :', $devBranchPeg);
1590
    Verbose0 ('devBranchHead     :', $devBranchHead);
1591
    Verbose0 ('tagLabel          :', $tagLabel);
1592
    Verbose0 ('tagPeg            :', $tagPeg);
1593
    Verbose0 ('tagLabelBranch    :', $tagLabelBranch);
1594
    Verbose0 ('tagLabelBranchPeg :', $tagLabelBranchPeg);
1595
}
1596
 
1597
#-------------------------------------------------------------------------------
1598
 
1599
 
1600
#-------------------------------------------------------------------------------
267 dpurdie 1601
#   Documentation
1602
#
1603
 
1604
=pod
1605
 
361 dpurdie 1606
=for htmltoc    GENERAL::Subversion::
1607
 
267 dpurdie 1608
=head1 NAME
1609
 
1610
jats_svnrelease - Build a package given a SubVersion label
1611
 
1612
=head1 SYNOPSIS
1613
 
1614
  jats svnrelease [options] [-label=]label
1615
 
1616
 Options:
1617
    -help              - brief help message
1618
    -help -help        - Detailed help message
1619
    -man               - Full documentation
1620
    -label=xxx         - Subversion label
1621
    -spec=xxx          - Same as -label=xxx
1622
    -path=xxx          - Source Path
1623
    -view=xxx          - Modify the name of the created view
1624
    -build=xxx         - Package Name to build
1625
    -root=xxx          - Root directory for generated view
1626
    -[mk]branch=xxx    - Will create a view with a branch rule
1348 dpurdie 1627
    -tag=xxx           - Compatibility. Not used
267 dpurdie 1628
    -extract           - Extract the view and exit
1629
    -extractfiles      - Extract files, without a view
1348 dpurdie 1630
    -devMode=xxx       - Create Workspace suitable for development.(Tip,Tag,...)
267 dpurdie 1631
    -cache             - Refresh local dpkg_archive cache
361 dpurdie 1632
    -delete[=n]        - Remove any existing view and exit
267 dpurdie 1633
    -debugOnly         - Make only the debug version
1634
    -prodOnly          - Make only the production version
1635
    -[no]dpkg          - Transfer package into dpkg_archive
1636
    -[no]copy          - Transfer pkg directory to the current user directory
1637
    -[no]reuse         - Reuse the view
1638
    -[no]test          - Test package build. Implies nocopy and nodpkg
1639
    -[no]keep          - Keep the view after the build
1640
    -[no]beta          - Release a beta package
1641
    -[no]merge         - Merge packages into dpkg_archive
1642
    -[no]runtests      - Run units tests. Default is runtests
1348 dpurdie 1643
    -[no]prefix        - Suppress user prefix in view name. Default prefix is USER
267 dpurdie 1644
 
1645
=head1 OPTIONS
1646
 
1647
=over 8
1648
 
1649
=item B<-help>
1650
 
1651
Print a brief help message and exits.
1652
 
1653
=item B<-help -help>
1654
 
1655
Print a detailed help message with an explanation for each option.
1656
 
1657
=item B<-man>
1658
 
1659
Prints the manual page and exits.
1660
 
1661
=item B<-label> or B<-spec>
1662
 
1348 dpurdie 1663
The Subversion label to use as the base for the workspace. The utility will
1664
accept the following forms of label identifier, each with an optional 'SVN::' prefix.
267 dpurdie 1665
 
1348 dpurdie 1666
=over 4
267 dpurdie 1667
 
1348 dpurdie 1668
=item Full URL
1669
 
1670
This form is identified by the complete lack of the '::' subfield delimiter. The
1671
URL is used as provided. It is not modified.
1672
 
1673
 Eg: AUPERASVN01/DPG_SWBASE/daf_utils_math/tags/daf_utils_math_3.2.1@12345
1674
 Eg: https://auperasvn01.aupera.erggroup.com/svn/DPG_SWBASE/daf_utils_math/tags/daf_utils_math_3.2.1@12345
1675
 
1676
 
1677
=item SourcePath::Tag
1678
 
1679
The SourcePath component is used to calculate the root of the package directory.
1680
The source path is then caclulated assuming that the 'Tag' exists within a
1681
'/tags' subdirectory of the root of the package.
1682
 
1683
This is the form preferred by Release Manager and the VIX build system.
1684
 
1685
 Eg: AUPERASVN01/DPG_SWBASE/daf_utils_math/trunk::daf_utils_math_3.2.1@12345
1686
 
1687
=item SourcePath::Peg
1688
 
1689
A special case of of the 'SourcePath::Tag' form is invoked if the 'Tag' component
1690
is numeric. It will be treated as a peg of the Base Path.
1691
 
1692
 Eg: AUPERASVN01/DPG_SWBASE/daf_utils_math/trunk::12345
1693
 
1694
=back
1695
 
267 dpurdie 1696
=item B<-view name>
1697
 
1698
Specified an alternate view name and tag to be used. This option does not provide the
1699
full name of the view.
1700
 
361 dpurdie 1701
The view path will be: "${USER}_${NAME}"
267 dpurdie 1702
 
1703
The default "NAME" is the first label specified with the repository and tag removed.
1704
 
1705
If the user provides a view "name" that is prefixed with their user name
1706
('${USER}_'), then the username will be stripped of for internal processing.
1707
This allows a user to provide a view path when deleting a view.
1708
 
1709
=item B<-path=xxx>
1710
 
1711
Specifies the source path to the root of the extracted file tree. This option is
1348 dpurdie 1712
not mandatory and is only used to maintain toolset compatibility with other
267 dpurdie 1713
,similar, tools.
1714
 
1715
If provided, then the Workspace will be created within the named subdirectory
1716
tree within the base of the view.
1717
 
1718
=item B<-build=xxx>
1719
 
1720
This option allows the user to specify the packages to be built and the
1721
order in which the packages are to be built.
1722
This is useful if the extracted view contains multiple build files
1723
 
1724
This option may be used multiple times.
1725
 
1726
There are two forms in which the build target can be specified. It can be
1348 dpurdie 1727
specified as a full package name and version, or as a package name and the
267 dpurdie 1728
project suffix.
1729
 
1730
By default the program will assume that there is only one build file in the
1731
view and will not build if multiple files are present, unless the package to be
1732
built can be resolved.
1733
 
1734
The location mechanism operates for both JATS and ANT build files.
1735
 
1736
Example: -build=jats-api.1.0.0000.cr
1737
 
1738
This will locate the build file that builds version 1.0.0000.cr of the jats-api
1739
package. The version numbers must match exactly.
1740
 
1741
Example: -build=jats-api.cr -build=jats-lib.cr
1742
 
1743
This will located the build files that build the jats_api (cr) package and the
1744
jats-lib (cr) package. The version of the packages will not be considered.
1745
 
1746
=item B<-root=xxx>
1747
 
1748
This option allows the location of the generated view to be specified on the
1348 dpurdie 1749
command line. It overrides the value of GBE_VIEWBASE.
267 dpurdie 1750
 
1348 dpurdie 1751
If the command is invoked within a development sandbox, then the default
267 dpurdie 1752
location will be the root directory of the development sandbox.
1753
 
1754
=item B<-branch=xxx or -mkbranch=xxx>
1755
 
1270 dpurdie 1756
This option will create a workspace associated with a branch within the
1757
repository. This is intended to facilitate the maintenance of existing packages
1758
and the creation of project or development branches in a manner similar to
1759
ClearCase.
267 dpurdie 1760
 
1270 dpurdie 1761
If the named branch exists, then the workspace will be based on the branch and
1762
not on the specified label.
267 dpurdie 1763
 
1270 dpurdie 1764
If the named branch does not exist, then this tool will copy the specified
1765
source version to the branch and then create a workspace based on the branch.
267 dpurdie 1766
 
383 dpurdie 1767
A branch name of TIMESTAMP will be treated in special manner. The name will be
1768
replaced with a unique name based on the users name and the current date time.
1769
 
351 dpurdie 1770
=item B<-tag=text>
1771
 
1772
This option is not used.
1348 dpurdie 1773
It is present to maintain compatibility with the buildtool interface.
351 dpurdie 1774
 
267 dpurdie 1775
=item B<-extract>
1776
 
1777
With this option the view is created and the left in place. The user may then
1778
access the files within the view. The view should not be used for a
1779
production release.
1780
 
1781
=item B<-extractfiles>
1782
 
1783
With this option the utility will create a dynamic view and transfer files from
1348 dpurdie 1784
the view to the user's target. The dynamic view is then removed.
267 dpurdie 1785
 
1786
This command is intended to simplify the process of creating an escrow.
1787
 
1348 dpurdie 1788
=item B<-devMode=mode>
1789
 
1790
This option controls the exact form of the Workspace create. The svnRelease
1791
command supports the following modes (default is working):
1792
 
1793
=over 4
1794
 
1795
=item   Tag or TagPoint
1796
 
1797
The workspace will contain the point on the packages development branch from
1798
which the specified tag was copied.
1799
 
1800
The extraction process will highlight file differences between the specified tag
1801
and the tip. If any differences are found then these will be treated as an error.
1802
 
1803
The user B<should> resolve this error by selecting, in Release Manager, a
1804
version of the package based on the tip of the Development Branch.
1805
 
1806
This is the preferred Development Mode for working on a package as it provides
1807
checks to ensure that the Meta Data held in Release Manager is consistient.
1808
 
1809
=item   Work or Working
1810
 
1811
The workspace will contain the point on the packages development branch from
1812
which the specified tag was copied.
1813
 
1814
The extraction process will highlight file differences between the specified tag
1815
and the tip of the Development Branch. Unlike the 'Tag' Mode, such differences
1816
are not treated as an error.
1817
 
1818
This mode of WorkSpace has several features and constraints:
1819
 
1820
=over 4
1821
 
1822
=item *
1823
 
1824
The build files from the 'tagged' version will be transferred into the
1825
WorkSpace. These will be seen as modified files.
1826
 
1827
=item *
1828
 
1829
This style of workspace can be converted into a 'Tip' style through the use of the
1830
Subversion 'update' command.
1831
 
1832
=item *
1833
 
1834
If there have been changes to the Development Branch, then it not be possible to
1835
'commit' the workspace. It may need to be branched first.
1836
 
1837
=back
1838
 
1839
=item Tip or BranchTip
1840
 
1841
The workspace will contain the 'tip' of the Packages Development Branch.
1842
 
1843
The extraction process will highlight file differences between the specified tag
1844
and the tip.
1845
 
1846
=item Exact
1847
 
1848
The workspace will be directly based on the Tag or URL provided by the user.
1849
 
1850
The resultant workspace may not be suitable for development.
1851
 
1852
The extraction process will highlight file differences between the specified tag
1853
and the tip of any associated Development Branch.
1854
 
1855
=back
1856
 
1857
The four extraction points are shouwn in the following image:
1858
 
1859
     /branches/...    /tags/...
1860
            v            v
1861
            |
1862
        +---+---+
1863
  [Tag] | Work  |    +-------+
1864
        +---+---+----+ Exact |
1865
            |        +-------+
1866
        +---+---+
1867
        |       |
1868
        +---+---+
1869
            |
1870
        +---+---+
1871
        |  Tip  |
1872
        +---+---+
1873
 
267 dpurdie 1874
=item B<-cache>
1875
 
1876
Forces external packages to be placed in the local dpkg_archive cache.
1877
 
1878
The normal operation is to copy the packages, only if they do not already exist
1879
in the local cache. This option may be used to ensure that the local copy is
1880
correct and up to date.
1881
 
361 dpurdie 1882
=item B<-delete[=level]>
267 dpurdie 1883
 
1884
Delete the view used by the program, if it exists. This option may be used to
1885
cleanup after an error.
1886
 
361 dpurdie 1887
The default 'level' is 1.
267 dpurdie 1888
 
361 dpurdie 1889
If the delete level is 1, then ensure that no files are open in the view and
1890
that the users current working directory is not in the view as these will
1891
prevent the view from being deleted.
1892
 
1893
If the delete level is greater than one, then the view will be deleted, even
1894
if there are checkout out files.
1895
 
267 dpurdie 1896
=item B<-debugOnly>
1897
 
1898
Make only the debug version of the package. The default it to create both the
1899
debug and production version of the package. The type of build may be  further
1900
limited by options within the package.
1901
 
1902
=item B<-prodOnly>
1903
 
1904
Make only the production version of the package. The default it to create both the
1905
debug and production version of the package. The type of build may be  further
1906
limited by options within the package.
1907
 
1908
=item B<-[no]dpkg>
1909
 
1910
Copy the generated package into dpkg_archive. This is the default mode of
1911
operation.
1912
 
1913
=item B<-[no]copy>
1914
 
1915
Copy the built "pkg" directory to the users current directory. The entire
1916
"pkg" subdirectory includes the full package named directory for the package
1917
that has been built.
1918
 
1919
=item B<-[no]reuse>
1920
 
1921
This flag allows the view created by the program to be re-used.
1922
 
1923
=over 8
1924
 
361 dpurdie 1925
=item *
267 dpurdie 1926
 
361 dpurdie 1927
The view is not deleted before being populated.
267 dpurdie 1928
 
361 dpurdie 1929
=item *
267 dpurdie 1930
 
361 dpurdie 1931
The view will not be populated if it does exist.
1932
 
1933
=item *
1934
 
1935
The view will not be deleted at the end the process.
1936
 
267 dpurdie 1937
=back
1938
 
1939
This option is useful for debugging a build process.
1940
 
1941
=item B<-[no]test>
1942
 
1943
Test the building of the package. This option implies "nocopy" and "nodpkg".
1944
 
1945
=item B<-[no]keep>
1946
 
361 dpurdie 1947
Keep the workspace after the build. The default option is "nokeep"
267 dpurdie 1948
 
1949
This option is different to the "reuse" in that the view will be deleted, if
1950
it exists, before the build, but will be retained at the completion of the
1951
process. The user may then manually extract the created package.
1952
 
1953
The view may be deleted with the the "delete" option; taking care to ensure that
1954
no files are open in the view and that the users current working directory is
1955
not in the view.
1956
 
1957
=item B<-[no]beta>
1958
 
1959
This option overrides many of the package release tests to allow a beta package
1960
to be released.
1961
 
1962
=item B<-[no]merge>
1963
 
1964
This option will merge packages being built on multiple machines into
1965
dpkg_archive. By default, if a package already exists in the archive it will be
1966
deleted and replaced. With this option the package will be merged. The merge
1967
process does not over write files found in the archive.
1968
 
1969
=item B<-[no]runtests>
1970
 
1971
This option will allow the suppression of the running of the unit tests included
1972
with the component. By default the tests are run. This can be suppressed
1973
without affecting the release process.
1974
 
1975
=back
1976
 
1977
=head1 DESCRIPTION
1978
 
1979
This program is the primary tool for the creation, recreation and release of
1270 dpurdie 1980
packages within the B<VIX> build environment, although the program can perform a
267 dpurdie 1981
number of very useful operations required during normal development and
1982
maintenance.
1983
 
1984
This program will build a system containing one or more inter-related build
1985
files using the JATS build tools.
1986
 
1987
In normal operation the program will:
1988
 
1989
=over 8
1990
 
1991
=item Remove Workspace
1992
 
1993
Remove any existing workspace of the same name. The workspace will not be
1994
removed if it contains checked-out files.
1995
 
1996
The workspace removal may fail if there are any files B<open> within the view or if
1997
any shell has a subdirectory of the view set as a B<current working directory>.
1998
 
1999
=item Create the workspace
2000
 
2001
Create a workspace to contain the files described by the Subversion
2002
label being processed.
2003
 
2004
=item Populate the workspace
2005
 
2006
Loads files into the workspace.
2007
 
2008
I<Note:> If the workspace files are simply being extracted, then this is the end
2009
of the program. The extracted workspace is left in place.
2010
 
2011
=item Sanity Test
2012
 
2013
If the build is being used as a release into dpkg_archive then
2014
various tests are performed to ensure the repeatability of the view and the
2015
build. These tests include:
2016
 
2017
=over 8
2018
 
361 dpurdie 2019
=item   *
267 dpurdie 2020
 
361 dpurdie 2021
The view must be constructed from one label
267 dpurdie 2022
 
361 dpurdie 2023
=item   *
267 dpurdie 2024
 
361 dpurdie 2025
That label must be pegged
267 dpurdie 2026
 
361 dpurdie 2027
=item   *
2028
 
2029
The labelled view must contain exactly one build file
2030
 
2031
=item   *
2032
 
2033
The view cannot have been re-used.
2034
 
267 dpurdie 2035
=back
2036
 
2037
=item Locate build files
2038
 
2039
Locate the build file within the view.
2040
 
2041
It is an error to have multiple build files within the workspace, unless the
2042
B<-build> option is used. By default, only one package will be built.
2043
 
2044
=item Package the results
2045
 
2046
Use JATS to build and make the package.
2047
 
2048
The resultant package may be copied to a numbers of locations. These include
2049
 
2050
=over 8
2051
 
2052
=item 1
2053
 
2054
The master dpkg_archive as an official release. This is the default operation.
2055
 
2056
=item 2
2057
 
2058
The users current directory. The package directory from the built package is
2059
copied locally. The "pkg" directory is copied. This is only performed with the
2060
B<-copy> option.
2061
 
2062
=back
2063
 
2064
=item Delete the workspace
2065
 
2066
Delete the workspace and all related files.
2067
 
2068
The workspace will not be deleted if an error was detected in the build process, or
2069
the "reuse" or "keep" options are present.
2070
 
2071
=back
2072
 
2073
=cut
2074