Subversion Repositories DevTools

Rev

Rev 6116 | Rev 6391 | 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   : jats_gen_releasenote.pl
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : Generate the package Release Note
10
#                 Requires
11
#                   1) Release Note data generated by jats_get_releasenote_data.pl
12
#                   2) Target package in dpkg_archive
13
#                   3) One or more built.files.xxx.xml (optional, but desirable)
14
#
15
#                 Will:
16
#                   Merge built.files.xxx.xml files into the release note data
17
#                   Insert build meta data
18
#                   Save the Release Note MetaData within the package
19
#                   Generate the HTML release note - save within the package
20
#                   Insert Release_Contents into RM Database
21
#
22
# Usage:        See POD
23
#
24
#......................................................................#
25
 
26
require 5.008_002;
27
use strict;
28
use warnings;
29
 
30
use Pod::Usage;
31
use Getopt::Long;
32
use XML::Simple;
33
use File::Path;
34
use File::Copy;
6383 dpurdie 35
use XML::LibXML;
4625 dpurdie 36
use Digest::MD5;
37
use File::Find;
38
use FindBin;                                # Determine the current directory
4697 dpurdie 39
use Encode qw(decode encode);
4625 dpurdie 40
 
41
use JatsError;
42
use JatsSystem;
43
use Getopt::Long;
44
use Pod::Usage;
45
use FileUtils;
46
use JatsEnv;
47
use JatsRmApi;
48
 
49
use DBI;
50
 
51
my $VERSION = "1.0.0";                                      # Update this. Inserted into meta data field
52
 
53
# User options
54
my $opt_verbose = 0;
55
my $opt_help = 0;
56
my $opt_archive;
57
my $archive_tag;
58
my $opt_pname;
59
my $opt_pversion;
60
my $opt_release_note;
61
my $opt_pvid;
62
my $opt_outname;
63
my $opt_outputXml;
64
my $opt_updateRmFiles;
65
my $opt_workingDir;
66
 
67
#   Global vars
68
our $GBE_HOSTNAME;
69
my $DPKG_ROOT;
70
my $DPKG_DOC;
71
my $JATS_RN;
72
my $OUT_ROOT;
73
 
74
 
75
#
76
#   Structure to translate -archive=xxx option to archive variable
77
#   These are the various dpkg_archives known to JATS
78
#
79
my %Archive2Var =( 'main'       =>  'GBE_DPKG',
80
                   'store'      =>  'GBE_DPKG_STORE',
81
                   'cache'      =>  'GBE_DPKG_CACHE',
82
                   'local'      =>  'GBE_DPKG_LOCAL',
83
                   'sandbox'    =>  'GBE_DPKG_SBOX',
84
                   'deploy'     =>  'GBE_DPLY',
85
                   );
86
 
