Subversion Repositories DevTools

Rev

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

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