Subversion Repositories DevTools

Rev

Rev 4096 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
311 dpurdie 1
########################################################################
2
# Copyright (C) 1998-2008 ERG Limited, All rights reserved
3
#
4
# Module name   : jats_svn.pl
5
# Module type   : Jats Utility
6
# Compiler(s)   : Perl
7
# Environment(s): Jats
8
#
9
# Description   : A script to perform a number of SVN utility functions
10
#                 The script will:
11
#                   Delete a package
12
#                   Create a package
13
#                   Import source to a package
14
#
15
#
16
#......................................................................#
17
 
18
require 5.006_001;
19
use strict;
20
use warnings;
21
use JatsError;
22
use JatsSvn qw(:All);
23
use JatsLocateFiles;
379 dpurdie 24
use JatsProperties;
311 dpurdie 25
use Pod::Usage;                                 # required for help support
26
use Getopt::Long qw(:config require_order);     # Stop on non-option
27
use Cwd;
28
use File::Path;
29
use File::Copy;
30
use File::Basename;
31
use File::Compare;
387 dpurdie 32
use Encode;
311 dpurdie 33
 
34
my $VERSION = "1.0.0";                          # Update this
35
 
36
#
37
#   Options
38
#
39
my $opt_debug   = $ENV{'GBE_DEBUG'};            # Allow global debug
40
my $opt_verbose = $ENV{'GBE_VERBOSE'};          # Allow global verbose
41
my $opt_help = 0;
42
 
43
#
44
#   Globals
45
#
46
my $opr_done;                                   # User has done something
47
 
48
#-------------------------------------------------------------------------------
49
# Function        : Mainline Entry Point
50
#
51
# Description     :
52
#
53
# Inputs          :
54
#
55
my $result = GetOptions (
56
                "help:+"        => \$opt_help,              # flag, multiple use allowed
57
                "manual:3"      => \$opt_help,              # flag
58
                "verbose:+"     => \$opt_verbose,           # flag, multiple use allowed
59
 
60
                );
61
 
62
                #
63
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
64
                #
65
 
66
#
67
#   Process help and manual options
68
#
69
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
70
pod2usage(-verbose => 1) if ($opt_help == 2 );
71
pod2usage(-verbose => 2) if ($opt_help > 2);
72
 
73
#
74
#   Configure the error reporting process now that we have the user options
75
#
76
ErrorConfig( 'name'    =>'SVN',
77
             'verbose' => $opt_verbose,
78
            );
79
 
80
#
369 dpurdie 81
#   Reconfigure the options parser to allow subcommands to parse options
311 dpurdie 82
#
83
Getopt::Long::Configure('permute');
84
 
85
#
86
#   Process command
87
#   First command line argument is a subversion command
88
#
89
my $cmd = shift @ARGV || "help";
90
CreatePackage()                        if ( $cmd =~ m/^create/ );
2049 dpurdie 91
CreateBranch()                         if ( $cmd =~ m/^branch/ );
92
SwitchBranch()                         if ( $cmd =~ m/^switch/ );
385 dpurdie 93
DeleteBranch()                         if ( $cmd =~ m/^delete-branch/ );
311 dpurdie 94
DeletePackage()                        if ( $cmd =~ m/^delete-package/ );
95
ImportPackage()                        if ( $cmd =~ m/^import/ );
96
SvnRepoCmd($cmd, @ARGV)                if ( $cmd eq 'ls' );
363 dpurdie 97
TestSvn()                              if ($cmd eq 'test');
369 dpurdie 98
ShowPaths()                            if ( $cmd =~ m/^path/ );
99
ShowTag()                              if ( $cmd =~ m/^tag/ );
100
ShowUrl()                              if ( $cmd =~ m/^url/ );
311 dpurdie 101
 
102
pod2usage(-verbose => 0, -message => "No valid operations specified") unless ( $opr_done );
103
exit 0;
104
 
