Subversion Repositories DevTools

Rev

Rev 2071 | Rev 2424 | Go to most recent revision | 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/ );
2048 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
#
2048 dpurdie 110
# Inputs          :
369 dpurdie 111
#
2048 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
 
1348 dpurdie 208
    Message ("Tag is  : " . $uref->RmRef() );
209
    Message ("Vcs Tag : " . $uref->SvnTag  );
2048 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
    {
268
        $url = SvnPath2Url($opt_tag);
269
    }
270
    else
271
    {
272
        $uref = NewSessionByWS($opt_path, 0, 1);
273
        my $ws_root = $uref->SvnLocateWsRoot(1);
274
        $url = $uref->FullWsRev();
275
    }
276
 
277
    Message ("Url: $url");
278
    $opr_done = 1;
279
}
280
 
281
#-------------------------------------------------------------------------------
363 dpurdie 282
# Function        : TestSvn
283
#
284
# Description     : Test access to subversion
285
#
286
# Inputs          : None
287
#
288
# Returns         :
289
#
290
sub TestSvn
291
{
292
    #
293
    #   Parse more options
294
    #
295
    GetOptions (
296
                "help:+"        => \$opt_help,
297
                "manual:3"      => \$opt_help,
298
                ) || Error ("Invalid command line" );
299
 
300
    #
301
    #   Subcommand specific help
302
    #
303
    SubCommandHelp( $opt_help, "Test Subversion") if ($opt_help || $#ARGV >= 0);
304
 
305
    SvnUserCmd( '--version');
306
    $opr_done = 1;
307
}
308
#-------------------------------------------------------------------------------
311 dpurdie 309
# Function        : SvnRepoCmd
310
#
311
# Description     : Execute a SVN command, where the first argument
312
#                   is a repository specifier
313
#
314
# Inputs          : $cmd
315
#                   $repo_url
316
#                   @opts
317
#
2048 dpurdie 318
# Returns         :
311 dpurdie 319
#
320
sub SvnRepoCmd
321
{
322
    my ( $cmd, $repo_url, @opts ) = @_;
323
    my $uref = NewSessionByUrl ( $repo_url );
324
 
325
    SvnUserCmd( $cmd,
326
            $uref->Full,
327
            @opts,
328
            { 'credentials' => 1 });
2048 dpurdie 329
 
311 dpurdie 330
    $opr_done = 1;
331
}
332
 
333
#-------------------------------------------------------------------------------
334
# Function        : DeletePackage
335
#
336
# Description     : Delete a Package structure within a Repository
337
#                   Intended for test usage
338
#
339
# Inputs          : URL                 - Url to Repo + Package Base
340
#
2048 dpurdie 341
# Returns         :
311 dpurdie 342
#
343
sub DeletePackage
344
{
379 dpurdie 345
    my $opt_error = 0;
311 dpurdie 346
    #
347
    #   Parse more options
348
    #
349
    GetOptions (
350
                "help:+"        => \$opt_help,
351
                "manual:3"      => \$opt_help,
379 dpurdie 352
                "error!"       => \$opt_error,
311 dpurdie 353
                ) || Error ("Invalid command line" );
354
 
355
    #
356
    #   Subcommand specific help
357
    #
358
    SubCommandHelp( $opt_help, "Delete a Package") if ($opt_help || $#ARGV < 0);
359
 
360
    #
361
    #   Sanity Tests
362
    #
363
    Message ("Delete Entire Package Tree" );
364
    Warning ("Too many arguments: @ARGV") if ( $#ARGV >= 1 );
365
 
366
    #
367
    #   Do all the hard work
368
    #       Create
369
    #       Import
370
    #       Label
371
    #
372
    my $uref = NewSessionByUrl ( $ARGV[0] );
379 dpurdie 373
    $uref->SvnValidatePackageRoot(!$opt_error);
311 dpurdie 374
    $uref->SvnDelete (
375
                      'target'      => $uref->Full,
385 dpurdie 376
                      'comment'   => [$uref->Path().": Delete Package",'Deleted by user command: jats svn delete-package'],
379 dpurdie 377
                      'noerror'   => !$opt_error,
311 dpurdie 378
                      );
379
    $opr_done = 1;
380
}
381
 
382
#-------------------------------------------------------------------------------
383
# Function        : CreatePackage
384
#
385
# Description     : Create a Package structure within a Repository
386
#                   Optionally Import Data
387
#                   Optionally Tag the import
388
#                   Optionally Tag the import on a branch
389
#
390
# Inputs          : URL                 - Url to Repo + Package Base
391
#                   Options             - Command modifiers
392
#                       -import=path    - Import named directory
393
#                       -label=name     - Label the result
394
#                       -tag=name       - Import to Tag Only
395
#                       -branch=name    - Import to Branch only
396
#                       -new            - Must be new package
397
#                       -replace        - Replace existing
398
#
2048 dpurdie 399
# Returns         :
311 dpurdie 400
#
401
sub CreatePackage
402
{
403
    my $opt_import;
404
    my $opt_tag;
405
    my $opt_branch;
406
    my $opt_trunk;
407
    my $opt_new;
408
    my $opt_label;
409
    my $opt_replace;
410
    my $pname;
411
    my $type;
385 dpurdie 412
    my $opt_author;
413
    my $opt_date;
311 dpurdie 414
    Message ("Create New Package Version" );
415
 
416
    #
417
    #   Parse more options
418
    #
419
    GetOptions (
420
                "help:+"        => \$opt_help,
421
                "manual:3"      => \$opt_help,
422
                "verbose:+"     => \$opt_verbose,
423
                "import=s"      => \$opt_import,
424
                "new"           => \$opt_new,
425
                "branch=s"      => \$opt_branch,
426
                "trunk"         => \$opt_trunk,
1347 dpurdie 427
                "tags=s"        => \$opt_tag,
311 dpurdie 428
                "label=s"       => \$opt_label,
429
                "replace"       => \$opt_replace,
385 dpurdie 430
                'author=s'      => \$opt_author,
431
                'date=s'        => \$opt_date,
311 dpurdie 432
 
433
                ) || Error ("Invalid command line" );
434
 
435
    #
436
    #   Subcommand specific help
437
    #
438
    SubCommandHelp( $opt_help, "Create a Package Version") if ($opt_help || $#ARGV < 0);
2048 dpurdie 439
 
311 dpurdie 440
    #
369 dpurdie 441
    #   Alter the error reporting parameters
311 dpurdie 442
    #
443
    ErrorConfig( 'verbose' => $opt_verbose );
444
 
445
    #
446
    #   Sanity Tests
447
    #
448
    my $count = 0;
449
    $count++ if ( $opt_trunk );
450
    $count++ if ( $opt_branch );
451
    $count++ if ( $opt_tag );
452
    Error ("Conflicting options: -trunk, -tag, -branch") if ( $count > 1 );
453
    Error ("Nothing imported to be labeled") if ( $count && !$opt_import );
454
    Error ("Import path does not exist: $opt_import") if ( $opt_import && ! -d $opt_import );
455
    Error ("Conflicting options: new and replace") if ( $opt_new && $opt_replace );
385 dpurdie 456
    Error ("Too many command line arguments") if ( exists $ARGV[1] );
311 dpurdie 457
 
1347 dpurdie 458
    $type = 'tags/' . $opt_tag          if ( $opt_tag);
459
    $type = 'branches/' . $opt_branch   if ( $opt_branch );
460
    $type = 'trunk'                     if ( $opt_trunk);
311 dpurdie 461
 
462
    #
463
    #   Do all the hard work
464
    #       Create
465
    #       Import
466
    #       Label
467
    #
468
    my $uref = NewSessionByUrl ( $ARGV[0] );
469
    $uref->SvnCreatePackage (
470
                      'import'  => $opt_import,
471
                      'label'   => $opt_label,
472
                      'type'    => $type,
473
                      'new'     => $opt_new,
474
                      'replace' => $opt_replace,
475
                      );
385 dpurdie 476
    #
477
    # Report RmPath as using a pegged version of a new package is a bit silly
478
    #
1356 dpurdie 479
#    Message ("Repository Ref: " . $uref->RmPath);
480
#    Message ("Vcs Tag       : " . $uref->SvnTag);
1270 dpurdie 481
    if ( $uref->{REVNO} )
482
    {
483
        $uref->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
484
        $uref->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
485
    }
311 dpurdie 486
    $opr_done = 1;
487
}
488
 
489
#-------------------------------------------------------------------------------
490
# Function        : ImportPackage
491
#
492
# Description     : Import a new version of a package
493
#                   Take great care to reuse file-versions that are already in
494
#                   the  package
495
#
369 dpurdie 496
#                   Intended to allow the importation of multiple
311 dpurdie 497
#                   versions of a package
498
#
2048 dpurdie 499
# Inputs          :
311 dpurdie 500
#
2048 dpurdie 501
# Returns         :
311 dpurdie 502
#
503
sub ImportPackage
504
{
505
    Message ("Import Package Version" );
506
 
507
    #
508
    #   Options
509
    #
510
    my $opt_package;
511
    my $opt_dir;
512
    my $opt_label;
513
    my $opt_replace = 0;
514
    my $opt_reuse;
515
    my $opt_workdir = "SvnImportDir";
516
    my $opt_delete = 1;
379 dpurdie 517
    my $opt_author;
518
    my $opt_date;
519
    my $opt_log = '';
520
    my $opt_branch;
521
    my $opt_datafile;
1348 dpurdie 522
    my $opt_printfiles;
311 dpurdie 523
 
524
    #
525
    #   Other globals
526
    #
527
    my $url_label;
379 dpurdie 528
    my $url_branch;
311 dpurdie 529
 
530
    #
531
    #   Configuration options
532
    #
533
    my $result = GetOptions (
379 dpurdie 534
                    'help:+'        => \$opt_help,
535
                    'manual:3'      => \$opt_help,
536
                    'verbose:+'     => \$opt_verbose,
537
                    'package=s'     => \$opt_package,
538
                    'dir=s'         => \$opt_dir,
539
                    'label=s'       => \$opt_label,
540
                    'branch=s'      => \$opt_branch,
541
                    'replace'       => \$opt_replace,
542
                    'reuse'         => \$opt_reuse,
543
                    'workspace=s'   => \$opt_workdir,
544
                    'delete!'       => \$opt_delete,
1348 dpurdie 545
                    'printfiles=i'  => \$opt_printfiles,
379 dpurdie 546
                    'author=s'      => \$opt_author,
547
                    'date=s'        => \$opt_date,
548
                    'log=s'         => \$opt_log,
549
                    'datafile=s'    => \$opt_datafile,
311 dpurdie 550
 
551
                    #
552
                    #   Update documentation at the end of the file
553
                    #
554
                    ) || Error ("Invalid command line" );
555
 
556
    #
557
    #   Insert defaults
341 dpurdie 558
    #   User can specify base package via -package or a non-options argument
311 dpurdie 559
    #
560
    $opt_package = $ARGV[0] unless ( $opt_package );
379 dpurdie 561
    unlink $opt_datafile if ( defined $opt_datafile );
2048 dpurdie 562
 
311 dpurdie 563
    #
564
    #   Subcommand specific help
565
    #
566
    SubCommandHelp( $opt_help, "Import directory to a Package")
567
        if ($opt_help || ! $opt_package );
568
 
569
    #
369 dpurdie 570
    #   Alter the error reporting parameters
311 dpurdie 571
    #
572
    ErrorConfig( 'verbose' => $opt_verbose );
573
 
574
    #
575
    #   Configure the error reporting process now that we have the user options
576
    #
577
    Error ("No package URL specified") unless ( $opt_package );
578
    Error ("No base directory specified") unless ( $opt_dir );
579
    Error ("Invalid base directory: $opt_dir") unless ( -d $opt_dir );
580
 
581
    #
582
    #   Create an SVN session
583
    #
584
    my $svn = NewSessionByUrl ( $opt_package );
585
 
586
    #
587
    #   Ensure that the required label is available
588
    #
589
    if ( $opt_label )
590
    {
591
        $opt_label = SvnIsaSimpleLabel ($opt_label);
592
        $url_label = $svn->BranchName( $opt_label, 'tags' );
593
        $svn->SvnValidateTarget (
594
                        'target' => $url_label,
595
                        'available' => 1,
596
                        ) unless ( $opt_replace );
597
    }
598
 
599
    #
379 dpurdie 600
    #   Validate the required branch
601
    #   It will be created if it doesn't exist
602
    #
603
    if ( $opt_branch )
604
    {
605
        $opt_branch = SvnIsaSimpleLabel($opt_branch);
606
        $url_branch = $svn->BranchName( $opt_branch, 'branches' );
385 dpurdie 607
        my $rv = $svn->SvnValidateTarget (
608
                        'cmd'    => 'SvnImporter. Create branch',
379 dpurdie 609
                        'target' => $url_branch,
610
                        'create' => 1,
611
                        );
385 dpurdie 612
        if ( $rv == 2 )
613
        {
614
            $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
615
            $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
616
        }
379 dpurdie 617
    }
618
 
619
    #
311 dpurdie 620
    #   Create a workspace based on the users package
621
    #   Allow the workspace to be reused to speed up multiple
622
    #   operations
623
    #
624
    unless ( $opt_reuse && -d $opt_workdir )
625
    {
626
        Message ("Creating Workspace");
627
        rmtree( $opt_workdir );
628
 
629
        $svn->SvnValidatePackageRoot ();
630
        #DebugDumpData( 'Svn', $svn );
631
        $svn->SvnValidateTarget (
632
                            'cmd'    => 'SvnImporter',
633
                            'target' => $svn->Full,
634
                            'require' => 1,
635
                            );
636
 
379 dpurdie 637
        my $url_co = $opt_branch ? $url_branch : $svn->Full . '/trunk';
1356 dpurdie 638
        $svn->SvnCo ( $url_co, $opt_workdir, 'print' => $opt_printfiles );
311 dpurdie 639
        Error ("Cannot locate the created Workspace")
640
            unless ( -d $opt_workdir );
641
    }
642
    else
643
    {
644
        Message ("Reusing Workspace");
645
    }
2048 dpurdie 646
 
311 dpurdie 647
    #
648
    #   Determine differences between the two folders
649
    #       Create structures for each directory
650
    #
651
    Message ("Determine Files in packages");
652
 
653
    my $search = JatsLocateFiles->new("--Recurse=1",
654
                                       "--DirsToo",
655
                                       "--FilterOutRe=/\.svn/",
656
                                       "--FilterOutRe=/\.svn\$",
657
                                       "--FilterOutRe=^/${opt_workdir}\$",
658
                                       "--FilterOutRe=^/${opt_workdir}/",
659
                                       );
660
    my @ws = $search->search($opt_workdir);
661
    my @dir = $search->search($opt_dir);
662
 
1270 dpurdie 663
    #
664
    #   Scan for a source file
665
    #   Trying to detect empty views
666
    #   Look for file, not directory
667
    #
668
    {
669
        my $fileFound = 0;
670
        foreach ( @dir )
671
        {
672
            next if ( m~/$~ );
673
            $fileFound++;
674
            last;
675
        }
676
 
677
        unless ( $fileFound )
678
        {
679
            Warning ("No source files found in source view");
680
            $opr_done = 1;
681
            return;
682
        }
683
    }
684
 
311 dpurdie 685
    #Information ("WS Results", @ws);
686
    #Information ("DIR Results", @dir);
1270 dpurdie 687
    #Information ("WS Results: ", scalar @ws);
688
    #Information ("DIR Results:", scalar @dir);
311 dpurdie 689
 
690
    #
691
    #   Create a hash the Workspace and the User dir
692
    #   The key will be file names
693
    #
694
    my %ws;  map ( $ws{$_} = 1 , @ws );
695
    my %dir; map ( $dir{$_} = 1 , @dir );
696
 
697
    #
698
    #   Create a hash of common elements
699
    #   Removing then from the other two
700
    #
701
    my %common;
702
    foreach ( keys %ws )
703
    {
704
        next unless ( exists $dir{$_} );
705
        $common{$_} = 1;
706
        delete $ws{$_};
707
        delete $dir{$_};
708
    }
709
 
710
    #DebugDumpData( 'WS', \%ws );
711
    #DebugDumpData( 'DIR', \%dir );
712
    #DebugDumpData( 'COMMON', \%common );
713
 
714
    #
379 dpurdie 715
    #   Need to consider the case where a file has been replaced with a directory
716
    #   and visa-versa. Delete files and directories first.
717
    #
718
    #
719
    #   Remove files
720
    #   Sort in reverse. This will ensure that we process directory
721
    #   contents before directories
722
    #
723
    my @rm_files = reverse sort keys %ws;
724
    if ( @rm_files )
725
    {
726
        foreach my $file ( @rm_files  )
727
        {
728
            Verbose ("Removing $file");
729
            unlink "$opt_workdir/$file";
730
        }
731
 
732
        #
733
        #   Inform Subversion about the removed files
734
        #
735
        my $base = 0;
736
        my $num = $#rm_files;
737
        Message ("Update the workspace: Removed " . ($num + 1) . " Files");
738
 
739
        while ( $base <= $num )
740
        {
741
            my $end = $base + 200;
742
            $end = $num if ( $end > $num );
743
 
744
            $svn->SvnCmd ( 'delete', map ("$opt_workdir/$_@", @rm_files[$base .. $end] ),
745
                            { 'error' => 'Deleting files from workspace' } );
2048 dpurdie 746
 
379 dpurdie 747
            $base = $end + 1;
748
        }
749
    }
2048 dpurdie 750
 
379 dpurdie 751
    #
311 dpurdie 752
    #   Add New Files
753
    #   Won't add empty directories at this point
754
    #
755
    #   Process by sorted list
756
    #   This will ensure we process parent directories first
757
    #
758
    my @added = sort keys %dir;
759
    if ( @added )
760
    {
761
        foreach my $file ( @added  )
762
        {
763
            my $src = "$opt_dir/$file";
764
            my $target = "$opt_workdir/$file";
765
 
766
            if ( -d $src )
767
            {
379 dpurdie 768
                Verbose ("Adding directory: $file");
311 dpurdie 769
                mkdir ( $target ) unless (-d $target);
770
            }
771
            else
772
            {
773
 
774
                my $path = dirname ( $target);
775
                mkdir ( $path ) unless (-d $path);
776
 
777
                Verbose ("Adding $file");
778
                unless (File::Copy::copy( $src, $target ))
779
                {
780
                    Error("Failed to transfer file [$file]: $!");
781
                }
782
            }
783
        }
784
 
785
        #
786
        #   Inform Subversion about the added files
787
        #   The command line does have a finite length, so add them 200 at a
788
        #   time.
789
        #
790
 
791
        my $base = 0;
792
        my $num = $#added;
379 dpurdie 793
        Message ("Update the workspace: Added " . (1 + $num) . " files");
311 dpurdie 794
 
795
        while ( $base <= $num )
796
        {
797
            my $end = $base + 200;
798
            $end = $num if ( $end > $num );
799
 
800
            $svn->SvnCmd ( 'add'
801
                            , '--depth=empty'
802
                            , '--parents'
379 dpurdie 803
                            , map ("$opt_workdir/$_@", @added[$base .. $end] ),
311 dpurdie 804
                            { 'error' => 'Adding files to workspace' } );
805
 
806
            $base = $end + 1;
807
        }
808
    }
809
 
810
    #
811
    #   The common files may have changed
812
    #   Simply copy them all in and let subversion figure it out
813
    #
814
    foreach my $file ( sort keys %common  )
815
    {
816
        my $src = "$opt_dir/$file";
817
        my $target = "$opt_workdir/$file";
818
 
819
        next if ( -d $src );
820
        if ( File::Compare::compare ($src, $target) )
821
        {
822
            Verbose ("Transfer $file");
823
            unlink $target;
824
            unless (File::Copy::copy( $src, $target ))
825
            {
826
                Error("Failed to transfer file [$file]: $!",
827
                      "Src: $src",
828
                      "Tgt: $target");
829
            }
830
        }
831
    }
832
 
833
    #
834
    #   Commit the workspace
835
    #   This will go back onto the trunk
836
    #
837
    $svn = NewSessionByWS( $opt_workdir );
379 dpurdie 838
    my $pkgPath = $svn->Path();
387 dpurdie 839
 
379 dpurdie 840
    my $ciComment = "$pkgPath: Checkin by Svn Import";
841
    $ciComment .= "\n" . $opt_log if ( $opt_log );
842
    $ciComment =~ s~\r\n~\n~g;
387 dpurdie 843
    $ciComment =~ s~\r~\n~g;
844
    $ciComment = encode('UTF-8', $ciComment, Encode::FB_DEFAULT);
845
 
379 dpurdie 846
    $svn->SvnCi ('comment' => $ciComment, 'allowSame' => 1 );
381 dpurdie 847
    Message ("Repository Ref: " . $svn->RmRef) unless( $opt_label );
379 dpurdie 848
    $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
849
    $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
311 dpurdie 850
 
851
    #
852
    #   Label the result
853
    #   The workspace will have been updated, so we can use it as the base for
854
    #   the labeling process
855
    #
856
    if ( $opt_label )
857
    {
858
        $svn->SvnCopyWs (
859
                       target => $url_label,
860
                       'noswitch' => 1,
861
                       'replace' => $opt_replace,
379 dpurdie 862
                       'comment' => "$pkgPath: Tagged by Jats Svn Import",
311 dpurdie 863
                       );
864
        Message ("Repository Ref: " . $svn->RmRef);
1347 dpurdie 865
        Message ("Vcs Tag       : " . $svn->SvnTag);
379 dpurdie 866
        $svn->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
867
        $svn->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
311 dpurdie 868
    }
869
 
870
    #
871
    #   Clean up
872
    #
873
    if ( $opt_delete && ! $opt_reuse )
874
    {
875
        Message ("Delete Workspace");
876
        rmtree( $opt_workdir );
877
    }
379 dpurdie 878
 
879
    #
880
    #   Automation data transfer
881
    #
882
    if ( defined $opt_datafile )
883
    {
884
        my $data = JatsProperties::New();
885
 
886
        $data->setProperty('Command'        , 'ImportPackage');
887
        $data->setProperty('Label'          , $opt_label);
1347 dpurdie 888
        $data->setProperty('subversion.url' , $svn->RmRef);
889
        $data->setProperty('subversion.tag' , $svn->SvnTag);
379 dpurdie 890
 
891
        $data->Dump('InfoFile') if ($opt_verbose);
892
        $data->store( $opt_datafile );
893
    }
894
 
311 dpurdie 895
    $opr_done = 1;
896
}
897
 
898
#-------------------------------------------------------------------------------
385 dpurdie 899
# Function        : DeleteBranch
900
#
901
# Description     : Delete the branch that a workspace is based upon
902
#
2048 dpurdie 903
# Inputs          :
385 dpurdie 904
#
2048 dpurdie 905
# Returns         :
385 dpurdie 906
#
907
sub DeleteBranch
908
{
909
    my $opt_path;
910
    my $opt_error = 0;
911
    #
912
    #   Parse more options
913
    #
914
    GetOptions (
915
                "help:+"        => \$opt_help,
916
                "manual:3"      => \$opt_help,
917
                "path:s"        => \$opt_path,
918
                ) || Error ("Invalid command line" );
919
 
920
    #
921
    #   Subcommand specific help
922
    #
923
    SubCommandHelp( $opt_help, "Delete Branch") if ($opt_help);
924
 
925
    #
926
    #   Sanity Tests
927
    #
2071 dpurdie 928
    Message ("Delete Workspace Branchs" );
385 dpurdie 929
 
930
    #
931
    #   Do all the hard work
932
    #
933
    $opt_path = '.' unless ( defined $opt_path );
934
    my $uref = NewSessionByWS($opt_path, 0, 1);
935
    my $ws_root = $uref->SvnLocateWsRoot(1);
936
    my $ws_url = $uref->FullWs();
937
 
938
    #
2071 dpurdie 939
    #   What we do depends what aruments the user provided
385 dpurdie 940
    #
2071 dpurdie 941
    unless ( @ARGV )
942
    {
943
        #
944
        #   If no branch was specified - then display the workspace branch
945
        #
946
        Error ('The workspace is not based on a branch')
947
            unless ( $ws_url =~ m ~/branches/(.*)~ );
948
        Message('The workspace is based on the branch: '. $1);
949
    }
950
    else
951
    {
952
        #
953
        #   Delete all specified branches
954
        #
955
        foreach my $branch ( @ARGV )
956
        {
957
            Message ("Deleting: " . $branch );
958
            my $target = join( '/', $uref->FullPath(), 'branches', $branch);
959
            if ( $uref->SvnDelete (
960
                              'target'    => $target,
961
                              'comment'   => [$uref->Path().": Delete Branch",'Deleted by user command: jats svn delete-branch'],
962
                              'noerror'   => 1,
963
                              )
964
               )
965
            {
966
                Warning ("Branch deletion failed: $branch");
967
            }
968
        }
969
    }
385 dpurdie 970
    $opr_done = 1;
971
}
972
 
2048 dpurdie 973
#-------------------------------------------------------------------------------
974
# Function        : CreateBranch
975
#
976
# Description     : Branch a workspace and then switch to the new branch
977
#
978
# Inputs          :
979
#
980
# Returns         :
981
#
982
sub CreateBranch
983
{
984
    my $opt_path;
985
    my $opt_comment;
986
    my $opt_switch = 1;
987
    my $opt_branch;
385 dpurdie 988
 
2048 dpurdie 989
    #
990
    #   Parse more options
991
    #
992
    GetOptions (
993
                "help:+"        => \$opt_help,
994
                "manual:3"      => \$opt_help,
995
                "path:s"        => \$opt_path,
996
                "switch!"       => \$opt_switch,
997
                "comment:s"     => \$opt_comment,
998
                ) || Error ("Invalid command line" );
999
 
1000
    #
1001
    #   Subcommand specific help
1002
    #
1003
    SubCommandHelp( $opt_help, "Create Branch") if ($opt_help);
1004
 
1005
    #
1006
    #   Sanity Tests
1007
    #
1008
    Message ("Create Workspace Branch" );
1009
    Error ("Too many arguments: @ARGV") if ( $#ARGV > 0 );
1010
    Error ("Not enough arguments. No branch name specified") if ( $#ARGV < 0 );
1011
 
1012
    #
1013
    #   Sanity test the label
1014
    #
1015
    $opt_branch = SvnIsaSimpleLabel ($ARGV[0] );
1016
 
1017
    #
1018
    #   Do all the hard work
1019
    #
1020
    $opt_path = '.' unless ( defined $opt_path );
1021
    my $uref = NewSessionByWS($opt_path, 0, 1);
1022
    my $ws_root = $uref->SvnLocateWsRoot(1);
1023
    my $ws_url = $uref->Full();
1024
 
1025
    #
1026
    #   Use the verion of the branch that has been committed as the base of the
1027
    #   copy. If the user has modified files, then they won't be commited
1028
    #
1029
    #   This operation will be server-side only
1030
    #
1031
    Message ("Creating branch: $opt_branch");
1032
    my $repoLink = $uref->{InfoWs}{URL} . '@' . $uref->{InfoWs}{Revision};
1033
    $uref->{DEVBRANCH} =  join ('/', 'branches', $opt_branch);
1034
    my $branch_tag = $uref->SvnCopy (
1035
                'old' => $repoLink,
1036
                'new' => join ('/', $ws_url, $uref->{DEVBRANCH} ),
1037
                'comment' => $opt_comment ? $opt_comment : 'Created by Jats svn branch',
1038
                'replace' => 0,
1039
                );
1040
 
2053 dpurdie 1041
 
2048 dpurdie 1042
    if ( $opt_switch )
1043
    {
1044
        Verbose ("Switching to new branch: $opt_branch");
1045
        $branch_tag = SvnPath2Url($branch_tag);
2053 dpurdie 1046
        chdir ($ws_root) || Error ("Cannot cd to: " .$ws_root);
1047
        $uref->SvnSwitch ($branch_tag, $opt_path, '--Print', '--KeepWs' );
2048 dpurdie 1048
    }
1049
    else
1050
    {
1051
        Warning ("Using existing workspace, not the created branch");
1052
    }
1053
    Message ("Repository Ref: " . $uref->RmRef);
1054
    Message ("Vcs Tag       : " . $uref->SvnTag);
1055
 
1056
#    #
1057
#    #   The copy operation *should* be a server side operation only
1058
#    #   If the user has commited changes, but not yet updated the local
1059
#    #   workspace, then subversion will do a client side copy
1060
#    #   This is not good.
1061
#    #
1062
#    $uref->SvnCopyWs (
1063
#                   target => join ('/', $ws_url, 'branches', $opt_branch),
1064
#                   'allowLocalMods' => 1,
1065
#                   'noupdatecheck' => 1,
1066
#                   'noswitch' => ! $opt_switch,
1067
#                   'replace' => 0,
1068
#                   'comment' => $opt_comment ? $opt_comment : 'Created by Jats svn branch',
1069
#                   );
1070
#
1071
#    Message ("Repository Ref: " . $uref->RmRef);
1072
#    Message ("Vcs Tag       : " . $uref->SvnTag);
1073
 
1074
    $opr_done = 1;
1075
}
1076
 
385 dpurdie 1077
#-------------------------------------------------------------------------------
2048 dpurdie 1078
# Function        : SwitchBranch
1079
#
1080
# Description     : Switch to a specified branch
1081
#
1082
# Inputs          :
1083
#
1084
# Returns         :
1085
#
1086
sub SwitchBranch
1087
{
1088
    my $opt_path = '.';
1089
    my $opt_branch;
1090
 
1091
    #
1092
    #   Parse more options
1093
    #
1094
    GetOptions (
1095
                "help:+"        => \$opt_help,
1096
                "manual:3"      => \$opt_help,
1097
                "path:s"        => \$opt_path,
1098
                ) || Error ("Invalid command line" );
1099
 
1100
    #
1101
    #   Subcommand specific help
1102
    #
1103
    SubCommandHelp( $opt_help, "Switch Branch") if ($opt_help);
1104
    return ShowBranches($opt_path) if ( $#ARGV < 0 );
1105
 
1106
    #
1107
    #   Sanity Tests
1108
    #
1109
    Error ("Too many arguments: @ARGV") if ( $#ARGV > 0 );
1110
 
1111
    #
1112
    #   Calculate the target name
1113
    #       trunk is special
1114
    #       tags/... is special
1115
    $opt_branch = $ARGV[0];
1116
    if ( $opt_branch eq 'trunk' ) {
1117
    } elsif ( $opt_branch =~ m~tags/.+~ ) {
1118
    } else {
1119
        $opt_branch = join ('/', 'branches', $opt_branch);
1120
    }
1121
    Message ("Switching to new branch: $opt_branch");
1122
 
1123
    #
1124
    #   Do all the hard work
1125
    #
1126
    my $uref = NewSessionByWS($opt_path, 0, 1);
2053 dpurdie 1127
    my $ws_root = $uref->SvnLocateWsRoot(1);
2048 dpurdie 1128
    my $ws_url = $uref->Full();
1129
    my $branch_tag = join ('/', $ws_url, $opt_branch);
1130
 
1131
    #
1132
    #   Validate the branch
1133
    #
1134
    $uref->SvnValidateTarget (
1135
                        'cmd'    => 'svn switch',
1136
                        'target' => $branch_tag,
1137
                        'require' => 1,
1138
                        );
1139
 
2053 dpurdie 1140
    #
1141
    #   Must Change directory before we switch
1142
    #   Otherwise we will import chnages into the wrong place
1143
    #
1144
    chdir ($ws_root) || Error ("Cannot cd to: " . $ws_root);
1145
    $uref->SvnSwitch ($branch_tag, $opt_path, '--Print', '--KeepWs' );
2048 dpurdie 1146
    $opr_done = 1;
1147
}
1148
 
1149
#-------------------------------------------------------------------------------
1150
# Function        : ShowBranches
1151
#
1152
# Description     : Show branches in current workspace
1153
#                   Internal use only
1154
#
1155
# Inputs          : $opt_path           - Optional path
1156
#
1157
# Returns         :
1158
#
1159
sub ShowBranches
1160
{
1161
    my ($opt_path) = @_;
1162
 
1163
    my $uref = NewSessionByWS($opt_path, 0, 1);
1164
    my $ws_url = $uref->Full();
1165
 
1166
    #
1167
    #   Display the packages full URL - allow the user to manuallu look at more
1168
    #   List the bracnhes
1169
    #
1170
    Message ("Url: $ws_url", 'Available Branches');
1171
    SvnUserCmd( 'ls', join ('/', $ws_url, 'branches'), { 'credentials' => 1 });
1172
    $opr_done = 1;
1173
}
1174
#-------------------------------------------------------------------------------
311 dpurdie 1175
# Function        : SubCommandHelp
1176
#
1177
# Description     : Provide help on a subcommand
1178
#
1179
# Inputs          : $help_level             - Help Level 1,2,3
1180
#                   $topic                  - Topic Name
1181
#
1182
# Returns         : This function does not return
1183
#
1184
sub SubCommandHelp
1185
{
1186
    my ($help_level, $topic) = @_;
1187
    my @sections;
1188
    #
1189
    #   Spell out the section we want to display
1190
    #
1191
    #   Note:
1192
    #   Due to bug in pod2usage can't use 'head1' by itself
1193
    #   Each one needs a subsection.
1194
    #
1195
    push @sections, qw( NAME SYNOPSIS ) ;
1196
    push @sections, qw( ARGUMENTS OPTIONS ) if ( $help_level > 1 );
1197
    push @sections, qw( DESCRIPTION )       if ( $help_level > 2 );
1198
 
1199
    #
1200
    #   Extract section from the POD
1201
    #
1202
    pod2usage({-verbose => 99,
1203
               -noperldoc => 1,
1204
               -sections => $topic . '/' . join('|', @sections) } );
1205
}
1206
 
1207
#-------------------------------------------------------------------------------
1208
#   Documentation
1209
#   NOTE
1210
#
1211
#   Each subcommand MUST have
1212
#   head1 section as used by the subcommand
1213
#       This should be empty, as the contents will NOT be displayed
1214
#   head2 sections called
1215
#       NAME SYNOPSIS ARGUMENTS OPTIONS DESCRIPTION
1216
#
1217
#=head1 xxxxxx
1218
#=head2 NAME
1219
#=head2 SYNOPSIS
1220
#=head2 ARGUMENTS
1221
#=head2 OPTIONS
1222
#=head2 DESCRIPTION
1223
#
1224
 
1225
=pod
1226
 
361 dpurdie 1227
=for htmltoc    GENERAL::Subversion::
1228
 
311 dpurdie 1229
=head1 NAME
1230
 
1231
jats svn - Miscellaneous SubVersion Operations
1232
 
1233
=head1 SYNOPSIS
1234
 
1235
jats svn [options] command [command options]
1236
 
1237
 Options:
1238
    -help[=n]              - Help message, [n=1,2,3]
1239
    -man                   - Full documentation [-help=3]
1240
    -verbose[=n]           - Verbose command operation
1241
 
1242
 Common Command Options:
1243
    All command support suboptions to provide command specific help
1244
 
1245
    -help[=n]              - Help message, [n=1,2,3]
1246
    -man                   - Full documentation [-help=3]
1247
 
1248
 Commands are:
363 dpurdie 1249
    test                   - Test access to subversion
369 dpurdie 1250
    paths                  - Display Subversion tag to URL conversions
311 dpurdie 1251
    ls URL                 - List Repo contents for URL
369 dpurdie 1252
    tag [URL]              - Convert URL or Path to a Release Manager Tag
1253
    url [TAG]              - Convert TAG or Path to a Subversion URL
2048 dpurdie 1254
    create-package URL     - Create a new package at URL
311 dpurdie 1255
    delete-package URL     - Delete Package Subtree
2048 dpurdie 1256
    branch BRANCH          - Create a Development Branch
1257
    switch [BRANCH]        - Switch to a Development Branch
385 dpurdie 1258
    delete-branch          - Delete a Development Branch
311 dpurdie 1259
    import URL             - Import files to package at URL
1260
 
1261
 Use the command
1262
    jats svn command -h
1263
 for command specific help
1264
 
1265
=head1 OPTIONS
1266
 
1267
=over
1268
 
1269
=item B<-help[=n]>
1270
 
1271
Print a help message and exit. The level of help may be either 1, 2 or
1272
3 for a full manual.
1273
 
1274
This option may be specified multiple times to increment the help level, or
1275
the help level may be directly specified as a number.
1276
 
1277
=item B<-man>
1278
 
1279
This is the same as '-help=3'.
1280
The complete help is produced in a man page format.
1281
 
2071 dpurdie 1282
=item B<-verbose[=n]>
311 dpurdie 1283
 
1284
This option will increase the level of verbosity of the commands.
1285
 
1286
If an argument is provided, then it will be used to set the level, otherwise the
1287
existing level will be incremented. This option may be specified multiple times.
1288
 
1289
=back
1290
 
1291
=head1 DESCRIPTION
1292
 
1293
This program provides a number of useful Subversion based operations.
1294
 
363 dpurdie 1295
=head1 Test Subversion
1296
 
1297
=head2 NAME
1298
 
1299
Test Subversion
1300
 
1301
=head2 SYNOPSIS
1302
 
1303
    jats svn test
1304
 
1305
=head2 DESCRIPTION
1306
 
1307
This command will ensure that the subversion command line utility can be
1308
located. The command will report the version of the svn client found.
1309
 
369 dpurdie 1310
=head1 Subversion Paths
1311
 
1312
=head2 NAME
1313
 
1314
Subversion Paths
1315
 
1316
=head2 SYNOPSIS
1317
 
1318
    jats svn paths
1319
 
1320
=head2 DESCRIPTION
1321
 
1322
This command will display the base Tags and associated URLs that are used by
1323
JATS to convert a 'Subversion Tag' into a full URLs that will be used to access
1324
a physical repository.
1325
 
1326
The 'Tags' configuration is site-specific.
1327
 
311 dpurdie 1328
=head1 List Repository
1329
 
363 dpurdie 1330
=head2 NAME
1331
 
1332
List Repository
1333
 
1334
=head2 SYNOPSIS
1335
 
1336
    jats svn ls <URL>
1337
 
1338
=head2 DESCRIPTION
1339
 
311 dpurdie 1340
This command will take a URL and perform a 'svn' list operation. The URL will
1341
be expanded to include the site specific repository.
1342
 
369 dpurdie 1343
=head1 Url to Tag
1344
 
1345
=head2 NAME
1346
 
1347
Url to Tag
1348
 
1349
=head2 SYNOPSIS
1350
 
1351
    jats svn tag [Option] [tag]
1352
 
1353
 Options:
1354
    -help[=n]              - Help message, [n=1,2,3]
1355
    -man                   - Full documentation [-help=3]
1356
    -path=path             - Convert specified path
1357
    -url=url               - Convert specified URL
1358
 
1359
=head2 DESCRIPTION
1360
 
1361
This command will convert a URL or a PATH to a Subversion Tag that can
1362
be used within the remainder of the build system. If no PATH or URL is provided,
1363
then the command uses a path of the current directory.
1364
 
1365
The command will convert either a PATH or a URL. It will not do both.
1366
 
1367
The command will use the configured Subversion URL prefixes to create the Tag.
1368
 
1369
If a PATH is to be converted, then the PATH must address a Subversion workspace.
1370
The conversion will return a Tag to the root of the Workspace and Peg it to
1371
the last committed version. The command will not determine if the workspace
1372
contains modified files.
1373
 
1374
If a URL is to be converted, then the resultant value should be used with
1375
caution. The result is only as good as the provided URL and may not address
1376
the root of a package.
1377
 
1378
=head1 Tag to Url
1379
 
1380
=head2 NAME
1381
 
1382
Tag to Url
1383
 
1384
=head2 SYNOPSIS
1385
 
1386
    jats svn url [Option] [url]
1387
 
1388
 Options:
1389
    -help[=n]              - Help message, [n=1,2,3]
1390
    -man                   - Full documentation [-help=3]
1391
    -path=path             - Convert specified path
1392
    -url=url               - Convert specified URL
1393
 
1394
=head2 DESCRIPTION
1395
 
1396
This command will convert a TAG or a PATH to a full URL that can be used
1397
directly by Subversion. If no PATH or TAG is provided, then the command uses a
1398
path of the current directory.
1399
 
1400
The command will convert either a TAG or a URL. It will not do both.
1401
 
1402
The command will use the configured Subversion URL prefixes to expand the TAG.
1403
 
1404
If a PATH is to be converted, then the PATH must address a Subversion workspace.
1405
The conversion will return a URL to the root of the Workspace and Peg it to
1406
the last committed version. The command will not determine if the workspace
1407
contains modified files.
1408
 
1409
If a TAG is to be converted, then the resultant value should be used with
1410
caution. The result is only as good as the provided URL and may not address
1411
the root of a package.
1412
 
2048 dpurdie 1413
=head1 Create a Package Version
1414
 
1415
=head2 NAME
1416
 
1417
Create a Package Version
1418
 
1419
=head2 SYNOPSIS
1420
 
1421
jats svn [options] create-package URL [command options]
1422
 
1423
 Options:
1424
    -help[=n]               - Help message, [n=1,2,3]
1425
    -man                    - Full documentation [-help=3]
1426
    -verbose[=n]            - Verbose command operation
1427
 
1428
 Command Options
1429
    -help[=n]               - Provide command specific help
1430
    -new                    - Package must not exist
1431
    -replace                - Replace any existing versions
2354 dpurdie 1432
    -import=path            - Import directory tree
2048 dpurdie 1433
    -label=nnn              - Label imported package
1434
    -trunk                  - Import to trunk (default)
1435
    -tags=nnn               - Import to tags
1436
    -branch=nnn             - Import to branches
1437
 
1438
=head2 ARGUMENTS
1439
 
1440
The command takes one argument: The URL of the desired package.
1441
This may be be:
1442
 
1443
=over
1444
 
1445
=item * A full URL
1446
 
1447
Complete with protocol and path information.
1448
 
1449
=item * A simple URL
1450
 
1451
JATS will prepend the site-specific repository location to the user provided URL
1452
 
1453
=back
1454
 
1455
=head2 OPTIONS
1456
 
1457
=over
1458
 
1459
=item -help[=n]
1460
 
1461
Print a help message and exit. The level of help may be either 1, 2 or 3.
1462
 
1463
This option may be specified multiple times to increment the help level, or
1464
the help level may be directly specified as a number.
1465
 
1466
=item -new
1467
 
1468
This option specifies that the named package MUST not exist at all.
1469
 
1470
=item -replace
1471
 
1472
This option allows the program to replace any existing versions of the
1473
imported source. It will allow the deletion of any existing trunk, tags or
1474
branches.
1475
 
2354 dpurdie 1476
=item -import=path
2048 dpurdie 1477
 
1478
This option specifies the path of a subdirectory tree to import into the newly
1479
created package. In not provided, then only a package skeleton will be created.
1480
 
2354 dpurdie 1481
All files and directories below, but not including, the named path will be
1482
imported into the package.
1483
 
2048 dpurdie 1484
=item -label=nnn
1485
 
1486
This option specifies a label to place the imported source.
1487
 
1488
=item -trunk
1489
 
1490
This option specifies that imported source will be placed on the trunk of the
1491
package. This is the default mode of import.
1492
 
1493
The options -trunk, -tags and -branch are mutually exclusive.
1494
 
1495
=item -tags=nnn
1496
 
1497
This option specifies that imported source will be placed directly on the
1498
named tag of the package.
1499
 
1500
The options -trunk, -tags and -branch are mutually exclusive.
1501
 
1502
=item -branch=nnn
1503
 
1504
This option specifies that imported source will be placed directly on the
1505
named branch of the package.
1506
 
1507
The options -trunk, -tags and -branch are mutually exclusive.
1508
 
1509
=back
1510
 
1511
=head2 DESCRIPTION
1512
 
1513
This command will create a new package within a repository. It will ensure
1514
that the package contains the three required subdirectories: trunk, tags and
1515
branches.
1516
 
1517
The command will also ensure that packages are not placed at inappropriate
1518
locations within the repository. It is not correct to place a package within
1519
another package.
1520
 
1521
The command will, optionally, import a directory tree into the repository and,
1522
optionally, label the package.
1523
 
1524
The package body may be imported to the 'trunk' or to a branch or a tag.
1525
By default the data will be imported to the trunk and may be labeled (tagged).
1526
 
1527
Options allow the targets to be deleted if they exist or to ensure that they
1528
are not present.
1529
 
1530
The command does not attempt to merge file versions within the repository. It
1531
may result in multiple instances of a file within the repository. Use only for
1532
simple imports. Use the 'import' command for more sophisticated import requirements.
1533
 
2354 dpurdie 1534
=head3 Examples
1535
 
1536
To create a package skeleton in the Perth MREF_Package repository for a package
1537
called 'VIXmyPackage':
1538
 
1539
    jats svn create-package AUPERASVN01/MREF_Package/VIXmyPackage
1540
 
1541
To create a package skeleton in the Perth MREF_Package repository, import code
1542
into the trunk of the package and label (tag) it:
1543
 
1544
    jats svn create-package \
1545
           AUPERASVN01/MREF_Package/VIXmyPackage \
1546
           -import=VIXmyNewPackage \
1547
           -label=VIXmyPackage.WIP
1548
 
311 dpurdie 1549
=head1 Delete a Package
1550
 
1551
=head2 NAME
1552
 
1553
Delete a Package
1554
 
1555
=head2 SYNOPSIS
1556
 
1557
jats svn delete-package URL [options]
1558
 
1559
 Options:
1560
    -help[=n]              - Help message, [n=1,2,3]
1561
    -man                   - Full documentation [-help=3]
1562
    -verbose[=n]           - Verbose command operation
1563
 
1564
=head2 ARGUMENTS
1565
 
1566
The command takes one argument: The URL of the desired package.
1567
This may be be:
1568
 
1569
=over
1570
 
1571
=item * A full URL
1572
 
1573
Complete with protocol and path information.
1574
 
1575
=item * A simple URL
1576
 
1577
JATS will prepend the site-specific repository location to the user provided URL
1578
 
1579
=back
1580
 
1581
=head2 OPTIONS
1582
 
1583
This command has no significant options, other than the general help options.
1584
 
1585
=head2 DESCRIPTION
1586
 
1587
This command will delete a package from the repository. It will ensure
1588
that the package is a valid package, before it is deleted.
1589
 
1590
The command is intended to be used by test scripts, rather than users.
1591
 
2048 dpurdie 1592
=head1 Create Branch
385 dpurdie 1593
 
1594
=head2 NAME
1595
 
2048 dpurdie 1596
Create a Workspace Branch
385 dpurdie 1597
 
1598
=head2 SYNOPSIS
1599
 
2048 dpurdie 1600
jats svn branch branch-name [options]
385 dpurdie 1601
 
1602
 Options:
1603
    -help[=n]              - Help message, [n=1,2,3]
1604
    -man                   - Full documentation [-help=3]
1605
    -verbose[=n]           - Verbose command operation
1606
    -path=path             - Target workspace
2048 dpurdie 1607
    -[no]switch            - Switch to new branch(default)
1608
    -comment=text          - Comment to apply to the new branch
385 dpurdie 1609
 
1610
=head2 ARGUMENTS
1611
 
2048 dpurdie 1612
The command takes one argument. The name of the branch to be created.
385 dpurdie 1613
 
1614
=head2 OPTIONS
1615
 
1616
=over
1617
 
1618
=item B<-path=path>
1619
 
1620
This options specifies the path of the target workspace. If not provided the
1621
command will use the current directory.
1622
 
2048 dpurdie 1623
=item B<-[no]switch>
1624
 
1625
If enabled (the default) the workspace will be switched to the new branch at
1626
the end of the process.
1627
 
1628
=item B<-comment=text>
1629
 
1630
If present, the specified text will be used as a Subversion comment when the
1631
branch is created.
1632
 
1633
If not provided, then JATS will provide a basic comment.
1634
 
385 dpurdie 1635
=back
1636
 
1637
=head2 DESCRIPTION
1638
 
2048 dpurdie 1639
This command will create a named branch associated with the workspace in the
1640
specified path. It is intended to simplify the creation of Private or
385 dpurdie 1641
Development branches.
1642
 
2048 dpurdie 1643
If the named branch already exists, then the command will fail.
385 dpurdie 1644
 
2048 dpurdie 1645
The command performs a server-side copy. It will not commit any locally
1646
modified files. Nor will it inform you if there are any.
311 dpurdie 1647
 
2048 dpurdie 1648
By default, the user is 'switched' to the newly created branch.
1649
 
1650
=head1 Switch Branch
1651
 
311 dpurdie 1652
=head2 NAME
1653
 
2048 dpurdie 1654
Switch a Workspace Branch
311 dpurdie 1655
 
1656
=head2 SYNOPSIS
1657
 
2048 dpurdie 1658
jats svn switch [branch-name] [options]
311 dpurdie 1659
 
1660
 Options:
2048 dpurdie 1661
    -help[=n]              - Help message, [n=1,2,3]
1662
    -man                   - Full documentation [-help=3]
1663
    -verbose[=n]           - Verbose command operation
1664
    -path=path             - Target workspace
311 dpurdie 1665
 
1666
=head2 ARGUMENTS
1667
 
2048 dpurdie 1668
The command takes one optional argument. The name of the target branch.
311 dpurdie 1669
 
2048 dpurdie 1670
=head2 OPTIONS
1671
 
311 dpurdie 1672
=over
1673
 
2048 dpurdie 1674
=item B<-path=path>
311 dpurdie 1675
 
2048 dpurdie 1676
This options specifies the path of the target workspace. If not provided the
1677
command will use the current directory.
311 dpurdie 1678
 
2048 dpurdie 1679
=back
311 dpurdie 1680
 
2048 dpurdie 1681
=head2 DESCRIPTION
311 dpurdie 1682
 
2048 dpurdie 1683
This command will switch the users workspace to the named branch. This is
1684
identical to the Subversion switch command, except it is easier to user and
1685
has several validity checks and other enhancements.
311 dpurdie 1686
 
2048 dpurdie 1687
The command has two modes of operation:
311 dpurdie 1688
 
2048 dpurdie 1689
=over 4
311 dpurdie 1690
 
2048 dpurdie 1691
=item   1. Display a list of branched in the current package.
311 dpurdie 1692
 
2048 dpurdie 1693
If no branch is specified, then the utility will display a list of branches in
1694
the packages 'branches' directory.
311 dpurdie 1695
 
2048 dpurdie 1696
=item   2. Switch to the named branch.
311 dpurdie 1697
 
2048 dpurdie 1698
The named branch must exists otherwise the command will fail.
311 dpurdie 1699
 
2354 dpurdie 1700
There are two special variants of the branch name:
311 dpurdie 1701
 
2048 dpurdie 1702
=over 4
311 dpurdie 1703
 
2048 dpurdie 1704
=item trunk
311 dpurdie 1705
 
2048 dpurdie 1706
If the branch is named 'trunk' then it will refer to the packages truck
1356 dpurdie 1707
 
2048 dpurdie 1708
=item tags
1356 dpurdie 1709
 
2048 dpurdie 1710
If the branch name starts with 'tags/', then the command will refer to
1711
a tag within the package and not a branch.
1356 dpurdie 1712
 
2048 dpurdie 1713
=back
1356 dpurdie 1714
 
2048 dpurdie 1715
The command will add and remove unmodified files from the workspace during this
1716
operation.
311 dpurdie 1717
 
2048 dpurdie 1718
=back
311 dpurdie 1719
 
2048 dpurdie 1720
=head3 Examples
311 dpurdie 1721
 
2048 dpurdie 1722
To switch to the packages trunk
311 dpurdie 1723
 
2048 dpurdie 1724
    jats svn switch trunk
311 dpurdie 1725
 
2048 dpurdie 1726
To switch to the a branch called MyBranch
311 dpurdie 1727
 
2048 dpurdie 1728
    jats svn switch MyBranch
311 dpurdie 1729
 
2048 dpurdie 1730
To switch to a tagged version of the package
311 dpurdie 1731
 
2048 dpurdie 1732
    jats svn switch tags/MyPackage_1.0.0000.cr
311 dpurdie 1733
 
2048 dpurdie 1734
To display a list of available branches (not tags)
311 dpurdie 1735
 
2048 dpurdie 1736
    jats svn switch
311 dpurdie 1737
 
2048 dpurdie 1738
=head1 Delete Branch
311 dpurdie 1739
 
2048 dpurdie 1740
=head2 NAME
311 dpurdie 1741
 
2048 dpurdie 1742
Delete the Workspace Branch
311 dpurdie 1743
 
2048 dpurdie 1744
=head2 SYNOPSIS
311 dpurdie 1745
 
2071 dpurdie 1746
jats svn delete-branch [options] [branch-list]
311 dpurdie 1747
 
2048 dpurdie 1748
 Options:
1749
    -help[=n]              - Help message, [n=1,2,3]
1750
    -man                   - Full documentation [-help=3]
1751
    -verbose[=n]           - Verbose command operation
1752
    -path=path             - Target workspace
311 dpurdie 1753
 
2048 dpurdie 1754
=head2 ARGUMENTS
1755
 
2354 dpurdie 1756
The command may take zero or more arguments. If provided the arguments will be
2071 dpurdie 1757
branch names to be deleted.
2048 dpurdie 1758
 
1759
=head2 OPTIONS
1760
 
1761
=over
1762
 
1763
=item B<-path=path>
1764
 
1765
This options specifies the path of the target workspace. If not provided the
1766
command will use the current directory.
1767
 
1768
=back
1769
 
1770
=head2 DESCRIPTION
1771
 
2071 dpurdie 1772
This command can display the branch associated with the workspace or it can
1773
delete one or more branches. It is intended to simplify the deletion of Private
1774
or Development branches.
2048 dpurdie 1775
 
2071 dpurdie 1776
=over 4
1777
 
1778
=item 1 Arguments are provided
1779
 
1780
The command will delete all the named branches. If a named branch does not exist
1781
then the command will issue a warning message.
1782
 
1783
=item 2 No arguments provided
1784
 
1785
The command will display the branch associated with the workspace
1786
 
2048 dpurdie 1787
If the workspace is not linked to a 'branch' then the command will fail.
1788
 
2071 dpurdie 1789
=back
1790
 
311 dpurdie 1791
=head1 Import directory to a Package
1792
 
1793
=head2 NAME
1794
 
1795
Import directory to a Package
1796
 
1797
=head2 SYNOPSIS
1798
 
1799
jats svn [options] import URL [command options]
1800
 
1801
 Options:
1802
    -help[=n]               - Help message, [n=1,2,3]
1803
    -man                    - Full documentation [-help=3]
1804
    -verbose[=n]            - Verbose command operation
1805
 
1806
 Command Options
1807
    -help[=n]               - Command specific help, [n=1,2,3]
1808
    -verbose[=n]            - Verbose operation
1809
    -package=name           - Name of source package
1810
    -dir=path               - Path to new version
379 dpurdie 1811
    -label=label            - Label the result
1812
    -branch=branchName      - Base import on a branch
311 dpurdie 1813
    -replace                - Allow the label to be replaced
1814
    -reuse                  - Reuse the import directory
1815
    -workspace=path         - Path and name of alternate workspace
1816
    -[no]delete             - Deletes workspace after use. Default:yes
379 dpurdie 1817
    -author=name            - Force author of changes
1818
    -date=dateString        - Force date of changes
1819
    -log=text               - Append text to the commit message
1820
    -datafile=path          - Export tag data for automation
311 dpurdie 1821
 
1822
=head2 ARGUMENTS
1823
 
1824
The command takes one argument: The URL of the desired package.
1825
This may be be:
1826
 
1827
=over
1828
 
1829
=item * A full URL
1830
 
1831
Complete with protocol and path information.
1832
 
1833
=item * A simple URL
1834
 
1835
JATS will prepend the site-specific repository location to the user provided URL
1836
 
1837
=back
1838
 
1839
=head2 OPTIONS
1840
 
1841
=over
1842
 
1843
=item -help[=n]
1844
 
1845
Print a help message and exit. The level of help may be either 1, 2 or 3.
1846
 
1847
This option may be specified multiple times to increment the help level, or
1848
the help level may be directly specified as a number.
1849
 
1850
=item -verbose[=n]
1851
 
1852
This option will increase the level of verbosity of the utility.
1853
 
1854
If an argument is provided, then it will be used to set the level, otherwise the
1855
existing level will be incremented. This option may be specified multiple times.
1856
 
1857
=item -package=name
1858
 
1859
Either this option or a bare URL on the command line must be provided. It
1860
specifies the repository and package to be used as a basis for the work.
1861
 
1862
=item -dir=path
1863
 
1864
This option is mandatory. It specifies the path to a local directory that
1865
contains a version of the software to be checked in.
1866
 
1867
=item -label=name
1868
 
1869
The resulting software version will be labeled with this tag, if it is provided.
1870
 
383 dpurdie 1871
A label name of TIMESTAMP will be treated in special manner. The name will be
1872
replaced with a unique name based on the users name and the current date time.
1873
 
379 dpurdie 1874
=item -branch=branchName
1875
 
1876
This option will cause the importation to be referenced to the named branch.
1877
If the branch does not exist it will be created. If it does exist then it will
1878
be used.
1879
 
1880
If this option is not specified, then the importation will be based on the 'trunk'.
1881
 
1882
If the Workspace is provided, then it will be used independently of this option.
1883
 
383 dpurdie 1884
A branchName of TIMESTAMP will be treated in special manner. The name will be
1885
replaced with a unique name based on the users name and the current date time.
1886
 
311 dpurdie 1887
=item -replace
1888
 
1889
This option, if provided, allows the label to be replaced.
1890
 
1891
=item -reuse
1892
 
1893
This option can be used to speed the creation of multiple versions in a scripted
1894
environment. The option allows the utility to reuse the workspace if it exists.
1895
 
1896
=item -workspace=path
1897
 
1898
This option specifies an alternate workspace directory to create and use. The
1899
default directory is "SvnImportDir" within the users current directory.
1900
 
1901
=item [no]delete
1902
 
341 dpurdie 1903
This option control the deletion of the workspace directory. By default the
311 dpurdie 1904
directory will be deleted, unless re-use is also used.
1905
 
379 dpurdie 1906
=item -author=name
1907
 
1908
This option will force the author of changes as recorded in the repository.
385 dpurdie 1909
The repository must be configured to allow such changes.
379 dpurdie 1910
 
1911
This option may not work for non-admin users.
1912
 
1913
=item -date=dateString
1914
 
1915
This option will force the date of the changes as recorded in the repository.
385 dpurdie 1916
The repository must be configured to allow such changes.
379 dpurdie 1917
The dateString is in a restricted ISO 8601 format: ie 2009-02-12T00:44:04.921324Z
1918
 
1919
This option may not work for non-admin users.
1920
 
1921
=item -log=text
1922
 
1923
This option will append the specified text to the commit message.
1924
The first line of the commit message is fixed by the import tool.
1925
 
1926
=item -datafile=path
1927
 
1928
This option will cause the utility to create a data file to record the import
1929
tag. It is used for automation of the import process.
1930
 
311 dpurdie 1931
=back
1932
 
1933
=head2 DESCRIPTION
1934
 
1935
Import a new version of a package to the trunk of the package. The utility
1936
will only import changed files so that file history is preserved within the
1937
repository.
1938
 
1939
This utility is used import software from another version control system
1940
The utility will:
1941
 
1942
=over
1943
 
361 dpurdie 1944
=item *
311 dpurdie 1945
 
361 dpurdie 1946
Create a Work Space based on the current package version
1947
 
379 dpurdie 1948
The 'trunk' of the named package will be used as the base for the workspace,
1949
unless modified with the -branch option.
311 dpurdie 1950
 
361 dpurdie 1951
=item *
311 dpurdie 1952
 
361 dpurdie 1953
Update files and directories
1954
 
311 dpurdie 1955
Determines the files and directories that have been added and deleted and
1956
update the Workspace to reflect the new structure.
1957
 
361 dpurdie 1958
=item *
311 dpurdie 1959
 
361 dpurdie 1960
Check in the new version
311 dpurdie 1961
 
361 dpurdie 1962
=item *
1963
 
1964
Label the new version
1965
 
311 dpurdie 1966
=back
1967
 
1968
=cut
1969