Subversion Repositories DevTools

Rev

Rev 6177 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
267 dpurdie 1
########################################################################
6177 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
267 dpurdie 3
#
4
# Module name   : jats_svnlabel.pl
5
# Module type   : Jats Utility
6
# Compiler(s)   : Perl
7
# Environment(s): Jats
8
#
9
# Description   : A script to perform a number of labeling operations
10
#                 The script will:
11
#                   label a workspace       - Create a tag
12
#                   delete a label          - Deletes a tag
13
#                   rename a label          - Renames a tag
14
#                   clone a label           - Clones a tag
15
#
16
#......................................................................#
17
 
18
require 5.006_001;
19
use strict;
20
use warnings;
21
use JatsError;
22
use JatsSvn;
23
 
24
use Pod::Usage;                             # required for help support
25
use Getopt::Long;
7262 dpurdie 26
use FileUtils;
267 dpurdie 27
 
28
my $VERSION = "1.0.0";                      # Update this
29
 
30
#
31
#   Options
32
#
33
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
34
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
35
my $opt_help = 0;
36
my $opt_check;
37
my $opt_avail;
38
my $opt_label;
39
my $opt_replace;
40
my $opt_delete;
41
my $opt_rename;
42
my $opt_clone;
43
my $opt_comment;
44
my $opt_workspace;
45
my $opt_packagebase;
46
my $opt_branch;
47
my $opt_list;
385 dpurdie 48
my $opt_author;
49
my $opt_date;
50
my $opt_complexTag;
1403 dpurdie 51
my $opt_noUpdateCheck;
267 dpurdie 52
 
53
#
54
#   Globals
55
#
56
my $session;                                # Subversion Session
57
my $label;                                  # User argument - one label
58
my $src_label;                              # User specified source label
59
my $pkg_root;                               # Root of corresponding package
60
my $opr_done;                               # User has done something
61
 
62
#-------------------------------------------------------------------------------
63
# Function        : Mainline Entry Point
64
#
65
# Description     :
66
#
67
# Inputs          :
68
#
69
my $result = GetOptions (
385 dpurdie 70
                'help:+'        => \$opt_help,              # flag, multiple use allowed
71
                'manual:3'      => \$opt_help,              # flag
72
                'verbose:+'     => \$opt_verbose,           # flag, multiple use allowed
73
                'check'         => \$opt_check,             # Flag
74
                'available'     => \$opt_avail,             # Flag
75
                'label'         => \$opt_label,             # Flag
76
                'auto'          => \$opt_label,             # Same as -label
77
                'delete'        => \$opt_delete,            # Flag
78
                'replace!'      => \$opt_replace,           # Flag
79
                'rename=s'      => \$opt_rename,            # String
80
                'clone=s'       => \$opt_clone,             # String
81
                'comment=s'     => \$opt_comment,           # String
82
                'workspace=s'   => \$opt_workspace,         # String
83
                'packagebase=s' => \$opt_packagebase,       # String
84
                'branch'        => \$opt_branch,            # Flag
85
                'list'          => \$opt_list,              # Flag
86
                'author=s'      => \$opt_author,            # String
87
                'date=s'        => \$opt_date,              # String
1329 dpurdie 88
                'allowlocalmods!'   => \$opt_complexTag,    # [no]aaaaaa
1403 dpurdie 89
                'allowRepoChanges!'   => \$opt_noUpdateCheck, # [no]aaaaaa
90
 
267 dpurdie 91
                );
92
 
93
                #
94
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
95
                #
96
 
97
#
98
#   Process help and manual options
99
#
100
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
101
pod2usage(-verbose => 1) if ($opt_help == 2 );
102
pod2usage(-verbose => 2) if ($opt_help > 2);
103
 
104
#
105
#   Configure the error reporting process now that we have the user options
106
#
7262 dpurdie 107
InitFileUtils();
267 dpurdie 108
ErrorConfig( 'name'    =>'SVNLABEL',
109
             'verbose' => $opt_verbose,
110
            );