87
#-------------------------------------------------------------------------------
88
# Function        : Main Entry
89
#
90
# Description     :
91
#
92
# Inputs          :
93
#
94
# Returns         :
95
#
96
{
97
    my $result = GetOptions (
98
                    "help+"         => \$opt_help,              # flag, multiple use allowed
99
                    "manual:3"      => \$opt_help,              # flag, set value
100
                    "verbose:+"     => \$opt_verbose,           # flag, increment
101
                    "archive=s"     => \$opt_archive,           # string
102
                    "releasenote=s" => \$opt_release_note,      # string
103
                    "UpdateRmFiles" => \$opt_updateRmFiles,     # flag
104
                    "WorkDir=s"     => \$opt_workingDir,        # String
105
                    );
106
 
107
    #
108
    #   Process help and manual options
109
    #
110
    pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
111
    pod2usage(-verbose => 1)  if ($opt_help == 2 );
112
    pod2usage(-verbose => 2)  if ($opt_help > 2);
113
 
114
    ErrorConfig( 'name'    =>'GenRn', 'verbose' => $opt_verbose );
115
    InitFileUtils();
116
 
117
    #
118
    #   Needed EnvVars
119
    #
120
    EnvImport ('GBE_HOSTNAME');
121
    $JATS_RN = $FindBin::Bin;
122
    Error("Release Note tools not found", $JATS_RN)
123
        unless (-d $JATS_RN);
124
 
125
 
126
    #
127
    #   Sanity Check
128
    #
129
    Error("Release Note data not provided") unless $opt_release_note;
130
    Error("Release Note data not found") unless -f $opt_release_note;
131
    if (defined $opt_workingDir)
132
    {
133
        $opt_workingDir = FullPath($opt_workingDir);
134
        Error("Working directory is not a directory") unless -d $opt_workingDir;
135
        Error("Working directory is writable") unless -w $opt_workingDir;
136
    }
137
 
138
    #
139
    #   Determine the target archive
140
    #   The default archive is GBE_DPKG, but this may be changed
141
    #
142
    $opt_archive = 'main' unless ( $opt_archive );
143
    my $archive_tag = $Archive2Var{$opt_archive};
144
    Error("Unknown archive specified: $opt_archive")
145
        unless ( $archive_tag );
146
    $DPKG_ROOT = $ENV{$archive_tag} || '';
147
    Verbose ("Archive Variable: $archive_tag" );
148
    Verbose2 ("Archive Path: $DPKG_ROOT" );
149
 
150
    #
151
    #   Process the release note and extract essential information
152
    #
153
    processReleaseNote();
154
 
155
    #
156
    #   Locate the target package
157
    #
158
    $DPKG_ROOT = catdir($DPKG_ROOT, $opt_pname, $opt_pversion);
159
    Verbose ("Package Path: ", DisplayPath($DPKG_ROOT) );
160
    Error ("Package not found in archive", $DPKG_ROOT) unless -d $DPKG_ROOT;
161
 
162
    #   OUT_ROOT is really only used for testing
163
    #   Needs to mimic $DPKG_ROOT
164
    $OUT_ROOT = defined($opt_workingDir) ? $opt_workingDir : $DPKG_ROOT; 
165
    Verbose2 ("Output Path: $OUT_ROOT" );
166
 
167
    #
168
    #   Calculate output filenames
169
    #   Html Release Note:
170
    #       RELEASE_NOTES_PVID_PKGNAME_CLEANV.html
171
    #
172
    $DPKG_DOC = catdir($OUT_ROOT, 'doc');
173
    $opt_outputXml = catdir($DPKG_DOC, 'release_note.xml');
174
 
175
    my $cleanv = $opt_pversion;
176
    $cleanv =~ s~\.~_~g;
177
    $opt_outname = join('_',
178
                        'RELEASE_NOTES',
179
                        $opt_pvid,
180
                        $opt_pname,
181
                        $cleanv,    
182
                        ) . '.html';
183
    Verbose("Note Name: $opt_outname");
184
 
185
    #
186
    #   Locate the release note data file
187
    #   This was created as a prerequisite to the build
188
    #   Note: windows requires '/' in the file list
189
    #
190
    my @filesList;
191
    foreach my $item ( glob(catdir($DPKG_ROOT, 'built.files.*.xml'))) {
192
        $item =~ s~\\~/~g;
193
        push @filesList, $item;
194
    }
195
    unless (scalar @filesList > 0)
196
    {
4697 dpurdie 197
        Warning("No file list found within the package: $opt_pname/$opt_pversion");
4625 dpurdie 198
        #
199
        #   No filelist found in the package
200
        #   This may occur for packages that did not go though the build system
201
        #   Create a package-list
202
        #
203
        my $item = generateFileList();
204
        $item =~ s~\\~/~g;
205
        push @filesList, $item;
206
    }
207
 
208
    #
209
    #   Create output directory within the package
210
    #
211
    mkpath($DPKG_DOC, 0, 0775);
212
 
213
    #
214
    #   Merge the Release Note and the various file lists into a single
215
    #   XML file. Keep the file local
216
    #
217
    System('--NoShell', '--Exit', 'java', '-jar', 
218
           catdir($JATS_RN, 'saxon9he.jar'), 
219
           '-xsl:' . catdir($JATS_RN, 'merge.xslt'),
220
           "-s:$opt_release_note",
221
           'fileList=' . join(',', @filesList),
222
           '-o:' . 'built.files.releasenote.xml'
223
            );
224
 
225
    #
226
    #   Generate the HTML Release Note
227
    #   Output directly to the body of the package
228
    #
229
    System('--NoShell', '--Exit', 'java', '-jar', 
230
           catdir($JATS_RN, 'saxon9he.jar'), 
231
           '-xsl:' . catdir($JATS_RN, 'releaseNote2html.xslt'),
232
           '-s:' . 'built.files.releasenote.xml',
233
           "-o:" . catdir($DPKG_DOC, $opt_outname)
234
            );
235
 
236
    #
237
    #   Transfer the XML database directly into the package
238
    #
239
    unless( File::Copy::copy('built.files.releasenote.xml', $opt_outputXml) )
240
    {
241
        Error("Cannot transfer XML release note", $!, $opt_outputXml);
242
    }
243
 
244
    #
245
    #   Delete the built.files.xxx.xml that may be present in the root of the package
246
    #   These are no longer needed - they have been incorporated into the release_note.xml file
247
    #
248
    foreach my $item ( glob(catdir($DPKG_ROOT, 'built.files.*.xml'))) {
249
        unlink $item;
250
    }
251
 
252
    #
253
    #   Update the Release Manager entry - File Data
254
    #
255
    if ($opt_updateRmFiles)
256
    {
257
        updateRmFiles();
258
        updateRmNoteInfo();
259
    }
260
 
261
    #
262
    #   All done
263
    #
264
    Verbose ("Release Note:", DisplayPath(catdir($DPKG_DOC, $opt_outname)));
265
    exit 0;
266
}
267
 
