Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
4625 dpurdie 1
########################################################################
2
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
3
#
4
# Module name   : process_release_notes.pl
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : Poll RM and generate Release Notes as required
10
#                 Must run on the same machine as the package archive
11
#                 It directly manipulates the target package
12
#                 Requires access to the machines sudo mechism
13
#
14
# Usage         : See POD at the end of this file
15
#
16
#......................................................................#
17
 
18
require 5.008_002;
19
 
20
use strict;
21
use warnings;
22
use JatsError;
23
use JatsSystem;
24
use Getopt::Long;
25
use Pod::Usage;                             # required for help support
26
use File::Temp qw/ tempfile tempdir /;
27
use LWP::UserAgent;
28
use HTTP::Request::Common 'POST';
29
use Fcntl ':flock';
30
use FindBin;                                # Determine the current directory
31
 
32
use JatsEnv;
33
use JatsRmApi;
34
use FileUtils;
35
 
36
use DBI;
37
 
38
my $VERSION = "1.0.0";                      # Update this
39
my $GBE_DPKG = $ENV{GBE_DPKG};              # Sanitised by Jats
4698 dpurdie 40
my $GBE_RM_URL = $ENV{GBE_RM_URL};
4625 dpurdie 41
my $RM_DB;
42
my $tempdir;
43
my $sudoUtilsDir = '/home/releasem/sbin';
44
my $lockFile = '/tmp/JATSRN_LOCK';
45
my $scriptDir = "$FindBin::Bin";
46
 
47
#
48
#   Options
49
#
50
my $opt_verbose = 0;
51
my $opt_help = 0;
52
my $opt_age = 2;
53
my $opt_keepTemp = 0;
54
my $opt_status = 0;
55
my $opt_pvid;
56
 
57
#
58
#   Package information
59
#
60
my @Packages;
61
my @packageItems = qw( PV_ID RTAG_ID NAME VERSION PKG_ID PROJ_ID RNINFO);
62
my %rmConfig;
63
 
64
#-------------------------------------------------------------------------------
65
# Function        : Main Entry
66
#
67
# Description     :
68
#
69
# Inputs          :
70
#
71
# Returns         :
72
#
73
my $result = GetOptions (
74
                'help+'         => \$opt_help,          # flag, multiple use allowed
75
                'manual:3'      => \$opt_help,          # flag
76
                'verbose:+'     => \$opt_verbose,       # flag
77
                'age:i'         => \$opt_age,           # Number
78
                'keeptemp!'     => \$opt_keepTemp,      # flag
79
                'status+'       => \$opt_status,        # flag
80
                'pvid:i'        => \$opt_pvid,          # Number
81
                );
82
 
83
#
84
#   Process help and manual options
85
#
86
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
87
pod2usage(-verbose => 1)  if ($opt_help == 2);
88
pod2usage(-verbose => 2)  if ($opt_help > 2);
89
 
90
ErrorConfig( 'name'    =>'RelNotes', 
91
             'verbose' => $opt_verbose );
92
$opt_verbose-- if ($opt_verbose > 0);
93
#
94
#   Sanity Test
95
#
96
Error("Not running on a Unix System") unless ($ENV{GBE_UNIX});
97
Error("Sudo Utils not found: $sudoUtilsDir") unless ( -d $sudoUtilsDir);
98
Warning("Not running as a sutable user" ) unless ($ENV{USER} eq 'buildadm' || $ENV{USER} eq 'releasem');
99
EnvImport ('GBE_PERL');
100
 
101
#
102
#   Ensure only one instance is running
103
#   PerlMonks say to use $0 as the lock file, but that did not work.
104
#   Perhaps the file was open in an editor
105
#   Solution: Create my own file
106
#
107
open( FW, '>',$lockFile);
108
print FW '';
109
close FW;
110
 
111
open (my $self, '<', $lockFile) || Error("Couldn't open self: $!");
112
flock ($self, (LOCK_EX | LOCK_NB)) || Error("This script is already running");
113
 
