Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
267 dpurdie 1
########################################################################
2
# Copyright ( C ) 2008 ERG Limited, All rights reserved
3
#
4
# Module name   : jats_svnasave_build.pl
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : Build Daemon Support Utility
10
#                 This utility will:
341 dpurdie 11
#                   +   Assume the CWD is where the build file is located
12
#                   +   Within a version controlled view
267 dpurdie 13
#                   +   Determine a suitable label for the package
14
#                   +   Save the build file in the view
15
#                   +   Label the resultant view
16
#
17
# Usage:        : See POD at end of this file
18
#
19
#               jats etool  jats_svnasave_build
20
#                   -infile     auto.xml/auto.pl
21
#                   -outfile    xxxdepends.xml/build.pl
22
#                   -pname      package_name
23
#                   -pversion   package_version
24
#                   -infofile   path_to_info_file
341 dpurdie 25
#                   -baselabel  View label
353 dpurdie 26
#                   -isawip     Is A WIP (optional)
267 dpurdie 27
#
28
#......................................................................#
29
 
30
use strict;
31
use warnings;
32
use JatsError;
33
use JatsBuildFiles;
34
use JatsSystem;
35
use JatsProperties;
36
use Getopt::Long;
37
use Pod::Usage;                             # required for help support
38
use File::Copy;
39
use JatsSvn;
40
use Cwd;
41
 
42
################################################################################
43
#   Option variables
44
#
45
 
46
my $VERSION = "2.0.0";                      # Update this
47
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
48
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
49
my $opt_infile  = "auto.pl";
50
my $opt_ofile = "build.pl";
51
my $opt_help = 0;
52
my $opt_infofile;
53
my $opt_pname;
54
my $opt_pversion;
341 dpurdie 55
my $opt_baselabel;
353 dpurdie 56
my $opt_isa_wip;
267 dpurdie 57
 
58
#
59
#   Globals
60
#
61
my $root_dir;
62
my $tag_label;
63
 
64
my $ws_root;
65
my $pkg_root;
66
 
67
#
68
#   Configuration options
69
#
70
my $result = GetOptions (
71
                "help:+"        => \$opt_help,              # flag, multiple use allowed
72
                "manual:3"      => \$opt_help,              # flag
73
                "verbose:+"     => \$opt_verbose,           # flag
74
 
75
                "outfile=s"     => \$opt_ofile,             # string
76
                "infile=s"      => \$opt_infile,            # string
77
 
78
                "infofile=s"    => \$opt_infofile,          # string
79
                "pname=s"       => \$opt_pname,             # string
80
                "pversion=s"    => \$opt_pversion,          # string
341 dpurdie 81
                "baselabel=s"   => \$opt_baselabel,         # string
353 dpurdie 82
                "isawip:+"      => \$opt_isa_wip,           # Flag
267 dpurdie 83
 
84
                #
85
                #   Update documentation at the end of the file
86
                #
87
                );
88
 
89
#
90
#   Process help and manual options
91
#
92
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
93
pod2usage(-verbose => 1)  if ( $opt_help == 2 );
94
pod2usage(-verbose => 2)  if ( $opt_help > 2 );
95
 
96
#
97
#   Configure the error reporting process now that we have the user options
98
#
99
ErrorConfig( 'name'    =>'SVNABTSAVE',
100
             'verbose' => $opt_verbose,
101
           );
102
 
103
Error ("Input and output file are the same: $opt_infile" )
104
    if ( $opt_infile eq $opt_ofile );
105
 
341 dpurdie 106
Error ("Base Label not provided")
107
    unless ( $opt_baselabel );
108
 
267 dpurdie 109
Error ("Package Name not provided")
110
    unless ( $opt_pname );
111
 
112
Error ("Package Version not provided")
113
    unless ( $opt_pversion );
114
 
115
Warning("Path to info file not provided")
116
    unless ( $opt_infofile );
117
 
118
unlink ($opt_infofile) if $opt_infofile;
119
 
120
#
341 dpurdie 121
#   User must have changed to the directory with build files
267 dpurdie 122
#   Continue with user argument sanity check
123
#
124
Error ("Input file not found: $opt_infile" )
125
    unless ( -f $opt_infile );
126
 
127
Error ("Output file not found: $opt_ofile" )
128
    unless ( -f $opt_ofile );
129
 
130
 
