Subversion Repositories DevTools

Rev

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

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