114
#
115
#   Init parameters
116
#
117
$tempdir = tempdir('/tmp/JATSRN_XXXXXX',CLEANUP => !$opt_keepTemp);
118
Warning("Need to remove tempdir: " . DisplayPath($tempdir)) if $opt_keepTemp;
119
Verbose("Tempdir:" , DisplayPath($tempdir));
120
Verbose("scriptDir:" , DisplayPath($scriptDir));
121
 
122
#   Force GBE_ABT. Currently the Release Manager proxy password only works
123
#   When used in this mode
124
$ENV{GBE_ABT} = 1 unless defined $ENV{GBE_ABT};
125
 
126
#
127
#   User RW password, if provided
128
#
129
$ENV{GBE_RM_USERNAME} = $ENV{GBE_RM_USERNAME_RW} if (exists $ENV{GBE_RM_USERNAME_RW});
130
$ENV{GBE_RM_PASSWORD} = $ENV{GBE_RM_PASSWORD_RW} if (exists $ENV{GBE_RM_PASSWORD_RW});
131
 
132
if ($ENV{GBE_ABT} && $ENV{GBE_RM_USERNAME} && $ENV{GBE_RM_USERNAME} !~ m~]$~ )
133
{
134
    Verbose("Access RM database as proxy user");
135
    $ENV{GBE_RM_USERNAME} = $ENV{GBE_RM_USERNAME} . '[release_manager]'; 
136
}
137
 
138
#
139
#   Interogate the RM database and locate packages that need to be processed
140
#
141
$opt_pvid ? LocatePackagesByPvid() : LocatePackages();
142
Verbose("Package to process:" . scalar @Packages);
143
#DebugDumpData("Packages", \@Packages);
144
 
145
#
146
#   Process each found entry
147
#
148
foreach my $entry ( @Packages)
149
{
150
    GenerateReleaseNote( $entry);
151
}
152
 
153
unlink $lockFile;
154
exit 0;
155
 
156
#-------------------------------------------------------------------------------
157
# Function        : LocatePackages 
158
#
159
# Description     : Locate packages in need of Release Notes
160
#
4698 dpurdie 161
#                   Note: Exclude manually built packages that do not have a build standard
162
#                         ie:  unit_test_br_st_saftp 1.0.1000.sea
163
#
4625 dpurdie 164
# Inputs          : None
165
#
166
# Returns         : Nothing
167
#                   Populates the @Packages array
168
#
169
sub LocatePackages
170
{
171
 
172
    my $m_sqlstr =
173
            "SELECT * from
174
            (
175
                SELECT pv.pv_id, 
176
                       rc.rtag_id, 
177
                       pkg.pkg_name, 
178
                       pv.pkg_version, 
179
                       pv.pkg_id, 
180
                       rt.proj_id , 
181
                       pv.release_notes_info,
182
                       TRUNC(sysdate - pv.modified_stamp ) AS age , 
183
                       row_number() OVER (PARTITION BY pv.pv_id, pkg.pkg_name, pv.pkg_version ORDER BY rc.rtag_id) rn
184
                FROM release_manager.package_versions pv, 
185
                     release_manager.release_content rc, 
186
                     release_manager.packages pkg, 
187
                     release_manager.release_tags rt
188
                WHERE pv.pv_id = rc.pv_id
189
                AND pkg.pkg_id = pv.pkg_id
190
                AND rc.rtag_id = rt.rtag_id
191
                AND pv.pv_id IN (SELECT pv_id 
192
                                 FROM release_manager.package_versions 
193
                                 WHERE (release_notes_info IS null 
194
                                     OR release_notes_info like 'MSG:%' )
195
                                 AND pv.dlocked = 'Y'
4698 dpurdie 196
                                 AND pv.build_type != 'M'
197
                                 AND pv.BS_ID != 3
4625 dpurdie 198
                                 AND pv.modified_stamp > (sysdate - $opt_age)
199
                                 )
200
            )
201
            where rn = 1";
202
 
203
    populateArrayFromSql('LocatePackages', \@Packages, $m_sqlstr, \@packageItems);
204
#    DebugDumpData("Packages", \@Packages);
205
}
206
 