268
#-------------------------------------------------------------------------------
269
# Function        : processReleaseNote 
270
#
271
# Description     : Extract essential information from the Release Note Data
272
#
273
# Inputs          : 
274
#
275
# Returns         : Populates global variables 
276
#
277
sub processReleaseNote
278
{
279
 
6383 dpurdie 280
    #
281
    #   Extract essential information
282
    #   
283
    my $xml;
284
    my $parser = XML::LibXML->new();
285
    my $doc    = $parser->parse_file($opt_release_note);
4625 dpurdie 286
 
6383 dpurdie 287
    #
288
    #   Extract the 'package' data
289
    #   Only expect one of them
290
    #   
291
    my @nodes = $doc->findnodes('/package_data/package');
292
    my $node = $nodes[0];
293
    Error ("Package section not found in $opt_release_note") unless defined $node;
294
 
295
    $opt_pname    = $node->getAttribute( 'name' );
296
    $opt_pversion = $node->getAttribute( 'version' );
297
    $opt_pvid     = $node->getAttribute( 'pvid' );
4625 dpurdie 298
 
299
    Verbose("Package Name: $opt_pname") ;
300
    Verbose("Package Version: $opt_pversion") ;
301
    Verbose("Package Pvid: $opt_pvid") ;
302
}
303
 
304
#-------------------------------------------------------------------------------
305
# Function        : generateFileList
306
#                   generateFileListProc 
307
#
308
# Description     : A fileList has not been found in the target package
309
#                   Perhaps the package was not created by the build system
310
#                   
311
#                   Generate a fileList        
312
#
313
# Inputs          : None
314
#
315
# Returns         : Path to the generated file list
316
#
317
my @generateFileListData;
318
my $baseLength;
319
sub generateFileList
320
{
321
    my $outXmlFile;
322
    Verbose("Generate internal filelist - none found in package");
323
 
324
    #
325
    #   Scan the package and process each file
326
    #
327
    $baseLength = length($DPKG_ROOT);
328
    File::Find::find( \&generateFileListProc, $DPKG_ROOT );
329
 
330
    #
331
    #   Write out XML of the Generated file list
332
    #
333
    my $data;
334
    $data->{file} = \@generateFileListData;
335
 
336
    #
337
    #   Write out sections of XML
338
    #       Want control over the output order
339
    #       Use lots of attributes and only elements for arrays
340
    #       Save as one attribute per line - for readability
341
    #
342
    $outXmlFile = catdir($OUT_ROOT,"built.files.$GBE_HOSTNAME.xml");
343
 
344
    Verbose2('Meta File', $outXmlFile);
345
    my $xs = XML::Simple->new( NoAttr =>0, AttrIndent => 1 );
346
 
347
    open (my $XML, '>', $outXmlFile) || Error ("Cannot create output file: $outXmlFile", $!);
348
    $xs->XMLout($data, 
349
                'RootName' => 'files', 
350
                'XMLDecl'  => '<?xml version="1.0" encoding="UTF-8"?>',
351
                'OutputFile' => $XML);
352
    close $XML;
353
 
354
    return $outXmlFile;
355
}
356
 