131
#
132
#   Create a SubVersion Session using the current workspace
133
#   as a basis. Error if not a workspace
134
#
135
my $session = NewSessionByWS( '.' );
136
 
137
Verbose ("Determine the current workspace root" );
138
$ws_root = $session->SvnLocateWsRoot(1) || '';
139
$pkg_root = $session->Full;
140
 
141
Verbose ("Workspace root: $ws_root");
142
Verbose ("Package root  : $pkg_root");
143
 
144
#
145
#   Determine the desired label for the package
146
#   May need to pick an unassigned label
147
#
148
determine_package_label();
149
 
150
#
151
#   Update the build file
152
#   Under subversion this is a simple 'copy'
153
#
154
Verbose ("Update build files");
155
unlink $opt_ofile;
156
unless ( File::Copy::copy($opt_infile, $opt_ofile) )
157
{
158
    Error("Failed to copy file [$opt_infile] to [$opt_ofile]: $!");
159
    Error ("Updating build files","Reason: $!");
160
}
161
 
162
#
163
#   Change back to original directory
164
#
165
if ( $root_dir )
166
{
167
    chdir $root_dir || Error ("Cannot change directory: $root_dir");
168
}
169
 
170
#
171
#   Label the view
172
#
173
label_build_view();
174
 
175
exit 0;
176
 
177
#-------------------------------------------------------------------------------
178
# Function        : determine_package_label
179
#
180
# Description     : Determine the label that is to be applied to the package
181
#                   There are several cases to consider
182
#                       1) Compatability mode: User provides label
183
#                       2) WIP Mode. Determine name of label to use in rename
184
#                       3) Create a new label
185
#
186
# Inputs          : Globals
187
#
188
# Returns         : Globals
353 dpurdie 189
#                       $tag_label
267 dpurdie 190
#
191
sub determine_package_label
192
{
193
 
194
    #
195
    #   Determine the desired label for the package
196
    #   This is a function of the package name and the package version
197
    #   The two are joined with a '.'
198
    #
199
    $tag_label = $opt_pname . '_' . $opt_pversion;
200
 
201
    #
202
    #   Ensure that desired label is "free", if not then hunt for a new one
203
    #   Determine the name of a 'new' label
204
    #
205
    my $base_label = $tag_label;
206
    my $index = 0;
207
 
208
    while ( ++$index )
209
    {
210
        if ( $index > 20 )
211
        {
212
            Error ("Cannot determine new label. Retry limit exceeded");
213
        }
214
        Verbose2 ("Trying $tag_label");
215
 
216
        if ( $session->SvnValidateTarget (
217
                    'target' => $session->BranchName($tag_label, 'tags' ),
218
                    'test' => 1,
219
                    ))
220
        {
221
            #
222
            #   Label found - so try another
223
            #
224
            Verbose2("Label found. Try another");
225
            $tag_label = $base_label . '.' . $index;
226
            next;
227
        }
228
 
229
        #
230
        #   Warn about non standard label
231
        #
232
        Verbose ("Package will be labeled: $tag_label");
233
        Warning ("Labeling with a non-standard label: $tag_label" )
234
            if ( $index > 1 );
235
        last;
236
    }
237
 
238
    #
239
    #   Free label has been found
240
    #
241
}
242
 