207
#-------------------------------------------------------------------------------
208
# Function        : LocatePackagesByPvid 
209
#
210
# Description     : Locate one package, as specified by its PVID
211
#                   This mode is only used in testing  
212
#
213
# Inputs          : Global: $opt_pvid 
214
#
215
# Returns         : Populate the @Packages array
216
#
217
sub LocatePackagesByPvid
218
{
219
    #   Extract: PV_ID RTAG_ID NAME VERSION PKG_ID PROJ_ID RNINFO AGE 
220
    my $m_sqlstr = "
221
                SELECT pv.pv_id, 
222
                       rc.rtag_id, 
223
                       pkg.pkg_name, 
224
                       pv.pkg_version, 
225
                       pv.pkg_id, 
226
                       rt.proj_id, 
227
                       pv.release_notes_info
228
                FROM release_manager.package_versions pv, 
229
                     release_manager.release_content rc, 
230
                     release_manager.packages pkg, 
231
                     release_manager.release_tags rt
232
                WHERE pv.pv_id = rc.pv_id
233
                AND pkg.pkg_id = pv.pkg_id
234
                AND rc.rtag_id = rt.rtag_id
235
                AND pv.pv_id = $opt_pvid
236
                ";
237
 
238
    populateArrayFromSql('LocatePackagesByPvid', \@Packages, $m_sqlstr, \@packageItems);
239
    #DebugDumpData("Packages", \@Packages);
240
}
241
 
242
#-------------------------------------------------------------------------------
243
# Function        : GenerateReleaseNote  
244
#
245
# Description     : Generate One Release Note
246
#                   Invoke several JATS utilities to do the hard work
247
#
248
# Inputs          : $entry          - Hash of useful infomation
249
#
250
# Returns         : Nothing
251
#                   Will exit on error
252
#
253
sub GenerateReleaseNote
254
{
255
    my ($entry) = @_;
256
    my $outfile;
257
    my $rv;
258
    my @args;
259
 
260
    #DebugDumpData("Entry", $entry);
261
    Message("-------------------- $entry->{NAME}, $entry->{VERSION}") if $opt_status || $opt_verbose;
262
 
263
    my $pkgBase = catdir($GBE_DPKG, $entry->{NAME}, $entry->{VERSION});
264
    Verbose("Processing: $pkgBase");
265
    unless (-d $pkgBase) {
266
        Warning("Package not in archive: $pkgBase");
267
        return;
268
    }
269
 
270
    #
271
    #   Make the target Package Version Writable and Ensure that the doc directory
272
    #   exists. This is done via a script that is invoked with SUDO, partially to
273
    #   interwork with the existing system  
274
    #
275
    runSudoCommand('make_writable', 'dpkg_archive', $entry->{NAME},$entry->{VERSION});
276
    runSudoCommand('make_docFolder', 'dpkg_archive', $entry->{NAME},$entry->{VERSION}, 'doc');
277
 
278
    #
279
    #   Get the basic data required for the Release Note
280
    #   jats jats_get_releasenote_data.pl -pvid=1002782
281
    #
282
    $outfile = catdir($tempdir, join('_',$entry->{NAME},$entry->{VERSION})) . '.xml';
283
    $rv = localTool('jats_get_releasenote_data', '-verbose', $opt_verbose, '-pvid', $entry->{PV_ID}, '-outfile', $outfile );
284
 
285
    #
286
    #   Generate the actual release note and update the Release Manager
287
    #   jats jats_gen_releasenote.pl -releasenote=mcrdemo_1.2.3157.cr.xml -UpdateRmFiles
288
    unless ($rv)
289
    {
290
        $rv = localTool('jats_gen_releasenote.pl', '-verbose', $opt_verbose, '-UpdateRmFiles', '-releasenote', $outfile);
291
    }
292
 
293
    #
294
    #   Release note complete - or failed
295
    #       Make the target PackageVersion ReadOnly
296
    #       Signal End of Package Processing - which will trigger blat
297
    #
298
    #   Do this even if we have a Release Note Failure
299
    #
300
    runSudoCommand('make_readonly', 'dpkg_archive', $entry->{NAME},$entry->{VERSION});
301
 
302
    #    make_release_changed 
303
    #       archive=archive-path 
4632 dpurdie 304
    #       pkg_name="package-name" 
305
    #       pkg_version="package-version" 
4625 dpurdie 306
    #       rtag_id=release-tag-id 
307
    #       pkg_id=package-id 
308
    #       pv_id=package-version-id 
309
    #       proj_id=project-id 
310
    #       mode_id=change-mode-id (1 pkg added, 2 pkg removed, 3 pkg released)
311
    #
4632 dpurdie 312
    #   Note: The ReleasedPackagereport tool parses the make_released_changed entries
313
    #         It requires quotes on the pkg_name and pkg_version for correct parsing
314
    #
4625 dpurdie 315
    push @args, 'archive=dpkg_archive';
316
    push @args, 'mode_id=3';
4632 dpurdie 317
    push @args, 'pkg_name="'    . $entry->{NAME} . '"';
318
    push @args, 'pkg_version="' . $entry->{VERSION} . '"';
4625 dpurdie 319
    push @args, 'rtag_id='     . $entry->{RTAG_ID};
320
    push @args, 'pkg_id='      . $entry->{PKG_ID};
321
    push @args, 'pv_id='       . $entry->{PV_ID};
322
    push @args, 'proj_id='     . $entry->{PROJ_ID};
323
 
324
    runSudoCommand('make_release_changed', @args);
325
 
326
    #
327
    #   Email interested users
328
    #
329
    notifyInterestedUsers($entry);
330
 
331
    Error ("Did not generate Release Note: $entry->{NAME}, $entry->{VERSION}") if ($rv);
332
}
333
 