357
sub generateFileListProc
358
{
359
    my %data;
360
    my $md5sum;
361
    my $source = $File::Find::name;
362
    my $type = 'dir';
363
 
364
    my $target = substr($source, $baseLength);
365
    $target =~ s~^/~~;
366
    $target =~ s~/$~~;
367
    Verbose2("GenFileList: $source, $target");
368
    return if (length ($target) == 0);
369
 
370
    if (-l $source)
371
    {
372
        $type = 'link';
373
    }
374
    elsif ( -f $source)
375
    {
376
        $type = 'file';
377
        Verbose2("Calculate MD5 Digest: $source");
378
        open(my $fh , $source) or Error ("Can't open '$source': $!");
379
        binmode $fh, ':crlf';
380
        $md5sum = Digest::MD5->new->addfile($fh)->hexdigest;
381
        close $fh;
382
    }
383
 
4697 dpurdie 384
    #
385
    #   Convert from iso-8859-1 into utf-8
386
    #
387
    $target = decode( 'iso-8859-1', $target );
388
    $target = encode( 'utf-8', $target );
4625 dpurdie 389
 
390
    if (-d $source)
391
    {
392
        $data{path} = $target;
393
    }
394
    else
395
    {
396
        $data{path} = StripFileExt($target);
397
        $data{name} = StripDir($target);
398
        if (defined $md5sum)
399
        {
400
            $data{size} = (stat($source))[7];
401
            $data{md5sum} = $md5sum;
402
        }
403
    }
404
 
405
    $data{fullname} = $target;
406
    $data{type} = $type;
407
    $data{machtype} = 'unknown';
408
    $data{host} = $GBE_HOSTNAME;
409
 
410
    # Put a nice '/' on the end of the patch elements
411
    $data{path} .= '/'
412
        if ( exists ($data{path}) && length($data{path}) > 0);
413
 
414
    push @generateFileListData, \%data;
415
}
416
 
417
#-------------------------------------------------------------------------------
418
# Function        : updateRmFiles 
419
#
420
# Description     : 
421
#
422
# Inputs          : 
423
#
424
# Returns         : 
425
#
426
my $RM_DB;
427
my  $updateRmFilesData;
428
sub updateRmFiles
429
{
430
    my $eCount = 0;
431
    #
432
    #   If in use the the autobuilder - which it should be, then
433
    #   modify the user name to access RM with a proxy user. This is the
434
    #   same method used in the 'buildtool'
435
    #
436
    if ($ENV{GBE_ABT} && $ENV{GBE_RM_USERNAME} && $ENV{GBE_RM_USERNAME} !~ m~]$~ )
437
    {
438
        Verbose("Access RM database as proxy user");
439
        $ENV{GBE_RM_USERNAME} = $ENV{GBE_RM_USERNAME} . '[release_manager]'; 
440
    }
441
 
442
    #
443
    #   Read in the release note data base
444
    #
445
    my $rnDataBase = catdir($DPKG_DOC, 'release_note.xml');
446
    if (! -f $rnDataBase )
447
    {
448
        Error("Release Note XML database not found: $!", $rnDataBase);
449
    }
450
 
451
    #
6383 dpurdie 452
    #   Extract essential information
453
    #   Don't use a simple parser - its gets it wrong
454
    #   
455
    my $xml;
456
    my $parser = XML::LibXML->new();
457
    my $doc    = $parser->parse_file($rnDataBase);
458
 
459
    #
460
    #   Extract the 'package' data
461
    #   Only expect one of them
462
 
463
    my @nodes = $doc->findnodes('/package_data/package');
464
    my $node = $nodes[0];
465
    Error ("Package section not found in $rnDataBase") unless defined $node;
466
 
467
    my %eldata;
468
    foreach my $atr ($node->findnodes( "./@*")) {     
469
        Debug("Package Data:" .  $atr->nodeName() . ":" . $atr->value);
470
        $xml->{package}{$atr->nodeName} = $atr->value;
471
    }
472
 
473
    #
474
    #   Extract the file data
475
    #   Tricky - needs to be an array
476
    #
477
    foreach my $element ($doc->findnodes('/package_data/files/file')) {
478
       my %eldata;
479
       foreach my $node ($element->findnodes( "./@*")) {     
480
           Debug("File:" .  $node->nodeName() . ":" . $node->value);
481
           $eldata{$node->nodeName} = $node->value;
482
       }
483
       push @{$xml->{file}}, \%eldata;
484
    }
485
    #DebugDumpData("XML DATA", $xml);