243
#-------------------------------------------------------------------------------
244
# Function        : label_build_view
245
#
246
# Description     : Label the view
247
#
248
#                   Either:
249
#                       Rename the WIP label to required name
250
#                       Label all files in the view
251
#                   
252
#                   Use JATS to do the hard work
253
#
254
#
255
# Inputs          : Globals
256
#
257
# Returns         : 
258
#
259
sub label_build_view
260
{
1329 dpurdie 261
    my $author;
262
 
267 dpurdie 263
    #
1329 dpurdie 264
    #   Determine the author of the workspace - before we update it
265
    #   The original author will be used to mark the work in the repo
266
    #   This better describes the task done
267
    #
268
    $author = $session->{'InfoWs'}{'Last Changed Author'};
269
    Error ("Internal: Svn Session data item 'InfoWs' not present")
270
        unless ( defined $author );
271
 
272
    #
267 dpurdie 273
    #   Save the current workspace - with its modified build file
274
    #
275
    Verbose ("Apply new label to package: $tag_label");
276
    $session->SvnCopyWs (
1403 dpurdie 277
               'target'         => $session->BranchName($tag_label, 'tags' ),
278
               'modified'       => $opt_ofile,
279
               'noswitch'       => 1,
280
               'replace'        => 0,
281
               'comment'        => 'Created by Jats SaveBuild',
282
               'noupdatecheck'  => 2,
267 dpurdie 283
               );
284
    Message ("Repository Ref: " . $session->RmRef);
1403 dpurdie 285
    Message ("Vcs Tag       : " . $session->SvnTag);
267 dpurdie 286
 
1329 dpurdie 287
    #
288
    #   Update the svn:author of the workspace rather than 'buildadm'
1403 dpurdie 289
    #   Allow badly configured repos. Don't fail if can't update the author
1329 dpurdie 290
    #
291
    Verbose ("Author: $author");
1403 dpurdie 292
    $session->setRepoProperty('svn:author', $author, 1);
1329 dpurdie 293
 
357 dpurdie 294
    if ( $opt_isa_wip )
267 dpurdie 295
    {
1403 dpurdie 296
        Verbose( 'Is a WIP');
297
        Verbose( '$session->WsType: ', $session->WsType);
298
        Verbose( '$opt_baselabel: ', $opt_baselabel);
267 dpurdie 299
        #
1403 dpurdie 300
        #   If the build is based on a WIP then we can delete the WIP
301
        #   tag under the following conditions:
302
        #       It is a true tag - and not a 'peg'
303
        #       It is a true WIP - and not a copy of another label
304
        #                          ie: Ends in .WIP - with possible peg
267 dpurdie 305
        #
1403 dpurdie 306
        if ( $opt_baselabel =~ m~(.+)::(.+)~ )
267 dpurdie 307
        {
1403 dpurdie 308
            my $baseTag = $2;
309
            if ( $baseTag =~ m~\.WIP(\@\d+)?$~)
310
            {
311
                $session->SvnDelete(
312
                        'target'  => $session->FullPath . '/tags/' . $baseTag,
313
                        'comment' => ["Deleted by Jats SaveBuild","Replaced by: $tag_label"],
314
                        'noerror' => 1,
315
                         );
316
            }
317
            else
318
            {
319
                Message ("WIP not deleted.","Will not delete WIPS of this type:" . $opt_baselabel );
320
            }
267 dpurdie 321
        }
322
        else
323
        {
1403 dpurdie 324
            Message ("WIP not deleted.","Cannot parse baselabel: " . $opt_baselabel );
267 dpurdie 325
        }
326
    }
327
 
328
    #
329
    #   Write the label out to the specified file so that the user
330
    #   can do something with it
331
    #
332
    if ( $opt_infofile )
333
    {
334
 
335
        my $data = JatsProperties::New();
336
 
337
        $data->setProperty('Label', $tag_label);
357 dpurdie 338
        $data->setProperty('WipLabel', $opt_baselabel) if $opt_isa_wip;
267 dpurdie 339
        $data->setProperty('PackageName', $opt_pname);
340
        $data->setProperty('PackageVersion', $opt_pversion);
341
        $data->setProperty('subversion.tag', $session->RmRef);
1403 dpurdie 342
        $data->setProperty('VCS.tag', 'SVN::' . $session->SvnTag);
267 dpurdie 343
 
344
        $data->Dump('InfoFile') if ($opt_verbose);
345
        $data->store( $opt_infofile );
346
    }
347
}
348
 
349
#-------------------------------------------------------------------------------
350
#   Documentation
351
#
352
 
353
=pod
354
 
361 dpurdie 355
=for htmltoc    SYSUTIL::
356
 
267 dpurdie 357
=head1 NAME
358
 
359
jats_svnsave_build - Save a build view to version control system
360
 
361
=head1 SYNOPSIS
362
 
363
  jats etool jats_save_build [options]
364
 
365
 Options:
366
    -help[=n]           - brief help message
367
    -help -help         - Detailed help message
368
    -man[=n]            - Full documentation
369
    -verbose[=n]        - Verbose operation
370
    -infile=xxx         - Input file (auto.pl)
371
    -outfile=xxx        - Output file (build.pl)
372
    -infofile=path      - Save label information in 'path'
373
    -pname=name         - Name of the package
374
    -pversion=text      - Package version
341 dpurdie 375
    -baselabel=text     - Base label for sandbox
353 dpurdie 376
    -isawip             - Current package is a WIP
267 dpurdie 377
 