334
#-------------------------------------------------------------------------------
335
# Function        : localTool 
336
#
337
# Description     : Run a jats tool from the same directory as this script 
338
#
339
# Inputs          : $name           - Name of the script
340
#                   ...             - Arguments for the command
341
#
342
# Returns         : 
343
#
344
sub localTool
345
{
346
    my $cmd = shift;
347
    $cmd .= '.pl' unless ( $cmd =~ m~\.pl$~i );
348
    $cmd = catdir($scriptDir, $cmd);
349
    Error ("Command not found: $cmd") unless -f $cmd;
350
 
351
    return System ( '--NoShell', $::GBE_PERL, $cmd, @_ );
352
}
353
 
354
 
355
#-------------------------------------------------------------------------------
356
# Function        : notifyInterestedUsers  
357
#
358
# Description     : A user can register interest in a package (name) being built in a 
359
#                   specific Project 
360
#                   Perhaps this should be done by the build tool, but at the moment 
361
#                   this release note generation process is really a part of the build
362
#
363
#                   NOTE: Similar code exists in the RM web server to handle manually
364
#                         released packages.
365
#                   
366
# Inputs          : $entry          - Hash of useful infomation
367
#
368
# Returns         : 
369
#
370
sub notifyInterestedUsers
371
{
372
    my ($entry) = @_;
373
    my @userList;
374
 
375
    #
376
    #   Determine interested users
377
    #
378
    my $m_sqlstr = "SELECT U.user_email, prj.proj_name, rt.rtag_name, pkg.pkg_name, pv.pkg_version ,pv.pv_id, rt.rtag_id
379
        FROM PACKAGE_INTEREST PI, 
380
             PACKAGES PKG, 
381
             PACKAGE_VERSIONS PV, 
382
             USERS U,
383
             RELEASE_TAGS RT, 
384
             PROJECTS PRJ 
385
        WHERE PKG.PKG_ID = PI.PKG_ID 
386
          AND RT.RTAG_ID = $entry->{RTAG_ID}
387
          AND PV.PV_ID = $entry->{PV_ID}
388
          AND PV.PKG_ID = PKG.PKG_ID 
389
          AND PRJ.PROJ_ID = RT.PROJ_ID 
390
          AND PRJ.PROJ_ID = PI.PROJ_ID 
391
          AND U.USER_ID = PI.USER_ID";
392
 
393
    my @items = qw( USER_EMAIL PROJ_NAME RTAG_NAME PKG_NAME PKG_VERSION PV_ID RTAG_ID );
394
 
395
    populateArrayFromSql('notifyInterestedUsers', \@userList, $m_sqlstr, \@items);
396
 
397
    #
398
    #   Do we have something to do
399
    #
400
    return unless (@userList);
401
    #DebugDumpData("userList", \@userList);
402
 
403
    #   Ensure we have basic emailing information
404
    #
405
    getRmConfig();
406
 
407
    #
408
    #   Send Email to all the required users
409
    #   Note: This emailer requires a sendmail utility
410
    #
411
    foreach my $entry ( @userList)
412
    {
413
        #$entry->{USER_EMAIL} = 'dpurdie@vixtechnology.com';
414
        #Debug0("Sending email to David Purdie indead of real user");
415
 
4698 dpurdie 416
        my $rnUrl = $GBE_RM_URL . "/fixed_issues.asp?pv_id=$entry->{PV_ID}&rtag_id=$entry->{RTAG_ID}";
4625 dpurdie 417
        my $subject = "Package Release Notification: $entry->{PKG_NAME} $entry->{PKG_VERSION}";
4698 dpurdie 418
        my $content = "Version <a href='$rnUrl'>$entry->{PKG_VERSION}</a> of Package $entry->{PKG_NAME} in Project $entry->{PROJ_NAME} on Release Branch $entry->{RTAG_NAME} has been released.";
419
           $content .= "<p>Package Link: $rnUrl";
4625 dpurdie 420
           $content .= "<p>You have received this email as a result of your interest in this package. If you do not wish to receive further emails then remove your package interest from the notifications area in Release Manager.";
421
 
422
 
423
        my $req = POST( 'mailto:' . $entry->{USER_EMAIL},
424
            From         => $rmConfig{'BUILD FAILURE MAIL SENDER'},
425
            CC           => 'buildadm@vixtechnology.com',
426
            Date         => scalar localtime,
427
            Subject      => $subject,
428
            Content_Type => qq(text/html),
429
            Content      => $content,
430
        );
431
 
432
        my $response = LWP::UserAgent->new->request($req);
433
        if ($response->code != 202)
434
        {
435
            Warning("Email Send Error: $response->code");
436
            #DebugDumpData("Response", \$response);
437
        }
438
    }
439
}
440
 