486
 
487
    #
4625 dpurdie 488
    #   Sanity Test the data
489
    #
490
    Error("Sanity Check Failure. PVID") unless($opt_pvid eq $xml->{package}{pvid});
491
    Error("Sanity Check Failure. Name") unless($opt_pname eq $xml->{package}{name});
492
    Error("Sanity Check Failure. Version") unless($opt_pversion eq $xml->{package}{version});
6383 dpurdie 493
    Error("Sanity Check Failure. File Section") unless(exists $xml->{file});
4625 dpurdie 494
 
495
    #
496
    #   Delete any existing entry(s)
497
    #
498
    updateRmFilesDelete();
499
 
500
    #
501
    #   Release Manager Database will barf if there are duplicate entries
502
    #   Maintain a hash of items processed, and only process each once
503
    #
504
    my %fullNameSeen;
505
 
6383 dpurdie 506
    $updateRmFilesData = "";
507
    foreach my $entry (@{$xml->{file}})
4625 dpurdie 508
    {
509
        #
510
        #   Ignore 'merge' entries
511
        #
512
        next if ((exists $entry->{type}) && ($entry->{type} eq 'merge'));
513
        #
514
        #   Clean up the data
515
        #
516
        my $fname = $entry->{name} || '';
517
        my $fpath  = $entry->{path} || '';
518
        my $fsize  = $entry->{size} || 0;
519
        my $fmd5  = $entry->{md5sum} || '';
520
        $fpath =~ s~/$~~ unless $fname;
521
 
522
        unless( $fullNameSeen{$fpath}{$fname} )
523
        {
524
            $fullNameSeen{$fpath}{$fname} = 1;
525
 
526
            #
527
            #   Create SQL fragment for the insert
528
            #
529
            $eCount++;
6116 dpurdie 530
            my $quoteFname = $fname;
531
            $quoteFname =~ s~'~''~g;
4625 dpurdie 532
            my $entry = " INTO release_manager.release_components ( pv_id, file_name, file_path, byte_size, crc_cksum, crc_modcrc ) " .
6116 dpurdie 533
                        " VALUES ( $opt_pvid, '$quoteFname', '$fpath',$fsize , '$fmd5', '')";
4625 dpurdie 534
            $updateRmFilesData .= $entry;
535
 
536
            # The size of the aggregation is key to performance
537
            # Too big is as bad as too small
538
            if (length($updateRmFilesData) > 10000)
539
            {
540
                updateRmFilesInsert();
541
            }
542
        }
543
        else
544
        {
545
            Warning("Multiple file entries for: $fpath $fname");
546
        }
547
    }
548
    updateRmFilesInsert();
549
    Verbose ("Inserted $eCount entries into Release_Components");
550
}
551
 
552
#-------------------------------------------------------------------------------
553
# Function        : updateRmFilesInsert 
554
#
555
# Description     : Insert entries using the partial SQL statement 
556
#                   Must be called when the partial SQL buffer get large
557
#                   as well as at the end to fluch any outstanding inserts
558
#
559
# Inputs          : 
560
#
561
# Returns         : 
562
#
563
sub updateRmFilesInsert
564
{
565
    if (length($updateRmFilesData) > 0)
566
    {
567
        executeRmQuery(
568
            'updateRmFilesInsert',
6116 dpurdie 569
            'INSERT ALL' . $updateRmFilesData . ' SELECT 1 FROM DUAL'
4625 dpurdie 570
            );
571
 
572
        $updateRmFilesData = ""; 
573
    }
574
}
575
#-------------------------------------------------------------------------------
576
# Function        : updateRmFilesDelete 
577
#
578
# Description     : Delete ALL entires in the 'release_components' table associated
579
#                   with the current pvid
580
#                   
581
#                   Needs to be done before new entries are added.    
582
#
583
# Inputs          : 
584
#
585
# Returns         : 
586
#
587
sub updateRmFilesDelete
588
{
589
    executeRmQuery(
590
        'updateRmFilesDelete',
591
        'delete from release_manager.release_components where pv_id=' . $opt_pvid
592
        );
593
}
594
 
