Subversion Repositories DevTools

Rev

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