Subversion Repositories DevTools

Rev

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