378
=head1 OPTIONS
379
 
380
=over 8
381
 
382
=item B<-help[=n]>
383
 
384
Print a brief help message and exits.
385
 
386
The verbosity of the help text can be controlled by setting the help level to a
387
number in the range of 1 to 3, or by invoking the option multiple times.
388
 
389
=item B<-man[=n]>
390
 
391
Without a numeric argument this is the same as -help=3. Full help will be
392
displayed.
393
 
394
With a numeric argument, this option is the same as -help=n.
395
 
396
=item B<-verbose[=n]>
397
 
398
This option will increase the level of verbosity of the utility.
399
 
400
If an argument is provided, then it will be used to set the level, otherwise the
401
existing level will be incremented. This option may be specified multiple times.
402
 
403
=item B<-infile=xxxx>
404
 
405
This option specifies the name of the generated build configuration file that
406
will be used as a data-source for the check-in build file.
407
 
408
The default file name is 'auto.pl'.
409
 
410
=item B<-outfile=xxxx>
411
 
412
This option specifies the name of the target build configuration file that
413
will be checked in to version-control. Data from from file specifies with '-
414
infile' will be used to update the file.
415
 
416
The default file name is 'build.pl'.
417
 
418
=item B<-infofile=path>
419
 
420
This option specifies a file that this utility will use to communicate with a
421
user script. It will write the new label text into the file.
422
 
423
The file path is relative to the current working directory.
424
 
425
The file will be deleted, and only created if the utility is successful.
426
 
427
=item B<-pname=name>
428
 
429
This option specifies the package name. It will be used to construct a new
430
label for the package.
431
 
432
=item B<-pversion=xxx>
433
 
434
This option specifies the package version. It will be used to construct a new
435
label for the package.
436
 
353 dpurdie 437
=item B<-baselabel=text>
438
 
439
This option specifies the Version Control Label that the current workspace
440
is based on. This may be used to determine the new label for the package.
441
 
442
This parameter is mandatory.
443
 
444
=item B<-isawip>
445
 
267 dpurdie 446
This option controls the manner in which this utility will label the build view.
447
 
448
If present, the label specifies a 'Work In Progress' label. The label will be
449
renamed. At the end of the process the wip label will be deleted from the
450
the repository.
451
 
452
If not present, then the view will be labeled with a new label.
453
 
454
=back
455
 
456
=head1 DESCRIPTION
457
 
458
This utility is used by the automated build system to place build view under
459
version control. The utility will:
460
 
461
=over 8
462
 
361 dpurdie 463
=item *
267 dpurdie 464
 
361 dpurdie 465
Determine a suitable label for the package
466
 
267 dpurdie 467
The label is constructed from the package name and the package version. The
468
utility will ensure that the label does not already exist. If it does it will
469
use an alternate form of the label.
470
 
361 dpurdie 471
=item *
267 dpurdie 472
 
361 dpurdie 473
Locate the build files within the package
474
 
267 dpurdie 475
JATS build files do not need to be at the root of the package. The utility
476
will locate the JATS build files.
477
 
361 dpurdie 478
=item *
267 dpurdie 479
 
361 dpurdie 480
Update the build files and save them into the version control system
481
 
267 dpurdie 482
The build file will be updated with new version information as provided by a
483
secondary configuration file.
484
 
485
The updated file will be checked into version control.
486
 
361 dpurdie 487
=item *
267 dpurdie 488
 
361 dpurdie 489
Ensure that the package is labeled
490
 
267 dpurdie 491
The build view will be labeled (tagged).
492
 
493
If a WIP label is provided then the WIP label will be removed if it is a branch.
494
 
361 dpurdie 495
=item *
267 dpurdie 496
 
361 dpurdie 497
Return the label to the user
498
 
267 dpurdie 499
The label used to label the package will be returned to the user in an 'info'
500
file. This is a 'properties' file. The following properties are defined:
501
 
502
=over 8
503
 
361 dpurdie 504
=item 1
267 dpurdie 505
 
361 dpurdie 506
Label - The label used to tag the file
267 dpurdie 507
 
361 dpurdie 508
=item 2
267 dpurdie 509
 
361 dpurdie 510
PackageName - The package name
511
 
512
=item 3
513
 
514
PackageVersion - The package version
515
 
267 dpurdie 516
=back
517
 
518
=back
519
 
520
=cut
521