441
 
442
#-------------------------------------------------------------------------------
443
# Function        : getRmConfig 
444
#
445
# Description     : Get Basic config from Release Manager
446
#                   Only do it once
447
#
448
#                   Just need:
449
#                       'BUILD FAILURE MAIL SENDER'
450
#                       'MAIL SERVER'
451
#
452
# Inputs          : None
453
#
454
# Returns         : Populates a global hash
455
#
456
sub getRmConfig
457
{
458
    return if keys(%rmConfig) > 0;
459
    my $m_sqlstr = "SELECT * from BUILD_SERVICE_CONFIG";
460
 
461
    performSqlQueryCallback('getRmConfig', 
462
                            $m_sqlstr, 
463
                            sub { 
464
                                my ($pRow) = @_;
465
                                $rmConfig{ $pRow->[0] } = $pRow->[1];
466
                                }
467
                            );
468
#DebugDumpData("rmConfig", \%rmConfig);
469
}
470
 
471
 
472
#-------------------------------------------------------------------------------
473
# Function        : runSudoCommand 
474
#
475
# Description     : Run a Unix command as root via the sodo system
476
#                   Requires that target commands be available
477
#                   Requires sudo to be configured to allow this user to run them
478
#
479
# Notes           : The sudoers file on the archive server needs to be configured to allow:
480
#                       This user to run programs from /home/releasem/sbin without a password
481
#                       The users sudo credentials must not timeout (or be used)
482
#
483
# Inputs          : prog            - Command to run
484
#                   arguments       - Command arguments
485
#
486
# Returns         : Nothing 
487
#
488
sub runSudoCommand
489
{
490
    my ($prog, @arguments) = @_;
491
    my $cmd;
492
    my $rv;
493
 
494
    #
495
    #   Construct command
496
    #
497
    $cmd = catdir($sudoUtilsDir, $prog);
498
    $rv = System('--NoShell','sudo','-n', $cmd, @arguments);
499
    Warning("SudoCmd Result: $prog: $rv") if ($rv);
500
}
501
 