105
#-------------------------------------------------------------------------------
369 dpurdie 106
# Function        : ShowPaths
107
#
108
# Description     : Show PATHS
109
#
2049 dpurdie 110
# Inputs          :
369 dpurdie 111
#
2049 dpurdie 112
# Returns         :
369 dpurdie 113
#
114
sub ShowPaths
115
{
116
    #
117
    #   Parse more options
118
    #
119
    GetOptions (
120
                "help:+"        => \$opt_help,
121
                "manual:3"      => \$opt_help,
122
                ) || Error ("Invalid command line" );
123
 
124
    #
125
    #   Subcommand specific help
126
    #
127
    SubCommandHelp( $opt_help, "Subversion Paths") if ($opt_help || $#ARGV >= 0);
128
 
129
    #
130
    #   Display known PATHS
131
    #
132
    my ( $pSVN_URLS, $pSVN_URLS_LIST) = SvnPaths();
133
    print ("Configured SubVersion Repository Paths\n");
134
    print sprintf("    %-20s %s\n", 'Tag', 'URL Prefix');
135
 
136
    foreach my $key ( @{$pSVN_URLS_LIST} )
137
    {
138
        print sprintf("    %-20s %s\n", $key || 'Default', $pSVN_URLS->{$key} );
139
    }
140
 
141
    $opr_done = 1;
142
}
143
 
144
#-------------------------------------------------------------------------------
145
# Function        : ShowTag
146
#
147
# Description     : Convert a URL into a TAG
148
#                   Convert the current workspace info into a TAG
149
#
150
# Inputs          : url                     - Url to convert (optional)
151
#                   Options
152
#                       -help[=n]           - Show help
153
#                       -man                - Show manual
154
#                       -url=url            - Convert URL
155
#                       -path=path          - Convert Workspace
156
#
157
# Returns         : Nothing
158
#
159
sub ShowTag
160
{
161
    my $opt_path;
162
    my $opt_url;
163
 
164
    #
165
    #   Parse more options
166
    #
167
    GetOptions (
168
                "help:+"        => \$opt_help,
169
                "manual:3"      => \$opt_help,
170
                "path:s"        => \$opt_path,
171
                "url:s"         => \$opt_url,
172
                ) || Error ("Invalid command line" );
173
 
174
    #
175
    #   Subcommand specific help
176
    #
177
    SubCommandHelp( $opt_help, "Url to Tag") if ($opt_help);
178
 
179
    #
180
    #   Bare argument is a URL
181
    #   If no arguments provided assume a path of the current directory
182
    #
183
    $opt_url = shift (@ARGV) if ( $#ARGV == 0 );
184
    $opt_path = '.' unless ( defined $opt_path || defined $opt_url );
185
 
186
    #
187
    #   Sanity Tests
188
    #
189
    Error ("Cannot specify both a URL and a PATH")
190
            if ( defined $opt_url && defined $opt_path );
191
    Warning ("Too many arguments") if ( $#ARGV >= 0 );
192
 
193
    #   Do all the hard work
194
    #
195
    my $uref;
196
    if ( $opt_url )
197
    {
198
        $uref = NewSessionByUrl ( $opt_url );
199
        $uref->CalcRmReference($uref->Full());
200
    }
201
    else
202
    {
203
        $uref = NewSessionByWS($opt_path, 0, 1);
204
        my $ws_root = $uref->SvnLocateWsRoot(1);
205
        $uref->CalcRmReference($uref->FullWs());
206
    }
207
 
1403 dpurdie 208
    Message ("Tag is  : " . $uref->RmRef() );
209
    Message ("Vcs Tag : " . $uref->SvnTag  );
2049 dpurdie 210
 
369 dpurdie 211
    $opr_done = 1;
212
}
213
#-------------------------------------------------------------------------------
214
# Function        : ShowUrl
215
#
216
# Description     : Convert a TAG into a URL
217
#                   Show the current workspace URL
218
#
219
# Inputs          : tag                     - Tag to convert (optional)
220
#                   Options
221
#                       -help[=n]           - Show help
222
#                       -man                - Show manual
223
#                       -tag=tag            - Convert TAG
224
#                       -path=path          - Convert Workspace
225
#
226
# Returns         : Nothing
227
#
228
sub ShowUrl
229
{
230
    my $opt_path;
231
    my $opt_tag;
232
 
233
    #
234
    #   Parse more options
235
    #
236
    GetOptions (
237
                "help:+"        => \$opt_help,
238
                "manual:3"      => \$opt_help,
239
                "path:s"        => \$opt_path,
240
                "tag:s"         => \$opt_tag,
241
                ) || Error ("Invalid command line" );
242
 
243
    #
244
    #   Subcommand specific help
245
    #
246
    SubCommandHelp( $opt_help, "Tag to Url") if ($opt_help);
247
 
248
    #
249
    #   Bare argument is a TAG
250
    #   If no arguments provided assume a path of the current directory
251
    #
252
    $opt_tag = shift (@ARGV) if ( $#ARGV == 0 );
253
    $opt_path = '.' unless ( defined $opt_path || defined $opt_tag );
254
 
255
    #
256
    #   Sanity Tests
257
    #
258
    Error ("Cannot specify both a TAG and a PATH")
259
            if ( defined $opt_tag && defined $opt_path );
260
    Warning ("Too many arguments") if ( $#ARGV >= 0 );
261
 
262
    #   Do all the hard work
263
    #
264
    my $uref;
265
    my $url;
266
    if ( $opt_tag )
267
    {
2429 dpurdie 268
        my $path = $opt_tag;
269
        my $label;
270
 
271
        $path =~ s~^SVN::~~;
272
        if ( $path =~ m~(.+)::(.+)~ )
273
        {
274
            $path = $1;
275
            $label = $2;
276
        }
277
        $url = SvnPath2Url($path);
278
        if ( $label && $label =~ m~^\d+$~ )
279
        {
280
            $url .= '@' . $label;
281
        }
282
        elsif ( $label )
283
        {
284
            $url =~ m~(.+)(/(tags|branches|trunk)(/|$|@))~;
285
            $url = $1 . '/tags/'. $label;
286
        }
369 dpurdie 287
    }
288
    else
289
    {
290
        $uref = NewSessionByWS($opt_path, 0, 1);
291
        my $ws_root = $uref->SvnLocateWsRoot(1);
292
        $url = $uref->FullWsRev();
293
    }
294
 
295
    Message ("Url: $url");
296
    $opr_done = 1;
297
}
298
 
299
#-------------------------------------------------------------------------------
363 dpurdie 300
# Function        : TestSvn
301
#
302
# Description     : Test access to subversion
303
#
304
# Inputs          : None
305
#
306
# Returns         :
307
#
308
sub TestSvn
309
{
310
    #
311
    #   Parse more options
312
    #
313
    GetOptions (
314
                "help:+"        => \$opt_help,
315
                "manual:3"      => \$opt_help,
316
                ) || Error ("Invalid command line" );
317
 
318
    #
319
    #   Subcommand specific help
320
    #
321
    SubCommandHelp( $opt_help, "Test Subversion") if ($opt_help || $#ARGV >= 0);
322
 
323
    SvnUserCmd( '--version');
324
    $opr_done = 1;
325
}
326
#-------------------------------------------------------------------------------
311 dpurdie 327
# Function        : SvnRepoCmd
328
#
329
# Description     : Execute a SVN command, where the first argument
330
#                   is a repository specifier
331
#
332
# Inputs          : $cmd
333
#                   $repo_url
334
#                   @opts
335
#
2049 dpurdie 336
# Returns         :
311 dpurdie 337
#
338
sub SvnRepoCmd
339
{
340
    my ( $cmd, $repo_url, @opts ) = @_;
341
    my $uref = NewSessionByUrl ( $repo_url );
342
 
343
    SvnUserCmd( $cmd,
344
            $uref->Full,
345
            @opts,
346
            { 'credentials' => 1 });
2049 dpurdie 347
 
311 dpurdie 348
    $opr_done = 1;
349
}
350
 
351
#-------------------------------------------------------------------------------
352
# Function        : DeletePackage
353
#
354
# Description     : Delete a Package structure within a Repository
355
#                   Intended for test usage
356
#
357
# Inputs          : URL                 - Url to Repo + Package Base
358
#
2049 dpurdie 359
# Returns         :
311 dpurdie 360
#
361
sub DeletePackage
362
{
379 dpurdie 363
    my $opt_error = 0;
311 dpurdie 364
    #
365
    #   Parse more options
366
    #
367
    GetOptions (
368
                "help:+"        => \$opt_help,
369
                "manual:3"      => \$opt_help,
379 dpurdie 370
                "error!"       => \$opt_error,
311 dpurdie 371
                ) || Error ("Invalid command line" );
372
 
373
    #
374
    #   Subcommand specific help
375
    #
376
    SubCommandHelp( $opt_help, "Delete a Package") if ($opt_help || $#ARGV < 0);
377
 
378
    #
379
    #   Sanity Tests
380
    #
381
    Message ("Delete Entire Package Tree" );
382
    Warning ("Too many arguments: @ARGV") if ( $#ARGV >= 1 );
383
 
384
    #
385
    #   Do all the hard work
386
    #       Create
387
    #       Import
388
    #       Label
389
    #
390
    my $uref = NewSessionByUrl ( $ARGV[0] );
379 dpurdie 391
    $uref->SvnValidatePackageRoot(!$opt_error);
311 dpurdie 392
    $uref->SvnDelete (
393
                      'target'      => $uref->Full,
385 dpurdie 394
                      'comment'   => [$uref->Path().": Delete Package",'Deleted by user command: jats svn delete-package'],
379 dpurdie 395
                      'noerror'   => !$opt_error,
311 dpurdie 396
                      );
397
    $opr_done = 1;
398
}
399
 
400
#-------------------------------------------------------------------------------
401
# Function        : CreatePackage
402
#
403
# Description     : Create a Package structure within a Repository
404
#                   Optionally Import Data
405
#                   Optionally Tag the import
406
#                   Optionally Tag the import on a branch
407
#
408
# Inputs          : URL                 - Url to Repo + Package Base
409
#                   Options             - Command modifiers
410
#                       -import=path    - Import named directory
411
#                       -label=name     - Label the result
412
#                       -tag=name       - Import to Tag Only
413
#                       -branch=name    - Import to Branch only
414
#                       -new            - Must be new package
415
#                       -replace        - Replace existing
416
#
2049 dpurdie 417
# Returns         :
311 dpurdie 418
#
419
sub CreatePackage
420
{
421
    my $opt_import;
422
    my $opt_tag;
423
    my $opt_branch;
424
    my $opt_trunk;
425
    my $opt_new;
426
    my $opt_label;
427
    my $opt_replace;
428
    my $pname;
429
    my $type;
385 dpurdie 430
    my $opt_author;
431
    my $opt_date;
311 dpurdie 432
    Message ("Create New Package Version" );
433
 
434
    #
435
    #   Parse more options
436
    #
437
    GetOptions (
438
                "help:+"        => \$opt_help,
439
                "manual:3"      => \$opt_help,
440
                "verbose:+"     => \$opt_verbose,
441
                "import=s"      => \$opt_import,
442
                "new"           => \$opt_new,
443
                "branch=s"      => \$opt_branch,
444
                "trunk"         => \$opt_trunk,
1403 dpurdie 445
                "tags=s"        => \$opt_tag,
311 dpurdie 446
                "label=s"       => \$opt_label,
447
                "replace"       => \$opt_replace,
385 dpurdie 448
                'author=s'      => \$opt_author,
449
                'date=s'        => \$opt_date,
311 dpurdie 450
 
451
                ) || Error ("Invalid command line" );
452
 
453
    #
454
    #   Subcommand specific help
455
    #
456
    SubCommandHelp( $opt_help, "Create a Package Version") if ($opt_help || $#ARGV < 0);
2049 dpurdie 457
 
311 dpurdie 458
    #
369 dpurdie 459
    #   Alter the error reporting parameters
311 dpurdie 460
    #
461
    ErrorConfig( 'verbose' => $opt_verbose );
462
 
463
    #
464
    #   Sanity Tests
465
    #
466
    my $count = 0;
467
    $count++ if ( $opt_trunk );
468
    $count++ if ( $opt_branch );
469
    $count++ if ( $opt_tag );
470
    Error ("Conflicting options: -trunk, -tag, -branch") if ( $count > 1 );
471
    Error ("Nothing imported to be labeled") if ( $count && !$opt_import );
472
    Error ("Import path does not exist: $opt_import") if ( $opt_import && ! -d $opt_import );
473
    Error ("Conflicting options: new and replace") if ( $opt_new && $opt_replace );
385 dpurdie 474
    Error ("Too many command line arguments") if ( exists $ARGV[1] );
311 dpurdie 475
 
1403 dpurdie 476
    $type = 'tags/' . $opt_tag          if ( $opt_tag);
477
    $type = 'branches/' . $opt_branch   if ( $opt_branch );
478
    $type = 'trunk'                     if ( $opt_trunk);
311 dpurdie 479
 
480
    #
481
    #   Do all the hard work
482
    #       Create
483
    #       Import
484
    #       Label
485
    #
486
    my $uref = NewSessionByUrl ( $ARGV[0] );
487
    $uref->SvnCreatePackage (
488
                      'import'  => $opt_import,
489
                      'label'   => $opt_label,
490
                      'type'    => $type,
491
                      'new'     => $opt_new,
492
                      'replace' => $opt_replace,
493
                      );
385 dpurdie 494
    #
495
    # Report RmPath as using a pegged version of a new package is a bit silly
496
    #
1403 dpurdie 497
#    Message ("Repository Ref: " . $uref->RmPath);
498
#    Message ("Vcs Tag       : " . $uref->SvnTag);
1329 dpurdie 499
    if ( $uref->{REVNO} )
500
    {
501
        $uref->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
502
        $uref->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
503
    }
311 dpurdie 504
    $opr_done = 1;
505
}
506
 
507
#-------------------------------------------------------------------------------
508
# Function        : ImportPackage
509
#
510
# Description     : Import a new version of a package
511
#                   Take great care to reuse file-versions that are already in
512
#                   the  package
513
#
369 dpurdie 514
#                   Intended to allow the importation of multiple
311 dpurdie 515
#                   versions of a package
516
#
2049 dpurdie 517
# Inputs          :
311 dpurdie 518
#
2049 dpurdie 519
# Returns         :
311 dpurdie 520
#
521
sub ImportPackage
522
{
523
    Message ("Import Package Version" );
524
 
525
    #
526
    #   Options
527
    #
528
    my $opt_package;
529
    my $opt_dir;
530
    my $opt_label;
531
    my $opt_replace = 0;
532
    my $opt_reuse;
533
    my $opt_workdir = "SvnImportDir";
534
    my $opt_delete = 1;
379 dpurdie 535
    my $opt_author;
536
    my $opt_date;
537
    my $opt_log = '';
538
    my $opt_branch;
539
    my $opt_datafile;
1403 dpurdie 540
    my $opt_printfiles;
2429 dpurdie 541
    my $opt_commit = 1;
2764 dpurdie 542
    my $opt_mergePaths;
311 dpurdie 543
 
544
    #
545
    #   Other globals
546
    #
547
    my $url_label;
379 dpurdie 548
    my $url_branch;
311 dpurdie 549
 
2764 dpurdie 550
    my $filesBase = 0;                  # Files in Base workspace
551
    my $filesDeleted = 0;               # Files Deleted
552
    my $filesAdded = 0;                 # Files Added
553
    my $filesTransferred = 0;           # Files Copied
554
    my $dirsDeleted = 0;                # Directories Deleted
555
    my $dirsAdded = 0;                  # Directories Added
556
    my $dirsTransferred = 0;            # Directories Copied
557
 
558
 
311 dpurdie 559
    #
560
    #   Configuration options
561
    #
562
    my $result = GetOptions (
379 dpurdie 563
                    'help:+'        => \$opt_help,
564
                    'manual:3'      => \$opt_help,
565
                    'verbose:+'     => \$opt_verbose,
566
                    'package=s'     => \$opt_package,
567
                    'dir=s'         => \$opt_dir,
568
                    'label=s'       => \$opt_label,
569
                    'branch=s'      => \$opt_branch,
570
                    'replace'       => \$opt_replace,
571
                    'reuse'         => \$opt_reuse,
572
                    'workspace=s'   => \$opt_workdir,
573
                    'delete!'       => \$opt_delete,
1403 dpurdie 574
                    'printfiles=i'  => \$opt_printfiles,
379 dpurdie 575
                    'author=s'      => \$opt_author,
576
                    'date=s'        => \$opt_date,
577
                    'log=s'         => \$opt_log,
578
                    'datafile=s'    => \$opt_datafile,
2429 dpurdie 579
                    'commit!'       => \$opt_commit,
2764 dpurdie 580
                    'mergePaths=s'  => \$opt_mergePaths,
311 dpurdie 581
 
582
                    #
583
                    #   Update documentation at the end of the file
584
                    #
585
                    ) || Error ("Invalid command line" );
586
 
587
    #
588
    #   Insert defaults
341 dpurdie 589
    #   User can specify base package via -package or a non-options argument
311 dpurdie 590
    #
591
    $opt_package = $ARGV[0] unless ( $opt_package );
379 dpurdie 592
    unlink $opt_datafile if ( defined $opt_datafile );
2049 dpurdie 593
 
311 dpurdie 594
    #
595
    #   Subcommand specific help
596
    #
597
    SubCommandHelp( $opt_help, "Import directory to a Package")
598
        if ($opt_help || ! $opt_package );
599
 
600
    #
369 dpurdie 601
    #   Alter the error reporting parameters
311 dpurdie 602
    #
603
    ErrorConfig( 'verbose' => $opt_verbose );
604
 
605
    #
606
    #   Configure the error reporting process now that we have the user options
607
    #
608
    Error ("No package URL specified") unless ( $opt_package );
609
    Error ("No base directory specified") unless ( $opt_dir );
610
    Error ("Invalid base directory: $opt_dir") unless ( -d $opt_dir );
2429 dpurdie 611
    Error ("Cannot label if not committing") if ( $opt_label && ! $opt_commit );
311 dpurdie 612
 
613
    #
614
    #   Create an SVN session
615
    #
616
    my $svn = NewSessionByUrl ( $opt_package );
617
 
618
    #
619
    #   Ensure that the required label is available
620
    #
621
    if ( $opt_label )
622
    {
623
        $opt_label = SvnIsaSimpleLabel ($opt_label);
624
        $url_label = $svn->BranchName( $opt_label, 'tags' );
625
        $svn->SvnValidateTarget (
626
                        'target' => $url_label,
627
                        'available' => 1,
628
                        ) unless ( $opt_replace );
629
    }
630
 
631
    #
379 dpurdie 632
    #   Validate the required branch
633
    #   It will be created if it doesn't exist
634
    #
635
    if ( $opt_branch )
636
    {
637
        $opt_branch = SvnIsaSimpleLabel($opt_branch);
638
        $url_branch = $svn->BranchName( $opt_branch, 'branches' );
385 dpurdie 639
        my $rv = $svn->SvnValidateTarget (
640
                        'cmd'    => 'SvnImporter. Create branch',
379 dpurdie 641
                        'target' => $url_branch,
642
                        'create' => 1,
643
                        );
385 dpurdie 644
        if ( $rv == 2 )
645
        {
646
            $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
647
            $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
648
        }
379 dpurdie 649
    }
650
 
651
    #
311 dpurdie 652
    #   Create a workspace based on the users package
653
    #   Allow the workspace to be reused to speed up multiple
654
    #   operations
655
    #
656
    unless ( $opt_reuse && -d $opt_workdir )
657
    {
658
        Message ("Creating Workspace");
659
        rmtree( $opt_workdir );
660
 
661
        $svn->SvnValidatePackageRoot ();
662
        #DebugDumpData( 'Svn', $svn );
663
        $svn->SvnValidateTarget (
664
                            'cmd'    => 'SvnImporter',
665
                            'target' => $svn->Full,
666
                            'require' => 1,
667
                            );
668
 
379 dpurdie 669
        my $url_co = $opt_branch ? $url_branch : $svn->Full . '/trunk';
1403 dpurdie 670
        $svn->SvnCo ( $url_co, $opt_workdir, 'print' => $opt_printfiles );
311 dpurdie 671
        Error ("Cannot locate the created Workspace")
672
            unless ( -d $opt_workdir );
673
    }
674
    else
675
    {
676
        Message ("Reusing Workspace");
677
    }
2049 dpurdie 678
 
311 dpurdie 679
    #
680
    #   Determine differences between the two folders
681
    #       Create structures for each directory
682
    #
683
    Message ("Determine Files in packages");
684
 
685
    my $search = JatsLocateFiles->new("--Recurse=1",
686
                                       "--DirsToo",
687
                                       "--FilterOutRe=/\.svn/",
688
                                       "--FilterOutRe=/\.svn\$",
689
                                       "--FilterOutRe=^/${opt_workdir}\$",
690
                                       "--FilterOutRe=^/${opt_workdir}/",
691
                                       );
692
    my @ws = $search->search($opt_workdir);
693
    my @dir = $search->search($opt_dir);
694
 
1329 dpurdie 695
    #
696
    #   Scan for a source file
697
    #   Trying to detect empty views
698
    #   Look for file, not directory
2764 dpurdie 699
    #       Keep a count for reporting
1329 dpurdie 700
    #
701
    {
2764 dpurdie 702
        foreach ( @ws )
703
        {
704
            $filesBase++ unless ( m~/$~ );
705
        }
706
 
1329 dpurdie 707
        my $fileFound = 0;
708
        foreach ( @dir )
709
        {
710
            next if ( m~/$~ );
2764 dpurdie 711
            $fileFound = 1;
1329 dpurdie 712
            last;
713
        }
714
 
715
        unless ( $fileFound )
716
        {
717
            Warning ("No source files found in source view");
718
            $opr_done = 1;
719
            return;
720
        }
721
    }
722
 
311 dpurdie 723
    #Information ("WS Results", @ws);
724
    #Information ("DIR Results", @dir);
1329 dpurdie 725
    #Information ("WS Results: ", scalar @ws);
726
    #Information ("DIR Results:", scalar @dir);
311 dpurdie 727
 
4086 dpurdie 728
 
311 dpurdie 729
    #
730
    #   Create a hash the Workspace and the User dir
731
    #   The key will be file names
732
    #
733
    my %ws;  map ( $ws{$_} = 1 , @ws );
734
    my %dir; map ( $dir{$_} = 1 , @dir );
735
 
736
    #
4086 dpurdie 737
    #   Create hash of paths to persist
738
    #       build/*   -> Persist directory. Keep dir tree if not
739
    #                    being imported, otherwise delete.
740
    #
741
    my %persistPaths;
742
    if ( $opt_mergePaths )
743
    {
744
        foreach ( split(',', $opt_mergePaths) )
745
        {
746
            if ( m~(.+/)\*$~ )
747
            {
748
                my $base = $1;
749
                $persistPaths{$base} = 1 unless( exists $dir{$base});
750
            }
751
        }
752
        Verbose0("Persist Paths:" , sort keys %persistPaths);
753
    }
754
 
755
    #
311 dpurdie 756
    #   Create a hash of common elements
757
    #   Removing then from the other two
758
    #
759
    my %common;
760
    foreach ( keys %ws )
761
    {
762
        next unless ( exists $dir{$_} );
763
        $common{$_} = 1;
764
        delete $ws{$_};
765
        delete $dir{$_};
766
    }
767
 
2764 dpurdie 768
    #
769
    #   Now have:
770
    #       %ws     - Hash of paths that are only in the Workspace
771
    #       %dir    - Hash of paths that are only in New Import
772
    #       %common - Hash of paths that are common to both
773
    #
311 dpurdie 774
    #DebugDumpData( 'WS', \%ws );
775
    #DebugDumpData( 'DIR', \%dir );
776
    #DebugDumpData( 'COMMON', \%common );
777
 
2764 dpurdie 778
 
311 dpurdie 779
    #
379 dpurdie 780
    #   Need to consider the case where a file has been replaced with a directory
781
    #   and visa-versa. Delete files and directories first.
782
    #
783
    #
784
    #   Remove files
785
    #   Sort in reverse. This will ensure that we process directory
786
    #   contents before directories
787
    #
2764 dpurdie 788
 
379 dpurdie 789
    my @rm_files = reverse sort keys %ws;
790
    if ( @rm_files )
791
    {
2764 dpurdie 792
        #
793
        #   Calculate new top level paths
794
        #   These are of the form xxxxx/
795
        #
796
        my @newTldPaths;
797
        if ( $opt_mergePaths )
798
        {
4086 dpurdie 799
            foreach (@rm_files)
2764 dpurdie 800
            {
801
                push (@newTldPaths, $1 ) if ( m~^([^/]+)/$~ );
802
            }
803
        }
804
 
805
        my @processedFiles;
379 dpurdie 806
        foreach my $file ( @rm_files  )
807
        {
2764 dpurdie 808
            #
809
            #   Detect items that are to be retained
810
            #   Do not delete items that are a part of a top level path that
3347 dpurdie 811
            #   are not present in the New Import
2764 dpurdie 812
            #
813
            if ( $opt_mergePaths )
814
            {
815
                my $keep = 0;
4086 dpurdie 816
                ##
817
                ##  Following removed because it did the wrong thing and I'm not too sure
818
                ##  under what conditions its needed.
819
                ##  It did the wrong thing when used with '++,XXXX/**'
820
                ##  Perhaps its only these that cause problems
821
 
822
                ##
823
                ##foreach ( @newTldPaths )
824
                ##{
825
                ##    if ( $file =~ m~^$_/~ )
826
                ##    {
827
                ##        Verbose("Merge Retain(0): $file, $_");
828
                ##        $keep = 1;
829
                ##        last;
830
                ##    }
831
                ##}
832
 
833
                if ( $file =~ m~(^.*/)~ )
2764 dpurdie 834
                {
4086 dpurdie 835
                    my $tpath = $1;
836
                    foreach ( keys %persistPaths)
2764 dpurdie 837
                    {
4086 dpurdie 838
                        if ( $file =~ m~^$_~ )
839
                        {
840
                            Verbose0("Merge Retain(1): $file");
841
                            $keep = 1;
842
                            last;
843
                        }
2764 dpurdie 844
                    }
845
                }
3347 dpurdie 846
 
847
                #
848
                #   Examine $opt_mergPaths and process entries that look like
849
                #       build/**  -> keep the directory and every think under it
4086 dpurdie 850
                #       build/*   -> Persist directory. Keep dir tree if not
851
                #                    being imported, otherwise delete.
3347 dpurdie 852
                #
853
                foreach ( split(',', $opt_mergePaths) )
854
                {
855
                    if ( m~(.+/)\*\*$~ )
856
                    {
857
                        my $base = $1;
858
                        if ( $file =~ m~^$base~ )
859
                        {
4086 dpurdie 860
                            Verbose0("Merge Retain(2): $file");
3347 dpurdie 861
                            $keep = 1;
862
                            last;
863
                        }
864
                    }
865
                }
866
 
2764 dpurdie 867
                next if ($keep);
868
            }
869
 
4086 dpurdie 870
            Verbose0("Removing $file");
2764 dpurdie 871
            $filesDeleted++ unless ( $file =~ m~/$~ );
872
            $dirsDeleted++ if ( $file =~ m~/$~ );
379 dpurdie 873
            unlink "$opt_workdir/$file";
2764 dpurdie 874
            push @processedFiles, $file;
379 dpurdie 875
        }
2764 dpurdie 876
        @rm_files = @processedFiles;
379 dpurdie 877
 
878
        #
879
        #   Inform Subversion about the removed files
880
        #
881
        my $base = 0;
882
        my $num = $#rm_files;
2764 dpurdie 883
        Message ("Update the workspace: Removed $filesDeleted Files, $dirsDeleted directories");
379 dpurdie 884
 
885
        while ( $base <= $num )
886
        {
887
            my $end = $base + 200;
888
            $end = $num if ( $end > $num );
889
 
890
            $svn->SvnCmd ( 'delete', map ("$opt_workdir/$_@", @rm_files[$base .. $end] ),
891
                            { 'error' => 'Deleting files from workspace' } );
2049 dpurdie 892
 
379 dpurdie 893
            $base = $end + 1;
894
        }
895
    }
2049 dpurdie 896
 
379 dpurdie 897
    #
311 dpurdie 898
    #   Add New Files
899
    #   Won't add empty directories at this point
900
    #
901
    #   Process by sorted list
902
    #   This will ensure we process parent directories first
903
    #
904
    my @added = sort keys %dir;
905
    if ( @added )
906
    {
2764 dpurdie 907
        my @processedFiles;
311 dpurdie 908
        foreach my $file ( @added  )
909
        {
2764 dpurdie 910
            #
911
            #   Detect items that are to be merged
912
            #   Only specified top level paths are to be imported
3347 dpurdie 913
            #   Special mergePath names
914
            #       ++              - All files and directories
915
            #       +               - All files in the root
916
            #       path/**         - Keep all items under path
917
            #       Otherwise       - name of a directory
2764 dpurdie 918
            #
919
            if ( $opt_mergePaths )
920
            {
921
                my $discard = 1;
922
                foreach ( split(',', $opt_mergePaths) )
923
                {
3347 dpurdie 924
                    next if ( m ~\*\*$~ );
925
                    if ( $_ eq '++' )
2764 dpurdie 926
                    {
3347 dpurdie 927
                        $discard = 0;
928
                        last;
929
                    }
930
                    elsif ( $_ eq '+' )
931
                    {
2764 dpurdie 932
                        if ( ($file =~ tr~/~/~) eq 0 )
933
                        {
934
                            $discard = 0;
935
                            last;
936
                        }
937
                    }
938
                    elsif ( $file =~ m~^$_/~ )
939
                    {
940
                        $discard = 0;
941
                        last;
942
                    }
943
                }
4086 dpurdie 944
                Verbose0("Not Importing: $file") if ( $discard ) ;
2764 dpurdie 945
                next if ( $discard );
946
            }
947
 
311 dpurdie 948
            my $src = "$opt_dir/$file";
949
            my $target = "$opt_workdir/$file";
2764 dpurdie 950
            $filesAdded++ unless ( $file =~ m~/$~ );
951
            $dirsAdded++ if ( $file =~ m~/$~ );
952
            push @processedFiles, $file;
311 dpurdie 953
 
954
            if ( -d $src )
955
            {
4086 dpurdie 956
                Verbose0("Adding directory: $file");
311 dpurdie 957
                mkdir ( $target ) unless (-d $target);
958
            }
959
            else
960
            {
961
 
962
                my $path = dirname ( $target);
963
                mkdir ( $path ) unless (-d $path);
964
 
4086 dpurdie 965
                Verbose0("Adding $file");
311 dpurdie 966
                unless (File::Copy::copy( $src, $target ))
967
                {
968
                    Error("Failed to transfer file [$file]: $!");
969
                }
970
            }
971
        }
2764 dpurdie 972
        @added = @processedFiles;
973
 
311 dpurdie 974
        #
975
        #   Inform Subversion about the added files
976
        #   The command line does have a finite length, so add them 200 at a
977
        #   time.
978
        #
979
 
980
        my $base = 0;
981
        my $num = $#added;
2764 dpurdie 982
        Message ("Update the workspace: Added $filesAdded Files, $dirsAdded directories");
311 dpurdie 983
 
984
        while ( $base <= $num )
985
        {
986
            my $end = $base + 200;
987
            $end = $num if ( $end > $num );
988
 
989
            $svn->SvnCmd ( 'add'
990
                            , '--depth=empty'
991
                            , '--parents'
379 dpurdie 992
                            , map ("$opt_workdir/$_@", @added[$base .. $end] ),
311 dpurdie 993
                            { 'error' => 'Adding files to workspace' } );
994
 
995
            $base = $end + 1;
996
        }
997
    }
998
 
999
    #
1000
    #   The common files may have changed
1001
    #   Simply copy them all in and let subversion figure it out
1002
    #
1003
    foreach my $file ( sort keys %common  )
1004
    {
1005
        my $src = "$opt_dir/$file";
1006
        my $target = "$opt_workdir/$file";
1007
 
2764 dpurdie 1008
        $filesTransferred++ unless ( $file =~ m~/$~ );
1009
        $dirsTransferred++ if ( $file =~ m~/$~ );
1010
 
311 dpurdie 1011
        next if ( -d $src );
1012
        if ( File::Compare::compare ($src, $target) )
1013
        {
1014
            Verbose ("Transfer $file");
1015
            unlink $target;
1016
            unless (File::Copy::copy( $src, $target ))
1017
            {
1018
                Error("Failed to transfer file [$file]: $!",
1019
                      "Src: $src",
1020
                      "Tgt: $target");
1021
            }
1022
        }
1023
    }
2764 dpurdie 1024
    Message ("Update the workspace: Transferred $filesTransferred Files, $dirsTransferred directories")
1025
        if ($filesTransferred);
311 dpurdie 1026
 
1027
    #
1028
    #   Commit the workspace
1029
    #   This will go back onto the trunk
1030
    #
2429 dpurdie 1031
    if ( $opt_commit )
1032
    {
1033
        $svn = NewSessionByWS( $opt_workdir );
1034
        my $pkgPath = $svn->Path();
387 dpurdie 1035
 
2429 dpurdie 1036
        my $ciComment = "$pkgPath: Checkin by Svn Import";
1037
        $ciComment .= "\n" . $opt_log if ( $opt_log );
1038
        $ciComment =~ s~\r\n~\n~g;
1039
        $ciComment =~ s~\r~\n~g;
1040
        $ciComment = encode('UTF-8', $ciComment, Encode::FB_DEFAULT);
387 dpurdie 1041
 
2429 dpurdie 1042
        $svn->SvnCi ('comment' => $ciComment, 'allowSame' => 1 );
1043
        Message ("Repository Ref: " . $svn->RmRef) unless( $opt_label );
4076 dpurdie 1044
        unless ($svn->{NoRepoChanges}) {
1045
            $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
1046
            $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
1047
        }
2429 dpurdie 1048
 
1049
        #
1050
        #   Label the result
1051
        #   The workspace will have been updated, so we can use it as the base for
1052
        #   the labeling process
1053
        #
1054
        if ( $opt_label )
1055
        {
4076 dpurdie 1056
            my $tagComment = "$pkgPath: Tagged by Jats Svn Import";
1057
            if ($svn->{NoRepoChanges} && $opt_log )
1058
            {
1059
                $tagComment .= "\nNo Repository changes on last commit. Comment was:";
1060
                $tagComment .= "\n" . $opt_log;
1061
                $tagComment =~ s~\r\n~\n~g;
1062
                $tagComment =~ s~\r~\n~g;
1063
                $tagComment = encode('UTF-8', $tagComment, Encode::FB_DEFAULT);
1064
            }
2429 dpurdie 1065
            $svn->SvnCopyWs (
1066
                           target => $url_label,
1067
                           'noswitch' => 1,
1068
                           'replace' => $opt_replace,
4076 dpurdie 1069
                           'comment' => $tagComment,
2429 dpurdie 1070
                           );
1071
            Message ("Repository Ref: " . $svn->RmRef);
1072
            Message ("Vcs Tag       : " . $svn->SvnTag);
1073
            $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
1074
            $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
1075
        }
311 dpurdie 1076
    }
2429 dpurdie 1077
    else
1078
    {
1079
        Message ("Workspace not commited","Workspace: $opt_workdir");
1080
    }
311 dpurdie 1081
 
1082
    #
1083
    #   Clean up
1084
    #
2429 dpurdie 1085
    if ( $opt_delete && ! $opt_reuse  && $opt_commit )
311 dpurdie 1086
    {
1087
        Message ("Delete Workspace");
1088
        rmtree( $opt_workdir );
1089
    }
379 dpurdie 1090
 
1091
    #
1092
    #   Automation data transfer
1093
    #
1094
    if ( defined $opt_datafile )
1095
    {
1096
        my $data = JatsProperties::New();
1097
 
1098
        $data->setProperty('Command'        , 'ImportPackage');
1099
        $data->setProperty('Label'          , $opt_label);
1403 dpurdie 1100
        $data->setProperty('subversion.url' , $svn->RmRef);
1101
        $data->setProperty('subversion.tag' , $svn->SvnTag);
379 dpurdie 1102
 
2764 dpurdie 1103
        $data->setProperty('files.base'     , $filesBase);
1104
        $data->setProperty('files.removed'  , $filesDeleted);
1105
        $data->setProperty('files.added'    , $filesAdded);
1106
 
379 dpurdie 1107
        $data->Dump('InfoFile') if ($opt_verbose);
1108
        $data->store( $opt_datafile );
1109
    }
1110
 
311 dpurdie 1111
    $opr_done = 1;
1112
}
1113
 
1114
#-------------------------------------------------------------------------------
385 dpurdie 1115
# Function        : DeleteBranch
1116
#
1117
# Description     : Delete the branch that a workspace is based upon
1118
#
2049 dpurdie 1119
# Inputs          :
385 dpurdie 1120
#
2049 dpurdie 1121
# Returns         :
385 dpurdie 1122
#
1123
sub DeleteBranch
1124
{
1125
    my $opt_path;
1126
    my $opt_error = 0;
1127
    #
1128
    #   Parse more options
1129
    #
1130
    GetOptions (
1131
                "help:+"        => \$opt_help,
1132
                "manual:3"      => \$opt_help,
1133
                "path:s"        => \$opt_path,
1134
                ) || Error ("Invalid command line" );
1135
 
1136
    #
1137
    #   Subcommand specific help
1138
    #
1139
    SubCommandHelp( $opt_help, "Delete Branch") if ($opt_help);
1140
 
1141
    #
1142
    #   Sanity Tests
1143
    #
2429 dpurdie 1144
    Message ("Delete Workspace Branchs" );
385 dpurdie 1145
 
1146
    #
1147
    #   Do all the hard work
1148
    #
1149
    $opt_path = '.' unless ( defined $opt_path );
1150
    my $uref = NewSessionByWS($opt_path, 0, 1);
1151
    my $ws_root = $uref->SvnLocateWsRoot(1);
1152
    my $ws_url = $uref->FullWs();
1153
 
1154
    #
2931 dpurdie 1155
    #   What we do depends what arguments the user provided
385 dpurdie 1156
    #
2429 dpurdie 1157
    unless ( @ARGV )
1158
    {
1159
        #
1160
        #   If no branch was specified - then display the workspace branch
1161
        #
1162
        Error ('The workspace is not based on a branch')
1163
            unless ( $ws_url =~ m ~/branches/(.*)~ );
1164
        Message('The workspace is based on the branch: '. $1);
1165
    }
1166
    else
1167
    {
1168
        #
1169
        #   Delete all specified branches
1170
        #
1171
        foreach my $branch ( @ARGV )
1172
        {
1173
            Message ("Deleting: " . $branch );
1174
            my $target = join( '/', $uref->FullPath(), 'branches', $branch);
1175
            if ( $uref->SvnDelete (
1176
                              'target'    => $target,
1177
                              'comment'   => [$uref->Path().": Delete Branch",'Deleted by user command: jats svn delete-branch'],
1178
                              'noerror'   => 1,
1179
                              )
1180
               )
1181
            {
1182
                Warning ("Branch deletion failed: $branch");
1183
            }
1184
        }
1185
    }
385 dpurdie 1186
    $opr_done = 1;
1187
}
1188
 
2049 dpurdie 1189
#-------------------------------------------------------------------------------
1190
# Function        : CreateBranch
1191
#
1192
# Description     : Branch a workspace and then switch to the new branch
1193
#
1194
# Inputs          :
1195
#
1196
# Returns         :
1197
#
1198
sub CreateBranch
1199
{
1200
    my $opt_path;
1201
    my $opt_comment;
1202
    my $opt_switch = 1;
1203
    my $opt_branch;
385 dpurdie 1204
 
2049 dpurdie 1205
    #
1206
    #   Parse more options
1207
    #
1208
    GetOptions (
1209
                "help:+"        => \$opt_help,
1210
                "manual:3"      => \$opt_help,
1211
                "path:s"        => \$opt_path,
1212
                "switch!"       => \$opt_switch,
1213
                "comment:s"     => \$opt_comment,
1214
                ) || Error ("Invalid command line" );
1215
 
1216
    #
1217
    #   Subcommand specific help
1218
    #
1219
    SubCommandHelp( $opt_help, "Create Branch") if ($opt_help);
1220
 
1221
    #
1222
    #   Sanity Tests
1223
    #
1224
    Message ("Create Workspace Branch" );
1225
    Error ("Too many arguments: @ARGV") if ( $#ARGV > 0 );
1226
    Error ("Not enough arguments. No branch name specified") if ( $#ARGV < 0 );
1227
 
1228
    #
1229
    #   Sanity test the label
1230
    #
1231
    $opt_branch = SvnIsaSimpleLabel ($ARGV[0] );
1232
 
1233
    #
1234
    #   Do all the hard work
1235
    #
1236
    $opt_path = '.' unless ( defined $opt_path );
1237
    my $uref = NewSessionByWS($opt_path, 0, 1);
1238
    my $ws_root = $uref->SvnLocateWsRoot(1);
1239
    my $ws_url = $uref->Full();
1240
 
1241
    #
2931 dpurdie 1242
    #   Use the version of the branch that has been committed as the base of the
1243
    #   copy. If the user has modified files, then they won't be committed
2049 dpurdie 1244
    #
1245
    #   This operation will be server-side only
1246
    #
1247
    Message ("Creating branch: $opt_branch");
1248
    my $repoLink = $uref->{InfoWs}{URL} . '@' . $uref->{InfoWs}{Revision};
1249
    $uref->{DEVBRANCH} =  join ('/', 'branches', $opt_branch);
1250
    my $branch_tag = $uref->SvnCopy (
1251
                'old' => $repoLink,
1252
                'new' => join ('/', $ws_url, $uref->{DEVBRANCH} ),
1253
                'comment' => $opt_comment ? $opt_comment : 'Created by Jats svn branch',
1254
                'replace' => 0,
1255
                );
1256
 
2054 dpurdie 1257
 
2049 dpurdie 1258
    if ( $opt_switch )
1259
    {
1260
        Verbose ("Switching to new branch: $opt_branch");
1261
        $branch_tag = SvnPath2Url($branch_tag);
2054 dpurdie 1262
        chdir ($ws_root) || Error ("Cannot cd to: " .$ws_root);
1263
        $uref->SvnSwitch ($branch_tag, $opt_path, '--Print', '--KeepWs' );
2049 dpurdie 1264
    }
1265
    else
1266
    {
1267
        Warning ("Using existing workspace, not the created branch");
1268
    }
1269
    Message ("Repository Ref: " . $uref->RmRef);
1270
    Message ("Vcs Tag       : " . $uref->SvnTag);
1271
 
1272
#    #
1273
#    #   The copy operation *should* be a server side operation only
2931 dpurdie 1274
#    #   If the user has committed changes, but not yet updated the local
2049 dpurdie 1275
#    #   workspace, then subversion will do a client side copy
1276
#    #   This is not good.
1277
#    #
1278
#    $uref->SvnCopyWs (
1279
#                   target => join ('/', $ws_url, 'branches', $opt_branch),
1280
#                   'allowLocalMods' => 1,
1281
#                   'noupdatecheck' => 1,
1282
#                   'noswitch' => ! $opt_switch,
1283
#                   'replace' => 0,
1284
#                   'comment' => $opt_comment ? $opt_comment : 'Created by Jats svn branch',
1285
#                   );
1286
#
1287
#    Message ("Repository Ref: " . $uref->RmRef);
1288
#    Message ("Vcs Tag       : " . $uref->SvnTag);
1289
 
1290
    $opr_done = 1;
1291
}
1292
 
385 dpurdie 1293
#-------------------------------------------------------------------------------
2049 dpurdie 1294
# Function        : SwitchBranch
1295
#
1296
# Description     : Switch to a specified branch
1297
#
1298
# Inputs          :
1299
#
1300
# Returns         :
1301
#
1302
sub SwitchBranch
1303
{
1304
    my $opt_path = '.';
1305
    my $opt_branch;
1306
 
1307
    #
1308
    #   Parse more options
1309
    #
1310
    GetOptions (
1311
                "help:+"        => \$opt_help,
1312
                "manual:3"      => \$opt_help,
1313
                "path:s"        => \$opt_path,
1314
                ) || Error ("Invalid command line" );
1315
 
1316
    #
1317
    #   Subcommand specific help
1318
    #
1319
    SubCommandHelp( $opt_help, "Switch Branch") if ($opt_help);
1320
    return ShowBranches($opt_path) if ( $#ARGV < 0 );
1321
 
1322
    #
1323
    #   Sanity Tests
1324
    #
1325
    Error ("Too many arguments: @ARGV") if ( $#ARGV > 0 );
1326
 
1327
    #
1328
    #   Calculate the target name
1329
    #       trunk is special
1330
    #       tags/... is special
1331
    $opt_branch = $ARGV[0];
1332
    if ( $opt_branch eq 'trunk' ) {
1333
    } elsif ( $opt_branch =~ m~tags/.+~ ) {
1334
    } else {
1335
        $opt_branch = join ('/', 'branches', $opt_branch);
1336
    }
1337
    Message ("Switching to new branch: $opt_branch");
1338
 
1339
    #
1340
    #   Do all the hard work
1341
    #
1342
    my $uref = NewSessionByWS($opt_path, 0, 1);
2054 dpurdie 1343
    my $ws_root = $uref->SvnLocateWsRoot(1);
2049 dpurdie 1344
    my $ws_url = $uref->Full();
1345
    my $branch_tag = join ('/', $ws_url, $opt_branch);
1346
 
1347
    #
1348
    #   Validate the branch
1349
    #
1350
    $uref->SvnValidateTarget (
1351
                        'cmd'    => 'svn switch',
1352
                        'target' => $branch_tag,
1353
                        'require' => 1,
1354
                        );
1355
 
2054 dpurdie 1356
    #
1357
    #   Must Change directory before we switch
2931 dpurdie 1358
    #   Otherwise we will import changes into the wrong place
2054 dpurdie 1359
    #
1360
    chdir ($ws_root) || Error ("Cannot cd to: " . $ws_root);
1361
    $uref->SvnSwitch ($branch_tag, $opt_path, '--Print', '--KeepWs' );
2049 dpurdie 1362
    $opr_done = 1;
1363
}
1364
 
1365
#-------------------------------------------------------------------------------
1366
# Function        : ShowBranches
1367
#
1368
# Description     : Show branches in current workspace
1369
#                   Internal use only
1370
#
1371
# Inputs          : $opt_path           - Optional path
1372
#
1373
# Returns         :
1374
#
1375
sub ShowBranches
1376
{
1377
    my ($opt_path) = @_;
1378
 
1379
    my $uref = NewSessionByWS($opt_path, 0, 1);
1380
    my $ws_url = $uref->Full();
1381
 
1382
    #
2931 dpurdie 1383
    #   Display the packages full URL - allow the user to manually look at more
1384
    #   List the branches
2049 dpurdie 1385
    #
1386
    Message ("Url: $ws_url", 'Available Branches');
1387
    SvnUserCmd( 'ls', join ('/', $ws_url, 'branches'), { 'credentials' => 1 });
1388
    $opr_done = 1;
1389
}
1390
#-------------------------------------------------------------------------------
311 dpurdie 1391
# Function        : SubCommandHelp
1392
#
1393
# Description     : Provide help on a subcommand
1394
#
1395
# Inputs          : $help_level             - Help Level 1,2,3
1396
#                   $topic                  - Topic Name
1397
#
1398
# Returns         : This function does not return
1399
#
1400
sub SubCommandHelp
1401
{
1402
    my ($help_level, $topic) = @_;
1403
    my @sections;
1404
    #
1405
    #   Spell out the section we want to display
1406
    #
1407
    #   Note:
1408
    #   Due to bug in pod2usage can't use 'head1' by itself
1409
    #   Each one needs a subsection.
1410
    #
1411
    push @sections, qw( NAME SYNOPSIS ) ;
1412
    push @sections, qw( ARGUMENTS OPTIONS ) if ( $help_level > 1 );
1413
    push @sections, qw( DESCRIPTION )       if ( $help_level > 2 );
1414
 
1415
    #
1416
    #   Extract section from the POD
1417
    #
1418
    pod2usage({-verbose => 99,
1419
               -noperldoc => 1,
1420
               -sections => $topic . '/' . join('|', @sections) } );
1421
}
1422
 
1423
#-------------------------------------------------------------------------------
1424
#   Documentation
1425
#   NOTE
1426
#
1427
#   Each subcommand MUST have
1428
#   head1 section as used by the subcommand
1429
#       This should be empty, as the contents will NOT be displayed
1430
#   head2 sections called
1431
#       NAME SYNOPSIS ARGUMENTS OPTIONS DESCRIPTION
1432
#
1433
#=head1 xxxxxx
1434
#=head2 NAME
1435
#=head2 SYNOPSIS
1436
#=head2 ARGUMENTS
1437
#=head2 OPTIONS
1438
#=head2 DESCRIPTION
1439
#
1440
 
1441
=pod
1442
 
361 dpurdie 1443
=for htmltoc    GENERAL::Subversion::
1444
 
311 dpurdie 1445
=head1 NAME
1446
 
1447
jats svn - Miscellaneous SubVersion Operations
1448
 
1449
=head1 SYNOPSIS
1450
 
1451
jats svn [options] command [command options]
1452
 
1453
 Options:
1454
    -help[=n]              - Help message, [n=1,2,3]
1455
    -man                   - Full documentation [-help=3]
1456
    -verbose[=n]           - Verbose command operation
1457
 
1458
 Common Command Options:
1459
    All command support suboptions to provide command specific help
1460
 
1461
    -help[=n]              - Help message, [n=1,2,3]
1462
    -man                   - Full documentation [-help=3]
1463
 
1464
 Commands are:
363 dpurdie 1465
    test                   - Test access to subversion
369 dpurdie 1466
    paths                  - Display Subversion tag to URL conversions
311 dpurdie 1467
    ls URL                 - List Repo contents for URL
369 dpurdie 1468
    tag [URL]              - Convert URL or Path to a Release Manager Tag
1469
    url [TAG]              - Convert TAG or Path to a Subversion URL
2049 dpurdie 1470
    create-package URL     - Create a new package at URL
311 dpurdie 1471
    delete-package URL     - Delete Package Subtree
2049 dpurdie 1472
    branch BRANCH          - Create a Development Branch
1473
    switch [BRANCH]        - Switch to a Development Branch
385 dpurdie 1474
    delete-branch          - Delete a Development Branch
311 dpurdie 1475
    import URL             - Import files to package at URL
1476
 
1477
 Use the command
1478
    jats svn command -h
1479
 for command specific help
1480
 
1481
=head1 OPTIONS
1482
 
1483
=over
1484
 
1485
=item B<-help[=n]>
1486
 
1487
Print a help message and exit. The level of help may be either 1, 2 or
1488
3 for a full manual.
1489
 
1490
This option may be specified multiple times to increment the help level, or
1491
the help level may be directly specified as a number.
1492
 
1493
=item B<-man>
1494
 
1495
This is the same as '-help=3'.
1496
The complete help is produced in a man page format.
1497
 
2429 dpurdie 1498
=item B<-verbose[=n]>
311 dpurdie 1499
 
1500
This option will increase the level of verbosity of the commands.
1501
 
1502
If an argument is provided, then it will be used to set the level, otherwise the
1503
existing level will be incremented. This option may be specified multiple times.
1504
 
1505
=back
1506
 
1507
=head1 DESCRIPTION
1508
 
1509
This program provides a number of useful Subversion based operations.
1510
 
363 dpurdie 1511
=head1 Test Subversion
1512
 
1513
=head2 NAME
1514
 
1515
Test Subversion
1516
 
1517
=head2 SYNOPSIS
1518
 
1519
    jats svn test
1520
 
1521
=head2 DESCRIPTION
1522
 
1523
This command will ensure that the subversion command line utility can be
1524
located. The command will report the version of the svn client found.
1525
 
369 dpurdie 1526
=head1 Subversion Paths
1527
 
1528
=head2 NAME
1529
 
1530
Subversion Paths
1531
 
1532
=head2 SYNOPSIS
1533
 
1534
    jats svn paths
1535
 
1536
=head2 DESCRIPTION
1537
 
1538
This command will display the base Tags and associated URLs that are used by
1539
JATS to convert a 'Subversion Tag' into a full URLs that will be used to access
1540
a physical repository.
1541
 
1542
The 'Tags' configuration is site-specific.
1543
 
311 dpurdie 1544
=head1 List Repository
1545
 
363 dpurdie 1546
=head2 NAME
1547
 
1548
List Repository
1549
 
1550
=head2 SYNOPSIS
1551
 
1552
    jats svn ls <URL>
1553
 
1554
=head2 DESCRIPTION
1555
 
311 dpurdie 1556
This command will take a URL and perform a 'svn' list operation. The URL will
1557
be expanded to include the site specific repository.
1558
 
369 dpurdie 1559
=head1 Url to Tag
1560
 
1561
=head2 NAME
1562
 
1563
Url to Tag
1564
 
1565
=head2 SYNOPSIS
1566
 
1567
    jats svn tag [Option] [tag]
1568
 
1569
 Options:
1570
    -help[=n]              - Help message, [n=1,2,3]
1571
    -man                   - Full documentation [-help=3]
1572
    -path=path             - Convert specified path
1573
    -url=url               - Convert specified URL
1574
 
1575
=head2 DESCRIPTION
1576
 
1577
This command will convert a URL or a PATH to a Subversion Tag that can
1578
be used within the remainder of the build system. If no PATH or URL is provided,
1579
then the command uses a path of the current directory.
1580
 
1581
The command will convert either a PATH or a URL. It will not do both.
1582
 
1583
The command will use the configured Subversion URL prefixes to create the Tag.
1584
 
1585
If a PATH is to be converted, then the PATH must address a Subversion workspace.
1586
The conversion will return a Tag to the root of the Workspace and Peg it to
1587
the last committed version. The command will not determine if the workspace
1588
contains modified files.
1589
 
1590
If a URL is to be converted, then the resultant value should be used with
1591
caution. The result is only as good as the provided URL and may not address
1592
the root of a package.
1593
 
1594
=head1 Tag to Url
1595
 
1596
=head2 NAME
1597
 
1598
Tag to Url
1599
 
1600
=head2 SYNOPSIS
1601
 
1602
    jats svn url [Option] [url]
1603
 
1604
 Options:
1605
    -help[=n]              - Help message, [n=1,2,3]
1606
    -man                   - Full documentation [-help=3]
1607
    -path=path             - Convert specified path
1608
    -url=url               - Convert specified URL
1609
 
1610
=head2 DESCRIPTION
1611
 
1612
This command will convert a TAG or a PATH to a full URL that can be used
1613
directly by Subversion. If no PATH or TAG is provided, then the command uses a
1614
path of the current directory.
1615
 
2429 dpurdie 1616
The command will convert either a TAG or a PATH. It will not do both.
369 dpurdie 1617
 
1618
The command will use the configured Subversion URL prefixes to expand the TAG.
1619
 
1620
If a PATH is to be converted, then the PATH must address a Subversion workspace.
1621
The conversion will return a URL to the root of the Workspace and Peg it to
1622
the last committed version. The command will not determine if the workspace
1623
contains modified files.
1624
 
1625
If a TAG is to be converted, then the resultant value should be used with
1626
caution. The result is only as good as the provided URL and may not address
1627
the root of a package.
1628
 
2429 dpurdie 1629
=head3 Examples
1630
 
1631
To display the URL of the current workspace
1632
 
1633
    jats svn url
1634
 
1635
To display the URL of a known workspace
1636
 
1637
    jats svn url -path=myWorkSpace
1638
 
1639
To convert a TAG from Release Manager or other JATS commands
1640
 
1641
    jats svn url AUPERASVN01/COTS
1642
    jats svn url SVN::AUPERASVN01/COTS/bouncycastle/trunk::bouncycastle_1.3.1.cots@502
1643
 
2049 dpurdie 1644
=head1 Create a Package Version
1645
 
1646
=head2 NAME
1647
 
1648
Create a Package Version
1649
 
1650
=head2 SYNOPSIS
1651
 
1652
jats svn [options] create-package URL [command options]
1653
 
1654
 Options:
1655
    -help[=n]               - Help message, [n=1,2,3]
1656
    -man                    - Full documentation [-help=3]
1657
    -verbose[=n]            - Verbose command operation
1658
 
1659
 Command Options
1660
    -help[=n]               - Provide command specific help
1661
    -new                    - Package must not exist
1662
    -replace                - Replace any existing versions
2429 dpurdie 1663
    -import=path            - Import directory tree
2049 dpurdie 1664
    -label=nnn              - Label imported package
1665
    -trunk                  - Import to trunk (default)
1666
    -tags=nnn               - Import to tags
1667
    -branch=nnn             - Import to branches
1668
 
1669
=head2 ARGUMENTS
1670
 
1671
The command takes one argument: The URL of the desired package.
1672
This may be be:
1673
 
1674
=over
1675
 
1676
=item * A full URL
1677
 
1678
Complete with protocol and path information.
1679
 
1680
=item * A simple URL
1681
 
1682
JATS will prepend the site-specific repository location to the user provided URL
1683
 
1684
=back
1685
 
1686
=head2 OPTIONS
1687
 
1688
=over
1689
 
1690
=item -help[=n]
1691
 
1692
Print a help message and exit. The level of help may be either 1, 2 or 3.
1693
 
1694
This option may be specified multiple times to increment the help level, or
1695
the help level may be directly specified as a number.
1696
 
1697
=item -new
1698
 
1699
This option specifies that the named package MUST not exist at all.
1700
 
1701
=item -replace
1702
 
1703
This option allows the program to replace any existing versions of the
1704
imported source. It will allow the deletion of any existing trunk, tags or
1705
branches.
1706
 
2429 dpurdie 1707
=item -import=path
2049 dpurdie 1708
 
1709
This option specifies the path of a subdirectory tree to import into the newly
1710
created package. In not provided, then only a package skeleton will be created.
1711
 
2429 dpurdie 1712
All files and directories below, but not including, the named path will be
1713
imported into the package.
1714
 
4096 dpurdie 1715
The imported directory tree will be scanned to ensure that the following subdirectories
1716
do not exist: .svn, .hg, .git, .cvs, tags, trunk and branches. These directories are
1717
either reserved or indicative that the import tree is already version controlled.
1718
 
2049 dpurdie 1719
=item -label=nnn
1720
 
1721
This option specifies a label to place the imported source.
1722
 
1723
=item -trunk
1724
 
1725
This option specifies that imported source will be placed on the trunk of the
1726
package. This is the default mode of import.
1727
 
1728
The options -trunk, -tags and -branch are mutually exclusive.
1729
 
1730
=item -tags=nnn
1731
 
1732
This option specifies that imported source will be placed directly on the
1733
named tag of the package.
1734
 
1735
The options -trunk, -tags and -branch are mutually exclusive.
1736
 
1737
=item -branch=nnn
1738
 
1739
This option specifies that imported source will be placed directly on the
1740
named branch of the package.
1741
 
1742
The options -trunk, -tags and -branch are mutually exclusive.
1743
 
1744
=back
1745
 
1746
=head2 DESCRIPTION
1747
 
1748
This command will create a new package within a repository. It will ensure
1749
that the package contains the three required subdirectories: trunk, tags and
1750
branches.
1751
 
1752
The command will also ensure that packages are not placed at inappropriate
1753
locations within the repository. It is not correct to place a package within
1754
another package.
1755
 
1756
The command will, optionally, import a directory tree into the repository and,
1757
optionally, label the package.
1758
 
1759
The package body may be imported to the 'trunk' or to a branch or a tag.
1760
By default the data will be imported to the trunk and may be labeled (tagged).
1761
 
1762
Options allow the targets to be deleted if they exist or to ensure that they
1763
are not present.
1764
 
1765
The command does not attempt to merge file versions within the repository. It
1766
may result in multiple instances of a file within the repository. Use only for
1767
simple imports. Use the 'import' command for more sophisticated import requirements.
1768
 
2429 dpurdie 1769
=head3 Examples
1770
 
1771
To create a package skeleton in the Perth MREF_Package repository for a package
1772
called 'VIXmyPackage':
1773
 
1774
    jats svn create-package AUPERASVN01/MREF_Package/VIXmyPackage
1775
 
1776
To create a package skeleton in the Perth MREF_Package repository, import code
1777
into the trunk of the package and label (tag) it:
1778
 
1779
    jats svn create-package \
1780
           AUPERASVN01/MREF_Package/VIXmyPackage \
1781
           -import=VIXmyNewPackage \
1782
           -label=VIXmyPackage.WIP
1783
 
311 dpurdie 1784
=head1 Delete a Package
1785
 
1786
=head2 NAME
1787
 
1788
Delete a Package
1789
 
1790
=head2 SYNOPSIS
1791
 
1792
jats svn delete-package URL [options]
1793
 
1794
 Options:
1795
    -help[=n]              - Help message, [n=1,2,3]
1796
    -man                   - Full documentation [-help=3]
1797
    -verbose[=n]           - Verbose command operation
1798
 
1799
=head2 ARGUMENTS
1800
 
1801
The command takes one argument: The URL of the desired package.
1802
This may be be:
1803
 
1804
=over
1805
 
1806
=item * A full URL
1807
 
1808
Complete with protocol and path information.
1809
 
1810
=item * A simple URL
1811
 
1812
JATS will prepend the site-specific repository location to the user provided URL
1813
 
1814
=back
1815
 
1816
=head2 OPTIONS
1817
 
1818
This command has no significant options, other than the general help options.
1819
 
1820
=head2 DESCRIPTION
1821
 
1822
This command will delete a package from the repository. It will ensure
1823
that the package is a valid package, before it is deleted.
1824
 
1825
The command is intended to be used by test scripts, rather than users.
1826
 
2049 dpurdie 1827
=head1 Create Branch
385 dpurdie 1828
 
1829
=head2 NAME
1830
 
2049 dpurdie 1831
Create a Workspace Branch
385 dpurdie 1832
 
1833
=head2 SYNOPSIS
1834
 
2049 dpurdie 1835
jats svn branch branch-name [options]
385 dpurdie 1836
 
1837
 Options:
1838
    -help[=n]              - Help message, [n=1,2,3]
1839
    -man                   - Full documentation [-help=3]
1840
    -verbose[=n]           - Verbose command operation
1841
    -path=path             - Target workspace
2049 dpurdie 1842
    -[no]switch            - Switch to new branch(default)
1843
    -comment=text          - Comment to apply to the new branch
385 dpurdie 1844
 
1845
=head2 ARGUMENTS
1846
 
2049 dpurdie 1847
The command takes one argument. The name of the branch to be created.
385 dpurdie 1848
 
1849
=head2 OPTIONS
1850
 
1851
=over
1852
 
1853
=item B<-path=path>
1854
 
1855
This options specifies the path of the target workspace. If not provided the
1856
command will use the current directory.
1857
 
2049 dpurdie 1858
=item B<-[no]switch>
1859
 
1860
If enabled (the default) the workspace will be switched to the new branch at
1861
the end of the process.
1862
 
1863
=item B<-comment=text>
1864
 
1865
If present, the specified text will be used as a Subversion comment when the
1866
branch is created.
1867
 
1868
If not provided, then JATS will provide a basic comment.
1869
 
385 dpurdie 1870
=back
1871
 
1872
=head2 DESCRIPTION
1873
 
2049 dpurdie 1874
This command will create a named branch associated with the workspace in the
1875
specified path. It is intended to simplify the creation of Private or
385 dpurdie 1876
Development branches.
1877
 
2049 dpurdie 1878
If the named branch already exists, then the command will fail.
385 dpurdie 1879
 
2049 dpurdie 1880
The command performs a server-side copy. It will not commit any locally
1881
modified files. Nor will it inform you if there are any.
311 dpurdie 1882
 
2049 dpurdie 1883
By default, the user is 'switched' to the newly created branch.
1884
 
1885
=head1 Switch Branch
1886
 
311 dpurdie 1887
=head2 NAME
1888
 
2049 dpurdie 1889
Switch a Workspace Branch
311 dpurdie 1890
 
1891
=head2 SYNOPSIS
1892
 
2049 dpurdie 1893
jats svn switch [branch-name] [options]
311 dpurdie 1894
 
1895
 Options:
2049 dpurdie 1896
    -help[=n]              - Help message, [n=1,2,3]
1897
    -man                   - Full documentation [-help=3]
1898
    -verbose[=n]           - Verbose command operation
1899
    -path=path             - Target workspace
311 dpurdie 1900
 
1901
=head2 ARGUMENTS
1902
 
2049 dpurdie 1903
The command takes one optional argument. The name of the target branch.
311 dpurdie 1904
 
2049 dpurdie 1905
=head2 OPTIONS
1906
 
311 dpurdie 1907
=over
1908
 
2049 dpurdie 1909
=item B<-path=path>
311 dpurdie 1910
 
2049 dpurdie 1911
This options specifies the path of the target workspace. If not provided the
1912
command will use the current directory.
311 dpurdie 1913
 
2049 dpurdie 1914
=back
311 dpurdie 1915
 
2049 dpurdie 1916
=head2 DESCRIPTION
311 dpurdie 1917
 
2049 dpurdie 1918
This command will switch the users workspace to the named branch. This is
1919
identical to the Subversion switch command, except it is easier to user and
1920
has several validity checks and other enhancements.
311 dpurdie 1921
 
2049 dpurdie 1922
The command has two modes of operation:
311 dpurdie 1923
 
2049 dpurdie 1924
=over 4
311 dpurdie 1925
 
2049 dpurdie 1926
=item   1. Display a list of branched in the current package.
311 dpurdie 1927
 
2049 dpurdie 1928
If no branch is specified, then the utility will display a list of branches in
1929
the packages 'branches' directory.
311 dpurdie 1930
 
2049 dpurdie 1931
=item   2. Switch to the named branch.
311 dpurdie 1932
 
2049 dpurdie 1933
The named branch must exists otherwise the command will fail.
311 dpurdie 1934
 
2429 dpurdie 1935
There are two special variants of the branch name:
311 dpurdie 1936
 
2049 dpurdie 1937
=over 4
311 dpurdie 1938
 
2049 dpurdie 1939
=item trunk
311 dpurdie 1940
 
2049 dpurdie 1941
If the branch is named 'trunk' then it will refer to the packages truck
1403 dpurdie 1942
 
2049 dpurdie 1943
=item tags
1403 dpurdie 1944
 
2049 dpurdie 1945
If the branch name starts with 'tags/', then the command will refer to
1946
a tag within the package and not a branch.
1403 dpurdie 1947
 
2049 dpurdie 1948
=back
1403 dpurdie 1949
 
2049 dpurdie 1950
The command will add and remove unmodified files from the workspace during this
1951
operation.
311 dpurdie 1952
 
2049 dpurdie 1953
=back
311 dpurdie 1954
 
2049 dpurdie 1955
=head3 Examples
311 dpurdie 1956
 
2049 dpurdie 1957
To switch to the packages trunk
311 dpurdie 1958
 
2049 dpurdie 1959
    jats svn switch trunk
311 dpurdie 1960
 
2049 dpurdie 1961
To switch to the a branch called MyBranch
311 dpurdie 1962
 
2049 dpurdie 1963
    jats svn switch MyBranch
311 dpurdie 1964
 
2049 dpurdie 1965
To switch to a tagged version of the package
311 dpurdie 1966
 
2049 dpurdie 1967
    jats svn switch tags/MyPackage_1.0.0000.cr
311 dpurdie 1968
 
2049 dpurdie 1969
To display a list of available branches (not tags)
311 dpurdie 1970
 
2049 dpurdie 1971
    jats svn switch
311 dpurdie 1972
 
2049 dpurdie 1973
=head1 Delete Branch
311 dpurdie 1974
 
2049 dpurdie 1975
=head2 NAME
311 dpurdie 1976
 
2049 dpurdie 1977
Delete the Workspace Branch
311 dpurdie 1978
 
2049 dpurdie 1979
=head2 SYNOPSIS
311 dpurdie 1980
 
2429 dpurdie 1981
jats svn delete-branch [options] [branch-list]
311 dpurdie 1982
 
2049 dpurdie 1983
 Options:
1984
    -help[=n]              - Help message, [n=1,2,3]
1985
    -man                   - Full documentation [-help=3]
1986
    -verbose[=n]           - Verbose command operation
1987
    -path=path             - Target workspace
311 dpurdie 1988
 
2049 dpurdie 1989
=head2 ARGUMENTS
1990
 
2429 dpurdie 1991
The command may take zero or more arguments. If provided the arguments will be
1992
branch names to be deleted.
2049 dpurdie 1993
 
1994
=head2 OPTIONS
1995
 
1996
=over
1997
 
1998
=item B<-path=path>
1999
 
2000
This options specifies the path of the target workspace. If not provided the
2001
command will use the current directory.
2002
 
2003
=back
2004
 
2005
=head2 DESCRIPTION
2006
 
2429 dpurdie 2007
This command can display the branch associated with the workspace or it can
2008
delete one or more branches. It is intended to simplify the deletion of Private
2009
or Development branches.
2049 dpurdie 2010
 
2429 dpurdie 2011
=over 4
2012
 
2013
=item 1 Arguments are provided
2014
 
2015
The command will delete all the named branches. If a named branch does not exist
2016
then the command will issue a warning message.
2017
 
2018
=item 2 No arguments provided
2019
 
2020
The command will display the branch associated with the workspace
2021
 
2049 dpurdie 2022
If the workspace is not linked to a 'branch' then the command will fail.
2023
 
2429 dpurdie 2024
=back
2025
 
311 dpurdie 2026
=head1 Import directory to a Package
2027
 
2028
=head2 NAME
2029
 
2030
Import directory to a Package
2031
 
2032
=head2 SYNOPSIS
2033
 
2034
jats svn [options] import URL [command options]
2035
 
2036
 Options:
2037
    -help[=n]               - Help message, [n=1,2,3]
2038
    -man                    - Full documentation [-help=3]
2039
    -verbose[=n]            - Verbose command operation
2040
 
2041
 Command Options
2042
    -help[=n]               - Command specific help, [n=1,2,3]
2043
    -verbose[=n]            - Verbose operation
2044
    -package=name           - Name of source package
2045
    -dir=path               - Path to new version
379 dpurdie 2046
    -label=label            - Label the result
2047
    -branch=branchName      - Base import on a branch
311 dpurdie 2048
    -replace                - Allow the label to be replaced
2049
    -reuse                  - Reuse the import directory
2050
    -workspace=path         - Path and name of alternate workspace
2051
    -[no]delete             - Deletes workspace after use. Default:yes
379 dpurdie 2052
    -author=name            - Force author of changes
2053
    -date=dateString        - Force date of changes
2054
    -log=text               - Append text to the commit message
2055
    -datafile=path          - Export tag data for automation
2931 dpurdie 2056
    -[no]commit             - Prevent changes being committed. Default:Yes
2429 dpurdie 2057
    -printfiles=n           - Control commit verbosity
2931 dpurdie 2058
    -mergePaths=dirList     - Comma separated list of directories to merge
311 dpurdie 2059
 
2060
=head2 ARGUMENTS
2061
 
2062
The command takes one argument: The URL of the desired package.
2063
This may be be:
2064
 
2065
=over
2066
 
2067
=item * A full URL
2068
 
2069
Complete with protocol and path information.
2070
 
2071
=item * A simple URL
2072
 
2073
JATS will prepend the site-specific repository location to the user provided URL
2074
 
2075
=back
2076
 
2077
=head2 OPTIONS
2078
 
2079
=over
2080
 
2081
=item -help[=n]
2082
 
2083
Print a help message and exit. The level of help may be either 1, 2 or 3.
2084
 
2085
This option may be specified multiple times to increment the help level, or
2086
the help level may be directly specified as a number.
2087
 
2088
=item -verbose[=n]
2089
 
2090
This option will increase the level of verbosity of the utility.
2091
 
2092
If an argument is provided, then it will be used to set the level, otherwise the
2093
existing level will be incremented. This option may be specified multiple times.
2094
 
2095
=item -package=name
2096
 
2097
Either this option or a bare URL on the command line must be provided. It
2098
specifies the repository and package to be used as a basis for the work.
2099
 
2100
=item -dir=path
2101
 
2102
This option is mandatory. It specifies the path to a local directory that
2103
contains a version of the software to be checked in.
2104
 
2105
=item -label=name
2106
 
2107
The resulting software version will be labeled with this tag, if it is provided.
2108
 
383 dpurdie 2109
A label name of TIMESTAMP will be treated in special manner. The name will be
2110
replaced with a unique name based on the users name and the current date time.
2111
 
379 dpurdie 2112
=item -branch=branchName
2113
 
2114
This option will cause the importation to be referenced to the named branch.
2115
If the branch does not exist it will be created. If it does exist then it will
2116
be used.
2117
 
2118
If this option is not specified, then the importation will be based on the 'trunk'.
2119
 
2120
If the Workspace is provided, then it will be used independently of this option.
2121
 
383 dpurdie 2122
A branchName of TIMESTAMP will be treated in special manner. The name will be
2123
replaced with a unique name based on the users name and the current date time.
2124
 
311 dpurdie 2125
=item -replace
2126
 
2127
This option, if provided, allows the label to be replaced.
2128
 
2129
=item -reuse
2130
 
2131
This option can be used to speed the creation of multiple versions in a scripted
2132
environment. The option allows the utility to reuse the workspace if it exists.
2133
 
2134
=item -workspace=path
2135
 
2136
This option specifies an alternate workspace directory to create and use. The
2137
default directory is "SvnImportDir" within the users current directory.
2138
 
2139
=item [no]delete
2140
 
341 dpurdie 2141
This option control the deletion of the workspace directory. By default the
311 dpurdie 2142
directory will be deleted, unless re-use is also used.
2143
 
379 dpurdie 2144
=item -author=name
2145
 
2146
This option will force the author of changes as recorded in the repository.
385 dpurdie 2147
The repository must be configured to allow such changes.
379 dpurdie 2148
 
2149
This option may not work for non-admin users.
2150
 
2151
=item -date=dateString
2152
 
2153
This option will force the date of the changes as recorded in the repository.
385 dpurdie 2154
The repository must be configured to allow such changes.
379 dpurdie 2155
The dateString is in a restricted ISO 8601 format: ie 2009-02-12T00:44:04.921324Z
2156
 
2157
This option may not work for non-admin users.
2158
 
2159
=item -log=text
2160
 
2161
This option will append the specified text to the commit message.
2162
The first line of the commit message is fixed by the import tool.
2163
 
2164
=item -datafile=path
2165
 
2166
This option will cause the utility to create a data file to record the import
2167
tag. It is used for automation of the import process.
2168
 
2429 dpurdie 2169
=item -[no]commit
2170
 
2171
This option will prevent the final workspace from being committed to the
2172
Repository. This allows inspection of the results.
2173
 
2174
The default operation is to commit and label the results of the import.
2175
 
2176
=item -printfiles=n
2177
 
2178
This option controls commit verbosity. The default operation is to display
2179
the files added and removed during the commit.
2180
 
2181
Suitable numbers are: None, 0 (No Display) and 1 (Full Display).
2182
 
2764 dpurdie 2183
=item -mergePaths=dirList
2184
 
2931 dpurdie 2185
This option specifies a Comma separated list of directories to be merged
3967 dpurdie 2186
during the import process. This works via the following mechanism:
2764 dpurdie 2187
 
2188
If the named directory exists in the 'new' image it will replace that in the
2189
'initial' workspace.
2190
 
2191
If the named directory does not exist in the 'new' image, but does exist in the
2192
'initial' image then it will be retained in the 'final' image.
2193
 
2194
Directories other than those named will not be imported.
2195
 
311 dpurdie 2196
=back
2197
 
2198
=head2 DESCRIPTION
2199
 
2200
Import a new version of a package to the trunk of the package. The utility
2201
will only import changed files so that file history is preserved within the
2202
repository.
2203
 
2204
This utility is used import software from another version control system
2205
The utility will:
2206
 
2207
=over
2208
 
361 dpurdie 2209
=item *
311 dpurdie 2210
 
361 dpurdie 2211
Create a Work Space based on the current package version
2212
 
379 dpurdie 2213
The 'trunk' of the named package will be used as the base for the workspace,
2214
unless modified with the -branch option.
311 dpurdie 2215
 
361 dpurdie 2216
=item *
311 dpurdie 2217
 
361 dpurdie 2218
Update files and directories
2219
 
311 dpurdie 2220
Determines the files and directories that have been added and deleted and
2221
update the Workspace to reflect the new structure.
2222
 
361 dpurdie 2223
=item *
311 dpurdie 2224
 
361 dpurdie 2225
Check in the new version
311 dpurdie 2226
 
361 dpurdie 2227
=item *
2228
 
2229
Label the new version
2230
 
311 dpurdie 2231
=back
2232
 
2233
=cut
2234