Subversion Repositories DevTools

Rev

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

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