502
#-------------------------------------------------------------------------------
503
# Function        : performSqlQueryCallback 
504
#
505
# Description     : Perform a general Sql query and invoke a user function for
506
#                   each row of results
507
#
508
# Inputs          : $fname                  - Name of query for error reporting
509
#                   $m_sqlstr               - Query string
510
#                   $f_process              - Function called for each row in the result
511
#                                             Use closure to have callback modify other data
512
#
513
# Returns         : Number of rows found
514
#
515
sub performSqlQueryCallback
516
{
517
    my ($fname, $m_sqlstr, $f_process ) = @_;
518
    my $found = 0;
519
 
520
    #
521
    #   Connect to the database - once
522
    #
523
    connectRM(\$RM_DB, $opt_verbose) unless $RM_DB;
524
 
525
    $m_sqlstr =~ s~\s+~ ~g;
526
    Verbose3("SQL:", $m_sqlstr);
527
    my $sth = $RM_DB->prepare($m_sqlstr);
528
    if ( defined($sth) )
529
    {
530
        if ( $sth->execute( ) )
531
        {
532
            if ( $sth->rows )
533
            {
534
                while ( my @row = $sth->fetchrow_array )
535
                {
536
                    $found++;
537
                    &$f_process(\@row);
538
                }
539
            }
540
            $sth->finish();
541
        }
542
        else
543
        {
544
            Error("$fname:Execute failure: $m_sqlstr", $sth->errstr() );
545
        }
546
    }
547
    else
548
    {
549
        Error("$fname:Prepare failure" );
550
    }
551
 
552
    unless ( $found )
553
    {
554
        Verbose("$fname:No data found");
555
    }
556
    return $found;
557
}
558
 
559
#-------------------------------------------------------------------------------
560
# Function        : populateArrayFromSql 
561
#
562
# Description     : Issue an SQL query and push the results into an array of hashes
563
#                   where each row from the query is a hash and the entire result is an 
564
#                   array 
565
#
566
# Inputs          :     name                - For error reporting
567
#                       pArray              - Ref to the output array
568
#                       sql                 - Sql to process
569
#                       pItems              - Array of tems to extract
570
#                                             Must match the SQL SELECT arguments
571
#                                             Item names starting with '-' do not end up in the
572
#                                             generated XML
573
# Returns         : 
574
#
575
sub populateArrayFromSql
576
{
577
    my ($fname, $pArray, $m_sqlstr, $pItems) = @_;
578
 
579
    performSqlQueryCallback($fname, 
580
                            $m_sqlstr, 
581
                            sub { 
582
                                my ($pRow) = @_;
583
                                my %entry;
584
                                push @{$pArray}, populateHash( \%entry, $pRow, $pItems);
585
                                }
586
                            );
587
#DebugDumpData("populateArrayFromSql", $pArray);
588
}
589
 
590
#-------------------------------------------------------------------------------
591
# Function        : populateHash 
592
#
593
# Description     : Put an array of data items into a hash
594
#
595
# Inputs          : pHash           - ref to output hash
596
#                   pRow            - Ref to the row data 
597
#                   pItems          - Ref to an hash array of entry names
598
#
599
# Returns         : pHash
600
#
601
sub populateHash
602
{
603
    my ($pHash, $pRow, $pItems) = @_;
604
 
605
    foreach my $item ( @{$pItems} ) {
606
        my $data = shift @{$pRow};
607
 
608
        if (defined $data)
609
        {
610
            $data =~ s~^\s+~~;
611
            $data =~ s~\s+$~~;
612
 
613
            #
614
            #   Store in hash
615
            #
616
            $pHash->{$item} = $data;
617
        }
618
    }
619
    return $pHash;
620
}
621
 