595
#-------------------------------------------------------------------------------
596
# Function        : updateRmNoteInfo 
597
#
598
# Description     : Insert Release Note Info into the Release Manager Database
599
#                   This has the side effect that RM will see the Release Note
600
#                   as being fully generated.
601
#
602
# Inputs          : 
603
#
604
# Returns         : 
605
#
606
sub updateRmNoteInfo
607
{
608
    #
609
    #   Determine the path to the Release Note in a form that is suitable for the Release Manager
610
    #   Database. This expects: /dpkg_archive/PkgName/PkgVer/doc/pkgFileName
611
    #
612
    my $rnPath = join('/', '', 'dpkg_archive', $opt_pname, $opt_pversion, 'doc', $opt_outname);
613
    Verbose("RN_INFO:", $rnPath);
614
 
615
    # Into the database
616
    executeRmQuery (
617
        'updateRmNoteInfo', 
618
        'update release_manager.package_versions set release_notes_info=\'' . $rnPath . '\' where pv_id=' . $opt_pvid
619
        );
620
}
621
 
622
#-------------------------------------------------------------------------------
623
# Function        : executeRmQuery 
624
#
625
# Description     : Execute a simple RM query. One that does not expect any return data
626
#
627
# Inputs          : $fname           - OprName, for error reporting
628
#                   $m_sqlstr        - SQL String
629
#
630
# Returns         : Will exit on error
631
#
632
sub executeRmQuery
633
{
634
    my ($fname, $m_sqlstr) = @_;
635
 
636
    #
637
    #   Connect to the Database - once
638
    #
639
    connectRM(\$RM_DB, 0) unless $RM_DB;
640
 
641
    Verbose2('ExecuteQuery:', $fname);
642
    #
643
    #   Create the full SQL statement
644
    #
645
    my $sth = $RM_DB->prepare($m_sqlstr);
646
    if ( defined($sth) )
647
    {
648
        if ( $sth->execute() )
649
        {
650
            $sth->finish();
651
        }
652
        else
653
        {
654
            Error("$fname: Execute failure: $m_sqlstr", $sth->errstr() );
655
        }
656
    }
657
    else
658
    {
659
        Error("$fname: Prepare failure");
660
    }
661
}
662
 
663
 
664
#-------------------------------------------------------------------------------
665
#   Documentation
666
#
667
 
668
=pod
669
 
670
=for htmltoc    SYSUTIL::
671
 
672
=head1 NAME
673
 
674
jats_gen_releasenote - Generate a Release Note
675
 
676
=head1 SYNOPSIS
677
 
678
 jats jats_gen_releasenote [options]
679
 
680
 Options:
681
    -help              - Brief help message
682
    -help -help        - Detailed help message
683
    -man               - Full documentation
684
    -verbose           - Display additional progress messages
685
    -outfile=name      - [Optional] Name of the output XML file
686
    -archive=name      - [Optional] Name package archive
687
    -releasenote=path  - Path to the Release Note Data
688
    -UpdateRmFiles     - Update the Files list in Release Manager
689
 
690
 
691
=head1 OPTIONS
692
 
693
=over 8
694
 
695
=item B<-help>
696
 
697
Print a brief help message and exits.
698
 
699
=item B<-help -help>
700
 
701
Print a detailed help message with an explanation for each option.
702
 
703
=item B<-man>
704
 
705
Prints the manual page and exits.
706
 
707
=item B<-pvid=nn>
708
 
709
This option provides identifies the PackageVersion to be processed.
710
 
711
This option is mandatory.
712
 
713
=item B<-outfile=name>
714
 
715
This option specifies the output file name.
716
 
717
If not provided by the user the output filename will be created in the current directory
718
and it will be named after the package name and package version.
719
 
720
If the filename does not end in .xml, then .xml will be appended to the file name.
721
 
722
=item B<-UpdateRmFiles>
723
 
724
This option will case the utility to ppdate the Files list in Release Manager.
725
 
726
The existing file list will be replaced by the one within the package.
727
 
728
Note: Write Access to Release Manager is required.
729
 
730
=back
731
 
732
=head1 DESCRIPTION
733
 
734
This utility program is used to extract sufficient information from Release Manager and other
735
associated databases so that a Release Note can be created.
736
 
737
The extracted data is stored in an XML format. The intent is that XSLT will be used to create
738
an HTML based release note.
739
 
740
 
741
=head1 EXAMPLE
742
 
743
=head2 jats jats_gen_releasenote -releasenote=/tmp/myreleasenote.xml
744
 
745
This will process release note data in the specified XML file.
746
 
747
=cut