Subversion Repositories DevTools

Rev

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