622
#-------------------------------------------------------------------------------
623
#   Documentation
624
#
625
 
626
=pod
627
 
628
=for htmltoc    SYSUTIL::
629
 
630
=head1 NAME
631
 
632
process_release_notes - Create Release Notes for newly created packages
633
 
634
=head1 SYNOPSIS
635
 
636
 jats process_release_notes [options]
637
 
638
 Options:
639
    -help              - Brief help message
640
    -help -help        - Detailed help message
641
    -man               - Full documentation
642
    -verbose           - Display additional progress messages
643
    -pvid=nn           - PVID of package to process(test mode)
644
    -age=nn            - Examine packages created in last n days
645
    -keeptemp          - Keep the temp workspace
646
    -status            - Display status
647
 
648
=head1 OPTIONS
649
 
650
=over 8
651
 
652
=item B<-help>
653
 
654
Print a brief help message and exits.
655
 
656
=item B<-help -help>
657
 
658
Print a detailed help message with an explanation for each option.
659
 
660
=item B<-man>
661
 
662
Prints the manual page and exits.
663
 
664
=item B<-pvid=nn>
665
 
666
This option bypasses the normal mechanism of determining packages to be processed and 
667
will process just the specified package. This is normally only used to test the operation 
668
of the subsystem.
669
 
670
=item B<-age=nn>
671
 
672
This option control the period of time period used in determing which packages to process. 
673
 
674
The number is in days. The default value is 2 days.
675
 
676
=item B<-keeptemp>
677
 
678
If this option is specified, then the temporary directory created in the processing will be 
679
retained. The user is responsible for deleting the directory.
680
 
681
This option is normally only used in testing.
682
 
683
=item B<-status>
684
 
685
When set, this option will cause the program to display the package name and version of each
686
package being processed.
687
 
688
=back
689
 
690
=head1 DESCRIPTION
691
 
692
This utility program is apart of the Package Release process. It is an interim solution.
693
 
694
The script is designed to be run as a cron jon on the dpkg_archive server.
695
 
696
It will scan the Release Manager database for packages that have been release, but do 
697
not yet have release notes. For each package it will then generate a Release Note by: 
698
 
699
=over 4
700
 
701
=item *
702
 
703
Invoke jats_get_releasenote_data to:
704
 
705
Extract relevent information from
706
 
707
=over 4
708
 
709
=item *
710
 
711
The Release Manager database
712
 
713
=item *
714
 
715
the ClearQuest database (now conatined within the Release Manager database)
716
 
717
=item *
718
 
719
the Jira Issue server 
720
 
721
=back
722
 
723
and create and XML file.
724
 
725
=item *
726
 
727
Invoke jats_gen_releasenote to:
728
 
729
=over 4
730
 
731
=item *
732
 
733
Process the the XML file created above, and package list info found within the new package. 
734
 
735
If no package informationis found then the utility will create a package list, but this is 
736
much slower than having it created by the package builder.
737
 
738
=item *
739
 
740
Create an XML file containing all the package information
741
 
742
=item *
743
 
744
Create an HTML based Release Note, from the XML file. This file could also be used to create a Release note in another format if required. 
745
 
746
=item *
747
 
748
Transfer these two files into the package in dpkg_archive
749
 
750
=item *
751
 
752
Insert the packages file list into the Release Manager database.
753
 
754
=back
755
 
756
=item *
757
 
758
Make the package read-only. This will trigger any post-install processing of the 
759
package. This is only required for packages that form a part of the build system.
760
 
761
=item *
762
 
763
Flag that the package has been released. This may tigger the BLAT package file transfer process 
764
and the package will be transferred to remote sites.
765
 
766
=item *
767
 
768
Determine the users that have registered interest in being informed when the package is released. 
769
It will then email these users.
770
 
771
=back
772
 
773
=head1 EXAMPLE
774
 
775
=head2 process_release_notes
776
 
777
This will perform a single scan of the Release Manager database and generate Release Notes as required.
778
 
779
=cut
780