Subversion Repositories DevTools

Rev

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