111
 
112
#
113
#   Validate user options
114
#   Need one command line argument
115
#
116
Error ("No labels provided") if ( $#ARGV < 0 && !$opt_list );
117
Error ("Too many labels provided") if ( $#ARGV > 0);
375 dpurdie 118
Error ("Conflicting options. Clone and Label") if ( $opt_clone && $opt_label );
119
Error ("Conflicting options. Rename and Label") if ( $opt_rename && $opt_label );
267 dpurdie 120
$label = $ARGV[0];
121
 
122
#
1403 dpurdie 123
#   Process user label specification
124
#   May in the form SVN::Path::Tag
125
#
126
$label =~ s~^SVN::~~ if $label;
127
if ( $label =~ m~(.+)::(.+)~ )
128
{
129
    my $sourcePath = $1;
130
    my $tag = $2;
131
 
132
    #
133
    #   Sanity test of sourcePath
134
    #
135
    Error ("Invalid use of a peg: $label")
136
        if ( $sourcePath =~ m~\@\d+$~ );
137
 
138
    #
139
    #   Remove anything after a ttb (truck, tags, branch) element
140
    #   This will be the root of the package within the repo
141
    #
142
    if (  $sourcePath =~ m~(.*)/((tags|branches|trunk)(/|$)(.*))~ )
143
    {
144
        Error ("Source Path has insufficient items")
145
            if ( $1 eq '' );
146
 
147
        Error ("SourcePath contains invalid items after '$3': '$5'")
148
            if ( ($3 eq 'tags' || $3 eq 'trunk') && $5 ne '' );
149
 
150
        Error ("SourcePath must contain items after 'branches'")
151
            if ( $3 eq 'branches' && $5 eq '');
152
 
153
        $label = $1 . '/tags/' . $tag;
154
    }
155
    else
156
    {
157
        Error ("Source Path does not contain tags or trunk or branches component");
158
    }
159
Verbose ("Tag: $label");
160
}
161
 
162
#
267 dpurdie 163
#   Locate package and workspace roots
164
#
165
LocateRoots ();
166
 
167
################################################################################
168
#
169
#   Validate one or more labels
170
#   Intended to be used within scripts for testing
171
#
172
if ( $opt_check )
173
{
174
    $session->SvnValidateTarget
175
    (
176
        'target'    => make_src_label ($pkg_root, $label),
341 dpurdie 177
        'cmd'       => 'Validate Existence',
267 dpurdie 178
        'require'   => 1,
179
    );
180
    $opr_done = 1;
181
}
182
 
183
if ( $opt_avail )
184
{
185
    $session->SvnValidateTarget
186
    (
187
        'target'    => make_src_label ($pkg_root, $label),
188
        'cmd'       => 'Validate Availablility',
189
        'available' => 1,
190
    );
191
    $opr_done = 1;
192
}
193
 
194
################################################################################
195
#
196
#   List labels
197
#
198
if ( $opt_list )
199
{
200
    my $pList = $session->ListLabels (make_label ($pkg_root, '') );
201
 
202
    #
379 dpurdie 203
    #   Remove trailing / on all directory names
267 dpurdie 204
    #
205
    chop @{$pList};
206
 
207
    my $type = $opt_branch ? 'branch' : 'tag';
208
    Information ( "Package: " . $session->Path,
209
                    ,map ( $type . ': ' . $_, @{$pList})
210
                    );
211
    $opr_done = 1;
212
}
213
 
214
 
215
################################################################################
216
#
217
#   Rename a label
218
#   This has implications for stuff that is stored within release manager
219
#
220
#   Renaming a pegged version is problematical
221
#   At the moment we do a copy ( rename, without the delete)
222
#
223
if ( $opt_rename )
224
{
225
    #
226
    #   Create old and new paths for the full label
227
    #
228
    my $ws_label_old = make_src_label ($pkg_root, $label);
1403 dpurdie 229
    my $label_new = SvnIsaSimpleLabel($opt_rename);
230
    my $ws_label_new = make_label ($pkg_root , $label_new);
267 dpurdie 231
 
232
    $session->SvnRename (
233
                'old' => $ws_label_old,
234
                'new' => $ws_label_new,
235
                'comment' => $opt_comment ? $opt_comment : 'Renamed by Jats Svnlabel',
236
                'replace' => $opt_replace ? 1 : 0,
237
                );
238
 
239
    Message ("Repository Ref: " . $session->RmRef);
1403 dpurdie 240
    Message ("Vcs Tag       : " . $session->SvnTag);
385 dpurdie 241
    updateProperties();
267 dpurdie 242
    $opr_done = 1;
243
}
244
 
245
################################################################################
246
#   
247
#   The Svn Label need a package root
248
#   If we are in a WorkSpace, then we can determine the package root
249
#
250
if ( $opt_label )
251
{
252
    #
253
    #   Can now create a nice pathname for the label
254
    #
1403 dpurdie 255
    $label = SvnIsaSimpleLabel ($label);
256
    my $ws_label = make_label( $pkg_root, $label );
267 dpurdie 257
 
258
    #
259
    #   Don't let the user create a tag from a workspace that is
260
    #   also created from a tag.
261
    #
262
    #   They should be using a branch.
263
    #   Can't stop them - but can make it difficult.
264
    #
265
    Error ("Cannot tag a Workspace based on a 'tag'",
266
           "You should be working in a branch",
267
           "WorkSpace: $session->{WSURL}" )
379 dpurdie 268
        if ( !$opt_branch && (($session->WsType) eq 'tags') );
267 dpurdie 269
 
1329 dpurdie 270
    #
271
    #   The label operation *should* be a server side operation only
1403 dpurdie 272
    #   If the user has commited changes, but not yet updated the local
1329 dpurdie 273
    #   workspace, then subversion will do a client side copy
274
    #   This is not good.
275
    #       If the 'tags' area is not writable then we get a cryptic message
276
    #       If the 'tags' area is writable then we commit the changes twice
277
    #
278
    #   Solution - ensure that the Workspace is upto date
279
    #              This is done within SvnCopyWs
280
    #
267 dpurdie 281
    $session->SvnCopyWs (
282
                   target => $ws_label,
385 dpurdie 283
                   'allowLocalMods' => $opt_complexTag,
1403 dpurdie 284
                   'noupdatecheck' => $opt_noUpdateCheck,
267 dpurdie 285
                   'noswitch' => 1,
286
                   'replace' => $opt_replace ? 1 : 0,
5073 dpurdie 287
                   'comment' => $opt_comment ? $opt_comment : ('Created by Jats Svnlabel:' . $label),
267 dpurdie 288
                   );
289
 
290
    Message ("Repository Ref: " . $session->RmRef);
1403 dpurdie 291
    Message ("Vcs Tag       : " . $session->SvnTag);
385 dpurdie 292
    updateProperties();
267 dpurdie 293
    $opr_done = 1;
294
}
295
 
296
################################################################################
297
#
298
#   Delete a label
299
#   Can't really delete one, but we can remove it from the head
300
#   If SVN ever gets an 'obliterate' command then prehaps we could use it
301
#
302
if ( $opt_delete )
303
{
304
    #
305
    #   Calculate the label name to delete
306
    #
307
    my $ws_label = make_src_label( $pkg_root, $label );
308
    $session->SvnDelete ( 'target' => $ws_label,
309
                          'comment' => $opt_comment ? $opt_comment : 'Deleted by Jats Svnlabel',
1329 dpurdie 310
                          'noerror' => 0 );
267 dpurdie 311
    $opr_done = 1;
312
}
313
 
314
################################################################################
315
#
316
#   Clone a label
317
#   Essentially a copy of a tag
318
#
319
#
320
if ( $opt_clone )
321
{
322
    #
323
    #   Create old and new paths for the full label
324
    #
325
    my $ws_label_old = make_src_label ($pkg_root, $label);
1403 dpurdie 326
    my $new_label = SvnIsaSimpleLabel($opt_clone);
327
    my $ws_label_new = make_label ($pkg_root , $new_label);
328
    #
329
    #   Backtrack label so that we clone the tag source, not the tag
330
    #
331
    if ( $ws_label_old =~ m~/tags/~ )
332
    {
333
        my $tag = $label;
334
        $tag = 'tags/' . $tag unless ( $tag =~ m~^tags/~ );
335
        $ws_label_old = $session->backTrackSvnLabel( $tag, savedevbranch => 1);
336
        Verbose2 ("Tag back tracked to: $ws_label_old");
337
        $ws_label_old = $pkg_root . '/' . $ws_label_old;
338
    }
339
 
267 dpurdie 340
    $session->SvnCopy (
341
                'old' => $ws_label_old,
342
                'new' => $ws_label_new,
1403 dpurdie 343
                'comment' => $opt_comment ? $opt_comment : 'Copied by Jats Svnlabel Clone',
267 dpurdie 344
                'replace' => $opt_replace ? 1 : 0,
345
                );
346
    Message ("Repository Ref: " . $session->RmRef);
1403 dpurdie 347
    Message ("Vcs Tag       : " . $session->SvnTag);
385 dpurdie 348
    updateProperties();
267 dpurdie 349
    $opr_done = 1;
350
}
351
 
352
 
353
Error ("No valid operations specified. Try -h") unless ( $opr_done );
354
exit 0;
355
 
356
 
357
#-------------------------------------------------------------------------------
358
# Function        : make_label
359
#
360
# Description     : Create a label ( tag or branch )
361
#
362
# Inputs          : $base
363
#                   $name
364
#
365
# Returns         : Full label
366
#
367
sub make_label
368
{
369
    my ($base, $name) = @_;
370
    my $join = $opt_branch ? '/branches/' : '/tags/';
371
    return $base . $join . $name;
372
}
373
 
374
#-------------------------------------------------------------------------------
375
# Function        : make_src_label
376
#
377
# Description     : Create a source label ( tag or branch )
378
#
1403 dpurdie 379
#                   Calculation may be bypassed if the global $src_label
379 dpurdie 380
#                   is specified.
381
#
267 dpurdie 382
# Inputs          : $base
379 dpurdie 383
#                   $name           - May contain hint
384
#                                     Prefixed with 'tags/' or 'branches/'
267 dpurdie 385
#
386
# Returns         : Full label
387
#
388
sub make_src_label
389
{
390
    return $src_label if ( $src_label );
391
    my ($base, $name) = @_;
379 dpurdie 392
    my $result = $name;
1329 dpurdie 393
    unless ( $name =~ m~(^branches/)|(^tags)|(^trunk\@)~ )
379 dpurdie 394
    {
395
        $result = ($opt_branch ? 'branches/' : 'tags/' ) . $name;
396
    }
397
    return $base . '/' . $result;
267 dpurdie 398
}
399
 
400
 
401
#-------------------------------------------------------------------------------
402
# Function        : LocateRoots
403
#
404
# Description     : Determine workspace root and associated
405
#                   package root
406
#
407
#                   Uses several hint to figure it out
408
#                       The default is the package in the current directory
409
#                       -workspace - may address a workspace
410
#                       -packagebase - may specify a package base
411
#                                      Does not work with -label
412
#                                      as we need a workspace
413
#
414
#
415
# Inputs          : None - uses globals
416
#
417
# Returns         : Setup global variables
418
#
419
sub LocateRoots
420
{
421
    #
422
    #   Use current directory as the workspace unless the user
423
    #   has specified a different one
424
    #
425
    $session = NewSessionByWS( $opt_workspace || '.', $opt_workspace ? 0 : 1 );
426
 
427
    Verbose ("Determine the current workspace root" );
428
    my $ws_root = $session->SvnLocateWsRoot(1) || '';
429
 
430
    #
431
    #   Only need a WS root for the label operation
432
    #   Every thing else can live without it
433
    #
434
    Error ("Cannot determine source Workspace") if ( $opt_label && !$ws_root );
435
 
436
    #
7262 dpurdie 437
    #   If operation is 'label', then we have a Workspace
438
    #   Ensure that we are in the 'root' of the workspace - otherwise we will get cryptic messages
439
    #
440
    if ( $opt_label && $ws_root  && !$opt_workspace) {   
441
        my $pathToRoot = RelPath($ws_root);
442
        if ( $pathToRoot =~ m~^..~) {
443
            Warning("Current directory is the not the workspace root",
444
                    "The 'svn update' command will not update the entire workspace");
445
        }
446
    }
447
 
448
    #
267 dpurdie 449
    #   Calculate the package base
450
    #       - User specified
451
    #       - Extacted from label
452
    #       - Extracted from WorkSpace
453
    #           - User specified Workspace
454
    #           - Current directory
455
    #
456
    if ( $opt_packagebase )
457
    {
458
        #
459
        #   User has given us the package base
460
        #
361 dpurdie 461
        $session = NewSessionByUrl ( $opt_packagebase, 0, $session );
267 dpurdie 462
        $session->SvnValidatePackageRoot();
463
    }
375 dpurdie 464
    elsif ( (!$opt_label ) && $label && $label =~ m~(.+)(/(tags|branches|trunk)(/|@)(.+))~ )
267 dpurdie 465
    {
466
        #
375 dpurdie 467
        #   Attempt to extract it from the label, but only if we are not
468
        #   labeling a sandbox.
267 dpurdie 469
        #   Remove it from the label
470
        #
471
        $src_label = $2;
472
        $label = $5;
361 dpurdie 473
        $session = NewSessionByUrl ( $1, 0, $session );
267 dpurdie 474
        $session->SvnValidatePackageRoot();
475
        $src_label = $session->Full . $src_label;
476
    }
477
    elsif ( $ws_root )
478
    {
479
        # $s2 = $session;
480
    }
481
    else
482
    {
483
        Error ("Cannot determine the Package Base");
484
    }
485
    $pkg_root = $session->Full;
486
 
487
    #
488
    #   Everything needs a $pkg_root
489
    #
490
    Error ("Cannot determine Package Base") unless ( $pkg_root  );
491
 
492
    Verbose ("Workspace root: $ws_root");
493
    Verbose ("Package root  : $pkg_root");
494
#DebugDumpData ("Session", $session );
495
}
496
 
497
#-------------------------------------------------------------------------------
385 dpurdie 498
# Function        : updateProperties
499
#
500
# Description     : Update the properties, if present
501
#
502
# Inputs          : Globals
503
#
504
# Returns         : Nothing
505
#
506
sub updateProperties
507
{
508
    $session->setRepoProperty('svn:author', $opt_author) if (defined ($opt_author));
509
    $session->setRepoProperty('svn:date', $opt_date) if (defined ($opt_date));
510
}
511
 
512
#-------------------------------------------------------------------------------
267 dpurdie 513
#   Documentation
514
#
515
 
516
=pod
517
 
361 dpurdie 518
=for htmltoc    GENERAL::Subversion::
519
 
267 dpurdie 520
=head1 NAME
521
 
522
jats_svnlabel - Subversion label operations
523
 
524
=head1 SYNOPSIS
525
 
361 dpurdie 526
jats svnlabel [options] C<label>
267 dpurdie 527
 
528
 Options:
529
    -help                  - brief help message
530
    -help -help            - Detailed help message
531
    -man                   - Full documentation
385 dpurdie 532
    -available             - Check for label availability
267 dpurdie 533
    -check                 - Check for label existence
534
    -clone=xxx             - Clone a package version
535
    -delete                - Delete label from the repository
536
    -label                 - Labels a Package
383 dpurdie 537
    -auto                  - Same as -label
385 dpurdie 538
    -list                  - List labels in a package
267 dpurdie 539
    -rename=xxx            - Rename a label
385 dpurdie 540
 
267 dpurdie 541
 Modifiers
542
    -branch                - Use branches, not tags
543
    -replace               - Replace existing labels. Use with -label
544
    -comment=text          - Comment to add to repository operations
545
    -workspace=path        - Path to a workspace to label
385 dpurdie 546
    -packagebase=path      - Repository path to package base
547
    -author=name           - Force author of changes
548
    -date=dateString       - Force date of changes
549
    -allowLocalMods        - Allow complex tagging
1403 dpurdie 550
    -allowRepoChanges      - Supress check for an up to date workspace
267 dpurdie 551
 
552
=head1 OPTIONS
553
 
554
=over 8
555
 
556
=item B<-help>
557
 
558
Print a brief help message and exits.
559
 
560
=item B<-help -help>
561
 
562
Print a detailed help message with an explanation for each option.
563
 
564
=item B<-man>
565
 
566
Prints the manual page and exits.
567
 
568
=item B<-clone=xxx>
569
 
385 dpurdie 570
This option will copy a labeled version of a package to a new label.
267 dpurdie 571
 
572
=item B<-delete>
573
 
574
This option will delete the specified label from the repository
575
 
576
=item B<-available>
577
 
385 dpurdie 578
This option will check for the labels non-existence. An error will be reported
267 dpurdie 579
if the label exists.
580
 
581
=item B<-check>
582
 
385 dpurdie 583
This option will check for the labels existence. An error will be reported
267 dpurdie 584
if the label does not exist.
585
 
586
=item B<-label>
587
 
588
This option will label a workspace.
589
 
590
The -replace option may be used to force labels to be moved.
591
 
383 dpurdie 592
=item B<-auto>
593
 
594
This option is the same as '-label'. It is provided for compatibility with other
595
labeling tools.
596
 
267 dpurdie 597
=item B<-rename=xxx>
598
 
599
This option will rename a label. The new name of the label is provided as the
600
argument after the option. If any further operation are to be performed the
601
new label name will be used.
602
 
603
=item B<-list>
604
 
385 dpurdie 605
This option will case all labels for the related package to be shown. The
267 dpurdie 606
command assumes that the repository is in a trunk/tags/branches format.
607
 
608
By default tags are shown. Branches may be shown with the -branches option.
609
 
610
=item B<-replace>
611
 
612
This option may be used with the -label command to allow existing labels to
613
be replaced.
614
 
615
=item B<-comment=text>
616
 
617
This option provides text to be used to document the operation in the log.
618
 
619
If none is provided, then the utility will use a simple comment of its own.
620
 
621
=item B<-workspace=path>
622
 
623
This option can be used to specify the path to a workspace to be labeled.
624
 
625
If not provided then the utility will use the current directory to determine
626
the root of the workspace.
627
 
2049 dpurdie 628
=item B<-packagebase=path>
267 dpurdie 629
 
630
This option can be used to specify the path to a package within a repository.
631
 
632
If the 'label' contains a package base, then it will be extracted and used.
633
 
634
If not provided and the utility is within a workspace, then the package base will
635
be taken to be that of the package in the workspace.
636
 
637
=item B<-branch>
638
 
639
This option modifies all commands. It causes the labeling operations to be
1403 dpurdie 640
performed on a packages 'branches' area instead of the default 'tags'
267 dpurdie 641
area.
642
 
385 dpurdie 643
=item -author=name
644
 
645
This option will force the author of changes as recorded in the repository.
646
The repository must be configured to allow such changes.
647
 
648
This option may not work for non-admin users.
649
 
650
=item -date=dateString
651
 
652
This option will force the date of the changes as recorded in the repository.
653
The repository must be configured to allow such changes.
654
The dateString is in a restricted ISO 8601 format: ie 2009-02-12T00:44:04.921324Z
655
 
656
This option may not work for non-admin users.
657
 
658
=item -allowLocalMods
659
 
660
This option modifies the checking that is done when the workspace is labeled.
661
The default is to 'not' allow local modifications. All modifications must be
662
committed before the label is created.
663
 
664
If local modifications are allowed, then the utility will warn about local
665
modifications, but the labelling process will continue. This allows
666
for 'complex' tagging. The modified files will be transferred to the repository
667
and will form a part of the tag.
668
 
669
This mode of operation should NOT be used for normal labeling. It is useful for
670
the preservation of 'Mixed Workspaces'.
671
 
1403 dpurdie 672
=item -allowRepoChanges
673
 
674
This option modifies the checking that is done when the workspace is labeled.
675
The default is to 'not' allow changes between the Workspace and the Repository.
676
Normally the Workspace must be up to date with respect to the head of the
677
development branch.
678
 
679
If Repository Changes are allowed, then the utility will warn about changes, but
680
the labelling process will continue. This allows Workspaces that have been
681
pegged to old versions to be tagged.
682
 
683
The Repository may still reject the tag if the workspace has been modified in
684
a manner that would result in a client-side copy. This is intentional.
685
 
267 dpurdie 686
=back
687
 
688
=head1 DESCRIPTION
689
 
690
This program provides a number of useful Subversion labeling operations. These
691
are:
692
 
693
=over 8
694
 
361 dpurdie 695
=item   *
267 dpurdie 696
 
385 dpurdie 697
check - check existence of a label
267 dpurdie 698
 
361 dpurdie 699
=item   *
267 dpurdie 700
 
385 dpurdie 701
available - check non-existence of a label
267 dpurdie 702
 
361 dpurdie 703
=item   *
267 dpurdie 704
 
375 dpurdie 705
list - list the labels on a package
267 dpurdie 706
 
361 dpurdie 707
=item   *
267 dpurdie 708
 
361 dpurdie 709
rename - rename a label
710
 
711
=item   *
712
 
713
label - label a workspace
714
 
715
=item   *
716
 
717
delete - delete a label
718
 
719
=item   *
720
 
721
clone - duplicate a label
722
 
267 dpurdie 723
=back
724
 
725
The various operations may be mixed in the one command. The order of the
726
operations is: check, available, list, rename, label, delete and clone
727
 
728
=head2 LABEL format
729
 
730
A 'label' as used by JATS within a Subversion repository, may have four elements.
731
These are:
732
 
733
=over
734
 
735
=item   * Package Path
736
 
385 dpurdie 737
Any text proceeding a / will be taken to be a package path. This identifies the
267 dpurdie 738
root of the package within the repository.
739
 
740
=item   * Label Type
741
 
742
This will be one of 'trunk', 'branches' or 'tags'.
743
 
744
Normally labels are placed on the 'tags' subdirectory of a package.
745
 
746
=item   * Simple Label
747
 
341 dpurdie 748
The label tag. It can only contain Alphanumerics and the characters :-_.
267 dpurdie 749
In practice this can be a simple version number as the labels are held the
750
context of a package.
751
 
383 dpurdie 752
A simple label of TIMESTAMP will be treated in special manner. The name will be
753
replaced with a unique name based on the users name and the current date time.
754
 
267 dpurdie 755
=item   * Peg
756
 
757
A peg consists of a '@' and a number string at the end of the label.
758
 
759
=back
760
 
761
An example of a full label is: repo/package/component/tags/label_text@1234
762
 
763
Not all operation support the full label syntax. The 'peg' is not allowed in
764
a label that will be used as a target of a repository copy operation, nor
765
is the 'Package Path'.
766
 
767
Full labels can be used in operations that specify the source of a
768
copy operation, such as a delete, rename or clone operation.
769
 
770
All operations report a 'Full Label' that can be used to reference the
341 dpurdie 771
repository at any time in the future. This is the 'tag' that needs to be
267 dpurdie 772
provided to 'Release Manager in order to reproduce the package.
773
 
774
=head1 EXAMPLE
775
 
776
jats svnlabel -label daf_br_23.0.0.syd
777
 
778
=cut
779