| 4625 |
dpurdie |
1 |
########################################################################
|
|
|
2 |
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
|
|
|
3 |
#
|
|
|
4 |
# Module name : jats_get_releasenote_data.pl
|
|
|
5 |
# Module type : Makefile system
|
|
|
6 |
# Compiler(s) : Perl
|
|
|
7 |
# Environment(s): jats
|
|
|
8 |
#
|
|
|
9 |
# Description : Extract Data from RM in order to generate a release note
|
|
|
10 |
# The data is stored in XML
|
|
|
11 |
#
|
|
|
12 |
# Improvements : Catpure non ripple build reason for Release
|
|
|
13 |
# Release ReleaseName
|
|
|
14 |
# Project ProjectName
|
|
|
15 |
# BuildFilters BuildMachines
|
|
|
16 |
# Build Standard
|
|
|
17 |
# Build Environment
|
|
|
18 |
#
|
|
|
19 |
# Get Jira Credentials from DataBase
|
|
|
20 |
#
|
|
|
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 JSON;
|
|
|
34 |
use LWP::UserAgent;
|
|
|
35 |
use MIME::Base64;
|
|
|
36 |
use POSIX qw(strftime);
|
|
|
37 |
use Encode qw(decode encode);
|
|
|
38 |
use Getopt::Long;
|
|
|
39 |
use Pod::Usage;
|
|
|
40 |
|
|
|
41 |
use JatsError;
|
|
|
42 |
use JatsSystem;
|
|
|
43 |
use FileUtils;
|
|
|
44 |
use JatsRmApi;
|
|
|
45 |
use ArrayHashUtils;
|
|
|
46 |
use DBI;
|
|
|
47 |
|
|
|
48 |
my $VERSION = "1.0.0"; # Update this. Inserted into meta data field
|
|
|
49 |
|
|
|
50 |
my $opt_verbose = 0;
|
|
|
51 |
my $opt_help = 0;
|
|
|
52 |
my $opt_pvid;
|
|
|
53 |
my $opt_prev_pvid;
|
|
|
54 |
my $opt_outfile;
|
|
|
55 |
|
|
|
56 |
#
|
|
|
57 |
# Data Items
|
|
|
58 |
#
|
|
|
59 |
my $RM_DB;
|
|
|
60 |
my %pkgData;
|
|
|
61 |
my %pkgPrevData;
|
|
|
62 |
my @dependData;
|
|
|
63 |
my @dependRunData;
|
|
|
64 |
my @unitTestData;
|
|
|
65 |
my @additionalNotesData;
|
|
|
66 |
my @buildDepDiff;
|
|
|
67 |
my @JiraIssues;
|
|
|
68 |
my @JiraIssueList;
|
|
|
69 |
my %ClearQuestIssueData;
|
|
|
70 |
my @ClearQuestIssues;
|
|
|
71 |
my @FileList; # Place Holder
|
|
|
72 |
|
|
|
73 |
#-------------------------------------------------------------------------------
|
|
|
74 |
# Function : Main Entry
|
|
|
75 |
#
|
|
|
76 |
# Description :
|
|
|
77 |
#
|
|
|
78 |
# Inputs :
|
|
|
79 |
#
|
|
|
80 |
# Returns :
|
|
|
81 |
#
|
|
|
82 |
{
|
|
|
83 |
my $result = GetOptions (
|
|
|
84 |
"help+" => \$opt_help, # flag, multiple use allowed
|
|
|
85 |
"manual:3" => \$opt_help,
|
|
|
86 |
"verbose:+" => \$opt_verbose, # flag
|
|
|
87 |
"pvid:n" => \$opt_pvid, # Number
|
|
|
88 |
"outfile:s" => \$opt_outfile, # String
|
|
|
89 |
);
|
|
|
90 |
|
|
|
91 |
#
|
|
|
92 |
# Process help and manual options
|
|
|
93 |
#
|
|
|
94 |
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
|
|
|
95 |
pod2usage(-verbose => 1) if ($opt_help == 2 );
|
|
|
96 |
pod2usage(-verbose => 2) if ($opt_help > 2);
|
|
|
97 |
|
|
|
98 |
ErrorConfig( 'name' =>'GetRnInfo', 'verbose' => $opt_verbose );
|
|
|
99 |
|
|
|
100 |
#
|
|
|
101 |
# Sanity Check
|
|
|
102 |
#
|
|
|
103 |
Error ("Must provide pvid") unless $opt_pvid;
|
|
|
104 |
Error ("GBE_JIRA_URL is not configured") unless exists ($ENV{GBE_JIRA_URL});
|
|
|
105 |
Error ("GBE_JIRA_USERNAME is not configured") unless exists ($ENV{GBE_JIRA_USERNAME});
|
|
|
106 |
Error ("GBE_JIRA_PASSWORD is not configured") unless exists ($ENV{GBE_JIRA_PASSWORD});
|
|
|
107 |
|
|
|
108 |
#
|
|
|
109 |
# Get Data Item
|
|
|
110 |
#
|
|
|
111 |
GetPkgInfo($opt_pvid, \%pkgData);
|
|
|
112 |
$opt_prev_pvid = $pkgData{prev_pvid} || $pkgData{'-prev_pvid'};
|
|
|
113 |
|
|
|
114 |
#
|
|
|
115 |
# Get Data on immediate Previous version
|
|
|
116 |
#
|
|
|
117 |
if ($opt_prev_pvid)
|
|
|
118 |
{
|
|
|
119 |
GetPkgInfo($opt_prev_pvid, \%pkgPrevData);
|
|
|
120 |
foreach my $field ( qw(pvid name version modified_stamp pname psuffix dlocked build_type)) {
|
|
|
121 |
$pkgData{previous}{$field} = $pkgPrevData{$field};
|
|
|
122 |
}
|
|
|
123 |
}
|
|
|
124 |
|
|
|
125 |
GetPkgIssues();
|
|
|
126 |
GetBuildDependencies();
|
|
|
127 |
GetRunTimeDependencies();
|
|
|
128 |
GetUnitTests();
|
|
|
129 |
GetNotes();
|
|
|
130 |
GetBuildDepDiff();
|
|
|
131 |
GetIssues();
|
|
|
132 |
|
|
|
133 |
#
|
|
|
134 |
# Create a single data structure
|
|
|
135 |
#
|
|
|
136 |
my $data;
|
|
|
137 |
|
|
|
138 |
$data->{package} = \%pkgData;
|
|
|
139 |
$data->{build}{dependency} = \@dependData;
|
|
|
140 |
$data->{builddep}{dependencydiff} = \@buildDepDiff;
|
|
|
141 |
$data->{runtime}{dependency} = \@dependRunData;
|
|
|
142 |
$data->{unit_tests}{test} = \@unitTestData;
|
|
|
143 |
$data->{additional_notes}{note} = \@additionalNotesData;
|
|
|
144 |
$data->{issues}{jira} = \@JiraIssues;
|
|
|
145 |
$data->{issues}{clearquest} = \@ClearQuestIssues;
|
|
|
146 |
$data->{files}{file} = \@FileList;
|
|
|
147 |
|
|
|
148 |
#
|
|
|
149 |
# Insert some metadata
|
|
|
150 |
# created datetime in same format as that from Release Manager
|
|
|
151 |
#
|
|
|
152 |
$data->{meta}{data_version} = $VERSION;
|
|
|
153 |
$data->{meta}{datetime} = time;
|
|
|
154 |
$data->{meta}{created} = strftime "%Y-%m-%d %H:%M:%S.0", gmtime(time);
|
|
|
155 |
|
|
|
156 |
#
|
|
|
157 |
# Determine the name of the output file
|
|
|
158 |
#
|
|
|
159 |
unless ($opt_outfile) {
|
|
|
160 |
$opt_outfile = join('_', $pkgData{name}, $pkgData{version});
|
|
|
161 |
$opt_outfile .= '.xml';
|
|
|
162 |
}
|
|
|
163 |
|
|
|
164 |
#
|
|
|
165 |
# Write out sections of XML
|
|
|
166 |
# Want control over the output order
|
|
|
167 |
# Use lots of attributes and only elements for arrays
|
|
|
168 |
# Save as one attribute per line - for readability
|
|
|
169 |
#
|
|
|
170 |
Verbose("Creating: " . DisplayPath($opt_outfile));
|
|
|
171 |
my $xs = XML::Simple->new( NoAttr =>0, AttrIndent => 1 );
|
|
|
172 |
|
|
|
173 |
open (my $XML, '>', $opt_outfile) || Error ("Cannot create output file: $opt_outfile", $!);
|
|
|
174 |
print $XML ('<?xml version="1.0" encoding="UTF-8"?>' . "\n");
|
|
|
175 |
print $XML ("<package_data>\n");
|
|
|
176 |
foreach my $section (qw( meta package build builddep runtime unit_tests additional_notes issues files)) {
|
|
|
177 |
print $XML $xs->XMLout($data->{$section}, 'RootName' => $section);
|
|
|
178 |
}
|
|
|
179 |
print $XML ("</package_data>\n");
|
|
|
180 |
close $XML;
|
|
|
181 |
|
|
|
182 |
#
|
|
|
183 |
# All done
|
|
|
184 |
#
|
|
|
185 |
exit 0;
|
|
|
186 |
}
|
|
|
187 |
|
|
|
188 |
#-------------------------------------------------------------------------------
|
|
|
189 |
# Function : populateHash
|
|
|
190 |
#
|
|
|
191 |
# Description : Put an array of data items into a hash
|
|
|
192 |
# Clean white space from the data
|
|
|
193 |
# Replace /r and /n sequences with a single <br>
|
|
|
194 |
#
|
|
|
195 |
# Inputs : pHash - ref to output hash
|
|
|
196 |
# pRow - Ref to the row data
|
|
|
197 |
# pItems - Ref to an hash array of entry names
|
|
|
198 |
#
|
|
|
199 |
# Returns : pHash
|
|
|
200 |
#
|
|
|
201 |
sub populateHash
|
|
|
202 |
{
|
|
|
203 |
my ($pHash, $pRow, $pItems) = @_;
|
|
|
204 |
|
|
|
205 |
foreach my $item ( @{$pItems} ) {
|
|
|
206 |
my $data = shift @{$pRow};
|
|
|
207 |
|
|
|
208 |
if (defined $data)
|
|
|
209 |
{
|
|
|
210 |
$data =~ s~^\s+~~;
|
|
|
211 |
$data =~ s~\s+$~~;
|
|
|
212 |
|
|
|
213 |
#
|
|
|
214 |
# Clean multiline items
|
|
|
215 |
#
|
|
|
216 |
if ($data =~ m~\n|\r~)
|
|
|
217 |
{
|
|
|
218 |
$data =~ tr~\r~\n~;
|
|
|
219 |
$data =~ tr~\n~\n~s;
|
|
|
220 |
$data =~ s~\n~<br>~g;
|
|
|
221 |
$data =~ s~<br><br>~<br>~gi;
|
|
|
222 |
}
|
|
|
223 |
|
|
|
224 |
#
|
|
|
225 |
# Convert from iso-8859-1 into utf-8
|
|
|
226 |
# Release Manger appears to store data in iso-8859-1
|
|
|
227 |
# Note sure about ClearQuest data
|
|
|
228 |
#
|
|
|
229 |
$data = decode( 'iso-8859-1', $data );
|
|
|
230 |
$data = encode( 'utf-8', $data );
|
|
|
231 |
|
|
|
232 |
#
|
|
|
233 |
# Some other nessessary conversions
|
|
|
234 |
# Appears to come from ClearQuest data, or RM fields pasted from ClearQuest
|
|
|
235 |
#
|
|
|
236 |
$data =~ s/\023/-/g; # Some form of -
|
|
|
237 |
$data =~ s/\x1C/"/g; # Some Forms of ' and "
|
|
|
238 |
$data =~ s/\x1D/"/g;
|
|
|
239 |
$data =~ s/\x18/'/g;
|
|
|
240 |
$data =~ s/\x19/'/g;
|
|
|
241 |
$data =~ s/\t/	/g; # Tab
|
|
|
242 |
$data =~ s/[[:cntrl:]]/?/g; # Control Chars
|
|
|
243 |
# $data =~ s/[^[:ascii:]]/?/g; # Non Ascii
|
|
|
244 |
|
|
|
245 |
#
|
|
|
246 |
# Store in hash
|
|
|
247 |
#
|
|
|
248 |
$pHash->{$item} = $data;
|
|
|
249 |
}
|
|
|
250 |
}
|
|
|
251 |
return $pHash;
|
|
|
252 |
}
|
|
|
253 |
|
|
|
254 |
#-------------------------------------------------------------------------------
|
|
|
255 |
# Function : performSqlQueryCallback
|
|
|
256 |
#
|
|
|
257 |
# Description : Perform a general Sql query and invoke a user function for
|
|
|
258 |
# each row of results
|
|
|
259 |
#
|
|
|
260 |
# Inputs : $fname - Name of query for error reporting
|
|
|
261 |
# $m_sqlstr - Query string
|
|
|
262 |
# $f_process - Function called for each row in the result
|
|
|
263 |
# Use closure to have callback modify other data
|
|
|
264 |
#
|
|
|
265 |
# Returns : Number of rows found
|
|
|
266 |
#
|
|
|
267 |
sub performSqlQueryCallback
|
|
|
268 |
{
|
|
|
269 |
my ($fname, $m_sqlstr, $f_process ) = @_;
|
|
|
270 |
my $found = 0;
|
|
|
271 |
|
|
|
272 |
#
|
|
|
273 |
# Connect to the database - once
|
|
|
274 |
#
|
|
|
275 |
connectRM(\$RM_DB, 0) unless $RM_DB;
|
|
|
276 |
|
|
|
277 |
$m_sqlstr =~ s~\s+~ ~g;
|
|
|
278 |
Verbose3("SQL:", $m_sqlstr);
|
|
|
279 |
my $sth = $RM_DB->prepare($m_sqlstr);
|
|
|
280 |
if ( defined($sth) )
|
|
|
281 |
{
|
|
|
282 |
if ( $sth->execute( ) )
|
|
|
283 |
{
|
|
|
284 |
if ( $sth->rows )
|
|
|
285 |
{
|
|
|
286 |
while ( my @row = $sth->fetchrow_array )
|
|
|
287 |
{
|
|
|
288 |
$found++;
|
|
|
289 |
&$f_process(\@row);
|
|
|
290 |
}
|
|
|
291 |
}
|
|
|
292 |
$sth->finish();
|
|
|
293 |
}
|
|
|
294 |
else
|
|
|
295 |
{
|
|
|
296 |
Error("$fname:Execute failure: $m_sqlstr", $sth->errstr() );
|
|
|
297 |
}
|
|
|
298 |
}
|
|
|
299 |
else
|
|
|
300 |
{
|
|
|
301 |
Error("$fname:Prepare failure" );
|
|
|
302 |
}
|
|
|
303 |
|
|
|
304 |
unless ( $found )
|
|
|
305 |
{
|
|
|
306 |
Verbose("$fname:No data for: $opt_pvid");
|
|
|
307 |
}
|
|
|
308 |
return $found;
|
|
|
309 |
}
|
|
|
310 |
|
|
|
311 |
#-------------------------------------------------------------------------------
|
|
|
312 |
# Function : populateArrayFromSql
|
|
|
313 |
#
|
|
|
314 |
# Description : Issue an SQL query and push the results into an array of hashes
|
|
|
315 |
# where each row from the query is a hash and the entire result is an
|
|
|
316 |
# array
|
|
|
317 |
#
|
|
|
318 |
# Inputs : name - For error reporting
|
|
|
319 |
# pArray - Ref to the output array
|
|
|
320 |
# sql - Sql to process
|
|
|
321 |
# pItems - Array of tems to extract
|
|
|
322 |
# Must match the SQL SELECT arguments
|
|
|
323 |
# Item names starting with '-' do not end up in the
|
|
|
324 |
# generated XML
|
|
|
325 |
# Returns :
|
|
|
326 |
#
|
|
|
327 |
sub populateArrayFromSql
|
|
|
328 |
{
|
|
|
329 |
my ($fname, $pArray, $m_sqlstr, $pItems) = @_;
|
|
|
330 |
|
|
|
331 |
performSqlQueryCallback($fname,
|
|
|
332 |
$m_sqlstr,
|
|
|
333 |
sub {
|
|
|
334 |
my ($pRow) = @_;
|
|
|
335 |
my %entry;
|
|
|
336 |
push @{$pArray}, populateHash( \%entry, $pRow, $pItems);
|
|
|
337 |
}
|
|
|
338 |
);
|
|
|
339 |
#DebugDumpData("populateArrayFromSql", $pArray);
|
|
|
340 |
}
|
|
|
341 |
|
|
|
342 |
#-------------------------------------------------------------------------------
|
|
|
343 |
# Function : GetPkgInfo
|
|
|
344 |
#
|
|
|
345 |
# Description : Get Basic Package Information
|
|
|
346 |
#
|
|
|
347 |
# Inputs : pvid - pvid of package to fetch
|
|
|
348 |
# pHash - Ref to Hash to populate
|
|
|
349 |
#
|
|
|
350 |
# Returns :
|
|
|
351 |
#
|
|
|
352 |
sub GetPkgInfo
|
|
|
353 |
{
|
|
|
354 |
my ($pvid, $pHash) = @_;
|
|
|
355 |
my $fname = 'GetPkgInfo';
|
|
|
356 |
|
|
|
357 |
#
|
|
|
358 |
# Now extract the package infromation
|
|
|
359 |
#
|
|
|
360 |
my @items = qw(name version modifier modifier_email modified_stamp owner owner_email pkg_label src_path vcstag reason long_desc short_desc pvid psuffix pname deployable -prev_pvid build_type);
|
|
|
361 |
my $m_sqlstr =
|
|
|
362 |
"SELECT ".
|
|
|
363 |
" pkg.pkg_name, ".
|
|
|
364 |
" pv.pkg_version, ".
|
|
|
365 |
" lm.full_name AS modifier,".
|
|
|
366 |
" lm.user_email AS modifier_email, ".
|
|
|
367 |
" pv.modified_stamp, ".
|
|
|
368 |
" own.full_name AS owner,".
|
|
|
369 |
" own.user_email AS owner_email, ".
|
|
|
370 |
" pv.PKG_LABEL,".
|
|
|
371 |
" pv.SRC_PATH,".
|
|
|
372 |
" release_manager.PK_RMAPI.return_vcs_tag(pv.PV_ID),".
|
|
|
373 |
" pv.comments reason, ".
|
|
|
374 |
" pv.pv_overview long_desc,".
|
|
|
375 |
" pv.pv_description short_desc,".
|
|
|
376 |
" pv.pv_id,".
|
|
|
377 |
" pv.v_ext,".
|
|
|
378 |
" pkg.pkg_name || pv.v_ext, ".
|
|
|
379 |
" pv.is_deployable,".
|
|
|
380 |
" pv.last_pv_id,".
|
|
|
381 |
" pv.build_type".
|
|
|
382 |
" FROM RELEASE_MANAGER.PACKAGES pkg, RELEASE_MANAGER.package_versions pv, RELEASE_MANAGER.users lm, RELEASE_MANAGER.users own".
|
|
|
383 |
" WHERE pv.pkg_id = pkg.pkg_id".
|
|
|
384 |
" AND pv.modifier_id = lm.user_id".
|
|
|
385 |
" AND pv.owner_id = own.user_id".
|
|
|
386 |
" AND pv.pv_id = " . $pvid;
|
|
|
387 |
|
|
|
388 |
performSqlQueryCallback($fname,
|
|
|
389 |
$m_sqlstr,
|
|
|
390 |
sub { populateHash( $pHash, $_[0], \@items); }
|
|
|
391 |
);
|
|
|
392 |
|
|
|
393 |
# DebugDumpData("$fname", $pHash);
|
|
|
394 |
}
|
|
|
395 |
|
|
|
396 |
#-------------------------------------------------------------------------------
|
|
|
397 |
# Function : GetPkgIssues
|
|
|
398 |
#
|
|
|
399 |
# Description : Get the Issues for the package
|
|
|
400 |
#
|
|
|
401 |
# Inputs :
|
|
|
402 |
#
|
|
|
403 |
# Returns :
|
|
|
404 |
#
|
|
|
405 |
sub GetPkgIssues
|
|
|
406 |
{
|
|
|
407 |
#
|
|
|
408 |
# Get associated Jira issues
|
|
|
409 |
# Insert Dependency issues into the Package Information
|
|
|
410 |
#
|
|
|
411 |
performSqlQueryCallback('GetPkgIssuesJira',
|
|
|
412 |
"SELECT iss_key".
|
|
|
413 |
" FROM".
|
|
|
414 |
" RELEASE_MANAGER.JIRA_ISSUES ".
|
|
|
415 |
" WHERE pv_id in ($opt_pvid)".
|
|
|
416 |
" ORDER BY iss_key ASC",
|
|
|
417 |
sub
|
|
|
418 |
{
|
|
|
419 |
my ($pRow) = @_;
|
|
|
420 |
UniquePush (\@JiraIssueList, $pRow->[0]);
|
|
|
421 |
push @{$pkgData{issues}{jira}}, $pRow->[0];
|
|
|
422 |
}
|
|
|
423 |
);
|
|
|
424 |
|
|
|
425 |
#
|
|
|
426 |
# Get associated ClearQuest Issues
|
|
|
427 |
# Insert Dependency issues into the Package Information
|
|
|
428 |
# Keep the body of the ClearQuest data for later
|
|
|
429 |
#
|
|
|
430 |
my @items = qw(iss_uid iss_db iss_id iss_state iss_mod_date iss_notes);
|
|
|
431 |
performSqlQueryCallback('GetPkgIssuesCQ',
|
|
|
432 |
"SELECT iss_db || '_' || iss_id as iss_uid, iss_db, iss_id, iss_state, mod_date, notes".
|
|
|
433 |
" FROM".
|
|
|
434 |
" RELEASE_MANAGER.CQ_ISSUES cq ".
|
|
|
435 |
" WHERE pv_id in ($opt_pvid)",
|
|
|
436 |
sub
|
|
|
437 |
{
|
|
|
438 |
my ($pRow) = @_;
|
|
|
439 |
my $uid = $pRow->[0];
|
|
|
440 |
push @{$pkgData{issues}{clearquest}}, $uid;
|
|
|
441 |
|
|
|
442 |
my %entry;
|
|
|
443 |
populateHash(\%entry,$pRow, \@items);
|
|
|
444 |
$ClearQuestIssueData{$uid} = \%entry;
|
|
|
445 |
|
|
|
446 |
}
|
|
|
447 |
);
|
|
|
448 |
}
|
|
|
449 |
|
|
|
450 |
#-------------------------------------------------------------------------------
|
|
|
451 |
# Function : GetBuildDependencies
|
|
|
452 |
#
|
|
|
453 |
# Description : Get the build dependencies and associated information
|
|
|
454 |
#
|
|
|
455 |
# Inputs :
|
|
|
456 |
#
|
|
|
457 |
# Returns :
|
|
|
458 |
#
|
|
|
459 |
sub GetBuildDependencies
|
|
|
460 |
{
|
|
|
461 |
my @items = qw(pvid name version dlocked pkg_label src_path vcstag -pkgid modified_stamp reason pname psuffix build_type);
|
|
|
462 |
my $m_sqlstr = "SELECT ".
|
|
|
463 |
" pv.PV_ID,".
|
|
|
464 |
" pkg.PKG_NAME, ".
|
|
|
465 |
" pv.PKG_VERSION, ".
|
|
|
466 |
" pv.DLOCKED,".
|
|
|
467 |
" pv.PKG_LABEL,".
|
|
|
468 |
" pv.SRC_PATH,".
|
|
|
469 |
" release_manager.PK_RMAPI.return_vcs_tag(pv.PV_ID),".
|
|
|
470 |
" pv.PKG_ID,".
|
|
|
471 |
" pv.MODIFIED_STAMP," .
|
|
|
472 |
" pv.comments as reason,".
|
|
|
473 |
" pkg.PKG_NAME || pv.v_ext," .
|
|
|
474 |
" pv.v_ext," .
|
|
|
475 |
" pv.build_type" .
|
|
|
476 |
" FROM ".
|
|
|
477 |
" RELEASE_MANAGER.PACKAGE_DEPENDENCIES pd, ".
|
|
|
478 |
" RELEASE_MANAGER.PACKAGE_VERSIONS pv, ".
|
|
|
479 |
" RELEASE_MANAGER.PACKAGES pkg" .
|
|
|
480 |
" WHERE ".
|
|
|
481 |
#" pv.PV_ID = \'$opt_pvid\' " .
|
|
|
482 |
" pd.PV_ID(+) = \'$opt_pvid\' " .
|
|
|
483 |
" AND pd.DPV_ID = pv.PV_ID" .
|
|
|
484 |
" AND pv.PKG_ID = pkg.PKG_ID" .
|
|
|
485 |
"";
|
|
|
486 |
|
|
|
487 |
populateArrayFromSql( 'GetBuildDependencies', \@dependData, $m_sqlstr, \@items );
|
|
|
488 |
|
|
|
489 |
#
|
|
|
490 |
# Get associated Jira issues
|
|
|
491 |
# Group issues by pvid
|
|
|
492 |
#
|
|
|
493 |
my %issuedByPvid;
|
|
|
494 |
performSqlQueryCallback( 'GetBuildDependenciesIssuesJira',
|
|
|
495 |
"SELECT ji.pv_id, ji.iss_key FROM".
|
|
|
496 |
" RELEASE_MANAGER.PACKAGE_DEPENDENCIES pd, ".
|
|
|
497 |
" RELEASE_MANAGER.PACKAGE_VERSIONS pv, ".
|
|
|
498 |
" RELEASE_MANAGER.JIRA_ISSUES ji ".
|
|
|
499 |
" WHERE ".
|
|
|
500 |
" pd.PV_ID(+) = \'$opt_pvid\' " .
|
|
|
501 |
" AND pd.DPV_ID = pv.PV_ID" .
|
|
|
502 |
" AND pd.DPV_ID = ji.PV_ID" .
|
|
|
503 |
" ORDER BY ji.iss_key ASC",
|
|
|
504 |
sub
|
|
|
505 |
{
|
|
|
506 |
my ($pRow) = @_;
|
|
|
507 |
my $pvid = $pRow->[0];
|
|
|
508 |
my $issue = $pRow->[1];
|
|
|
509 |
push @{$issuedByPvid{$pvid}}, $issue;
|
|
|
510 |
UniquePush (\@JiraIssueList, $issue);
|
|
|
511 |
}
|
|
|
512 |
);
|
|
|
513 |
|
|
|
514 |
#
|
|
|
515 |
# Insert jira issues into the dependendency array
|
|
|
516 |
#
|
|
|
517 |
foreach my $entry (@dependData) {
|
|
|
518 |
my $pvid = $entry->{pvid};
|
|
|
519 |
if (exists $issuedByPvid{$pvid})
|
|
|
520 |
{
|
|
|
521 |
push @{$entry->{issues}{jira}}, @{$issuedByPvid{$pvid}};
|
|
|
522 |
}
|
|
|
523 |
}
|
|
|
524 |
|
|
|
525 |
#
|
|
|
526 |
# Get associated ClearQuest issues
|
|
|
527 |
# Group issues by pvid
|
|
|
528 |
#
|
|
|
529 |
my %CQissuedByPvid;
|
|
|
530 |
@items = qw(-pvid iss_uid iss_db iss_id iss_state iss_mod_date iss_notes);
|
|
|
531 |
performSqlQueryCallback( 'GetBuildDependenciesIssuesCQ',
|
|
|
532 |
"SELECT cq.pv_id,iss_db || '_' || iss_id as iss_uid, cq.iss_db, cq.iss_id, cq.iss_state,mod_date, notes FROM".
|
|
|
533 |
" RELEASE_MANAGER.PACKAGE_DEPENDENCIES pd, ".
|
|
|
534 |
" RELEASE_MANAGER.PACKAGE_VERSIONS pv, ".
|
|
|
535 |
" RELEASE_MANAGER.CQ_ISSUES cq ".
|
|
|
536 |
" WHERE ".
|
|
|
537 |
" pd.PV_ID(+) = \'$opt_pvid\' " .
|
|
|
538 |
" AND pd.DPV_ID = pv.PV_ID" .
|
|
|
539 |
" AND pd.DPV_ID = cq.PV_ID",
|
|
|
540 |
sub
|
|
|
541 |
{
|
|
|
542 |
my ($pRow) = @_;
|
|
|
543 |
my $pvid = $pRow->[0];
|
|
|
544 |
my $uid = $pRow->[1];
|
|
|
545 |
|
|
|
546 |
my %data;
|
|
|
547 |
populateHash(\%data, $pRow, \@items);
|
|
|
548 |
|
|
|
549 |
push @{$CQissuedByPvid{$pvid}}, $uid;
|
|
|
550 |
$ClearQuestIssueData{$uid} = \%data;
|
|
|
551 |
|
|
|
552 |
}
|
|
|
553 |
);
|
|
|
554 |
|
|
|
555 |
#
|
|
|
556 |
# Insert clearquest issues into the dependendency array
|
|
|
557 |
#
|
|
|
558 |
foreach my $entry (@dependData) {
|
|
|
559 |
my $pvid = $entry->{pvid};
|
|
|
560 |
if (exists $CQissuedByPvid{$pvid})
|
|
|
561 |
{
|
|
|
562 |
push @{$entry->{issues}{clearquest}}, @{$CQissuedByPvid{$pvid}};
|
|
|
563 |
}
|
|
|
564 |
}
|
|
|
565 |
|
|
|
566 |
# DebugDumpData("Dependency Issues", \@dependData, \@issues, \%issues);
|
|
|
567 |
}
|
|
|
568 |
|
|
|
569 |
#-------------------------------------------------------------------------------
|
|
|
570 |
# Function : GetRunTimeDependencies
|
|
|
571 |
#
|
|
|
572 |
# Description : Get the runtime dependencies
|
|
|
573 |
#
|
|
|
574 |
# Inputs :
|
|
|
575 |
#
|
|
|
576 |
# Returns :
|
|
|
577 |
#
|
|
|
578 |
sub GetRunTimeDependencies
|
|
|
579 |
{
|
|
|
580 |
my $m_sqlstr = " SELECT pkg.pkg_name, ".
|
|
|
581 |
" pv.pkg_version, ".
|
|
|
582 |
" pv.v_ext, ".
|
|
|
583 |
" pkg.pkg_name || pv.v_ext, ".
|
|
|
584 |
" rtd.rtd_comments, ".
|
|
|
585 |
" rtd.rtd_url,".
|
|
|
586 |
" pv.pv_id".
|
|
|
587 |
" FROM RELEASE_MANAGER.PACKAGES pkg, ".
|
|
|
588 |
"RELEASE_MANAGER.package_versions pv, ".
|
|
|
589 |
"RELEASE_MANAGER.runtime_dependencies rtd".
|
|
|
590 |
" WHERE pv.pkg_id = pkg.pkg_id".
|
|
|
591 |
" AND rtd.rtd_id = pv.pv_id".
|
|
|
592 |
" AND rtd.pv_id = " . $opt_pvid .
|
|
|
593 |
" ORDER BY UPPER(pkg.pkg_name)";
|
|
|
594 |
my @items = qw(name version psuffix pname comment url pvid);
|
|
|
595 |
|
|
|
596 |
populateArrayFromSql( 'GetRunTimeDependencies', \@dependRunData, $m_sqlstr, \@items );
|
|
|
597 |
}
|
|
|
598 |
|
|
|
599 |
#-------------------------------------------------------------------------------
|
|
|
600 |
# Function : GetUnitTests
|
|
|
601 |
#
|
|
|
602 |
# Description : Get the unit test information
|
|
|
603 |
#
|
|
|
604 |
# Inputs :
|
|
|
605 |
#
|
|
|
606 |
# Returns :
|
|
|
607 |
#
|
|
|
608 |
sub GetUnitTests
|
|
|
609 |
{
|
|
|
610 |
my $m_sqlstr = << "END_SQL";
|
|
|
611 |
SELECT ttypes.test_type_id,
|
|
|
612 |
ttypes.test_type_name,
|
|
|
613 |
ut.TEST_ID,
|
|
|
614 |
ut.PV_ID,
|
|
|
615 |
ut.TEST_SUMMARY,
|
|
|
616 |
ut.COMPLETION_DATE,
|
|
|
617 |
tusr.full_name AS TESTER,
|
|
|
618 |
tusr.user_email AS TESTER_EMAIL,
|
|
|
619 |
ut.RESULTS_URL,
|
|
|
620 |
ut.RESULTS_ATTACHMENT_NAME,
|
|
|
621 |
ut.ACCEPTANCE_DATE,
|
|
|
622 |
ausr.FULL_NAME AS REVIEWEE,
|
|
|
623 |
ausr.user_email AS REVIEWEE_EMAIL,
|
|
|
624 |
ut.NUMOF_TEST,
|
|
|
625 |
ut.TEST_ACCEPTED,
|
|
|
626 |
ut.REVIEW_COMMENTS
|
|
|
627 |
FROM RELEASE_MANAGER.UNIT_TESTS ut,
|
|
|
628 |
(
|
|
|
629 |
SELECT tt.*
|
|
|
630 |
FROM RELEASE_MANAGER.TEST_TYPES tt
|
|
|
631 |
WHERE NOT tt.DISPLAY_ORDER IS NULL
|
|
|
632 |
) ttypes,
|
|
|
633 |
RELEASE_MANAGER.USERS tusr,
|
|
|
634 |
RELEASE_MANAGER.USERS ausr
|
|
|
635 |
WHERE
|
|
|
636 |
ut.TEST_TYPES_FK = ttypes.test_type_id
|
|
|
637 |
AND ut.pv_id (+) = $opt_pvid
|
|
|
638 |
AND ut.COMPLETED_BY = tusr.user_id (+)
|
|
|
639 |
AND ut.ACCEPTED_BY = ausr.user_id (+)
|
|
|
640 |
ORDER BY ttypes.DISPLAY_ORDER
|
|
|
641 |
END_SQL
|
|
|
642 |
|
|
|
643 |
my @items = qw(
|
|
|
644 |
-test_type
|
|
|
645 |
name
|
|
|
646 |
-test_id
|
|
|
647 |
-pv_id
|
|
|
648 |
test_summary
|
|
|
649 |
completion_date
|
|
|
650 |
tester
|
|
|
651 |
tester_email
|
|
|
652 |
results_url
|
|
|
653 |
results_attachment_name
|
|
|
654 |
acceptance_date
|
|
|
655 |
reviewee
|
|
|
656 |
reviewee_email
|
|
|
657 |
numof_test
|
|
|
658 |
test_accepted
|
|
|
659 |
review_comments
|
|
|
660 |
);
|
|
|
661 |
|
|
|
662 |
populateArrayFromSql( 'GetUnitTests', \@unitTestData, $m_sqlstr, \@items );
|
|
|
663 |
}
|
|
|
664 |
|
|
|
665 |
#-------------------------------------------------------------------------------
|
|
|
666 |
# Function : GetNotes
|
|
|
667 |
#
|
|
|
668 |
# Description : Get the addiotional Notes
|
|
|
669 |
#
|
|
|
670 |
# Inputs :
|
|
|
671 |
#
|
|
|
672 |
# Returns :
|
|
|
673 |
#
|
|
|
674 |
sub GetNotes
|
|
|
675 |
{
|
|
|
676 |
my $m_sqlstr = << "END_SQL";
|
|
|
677 |
SELECT an.note_id, an.NOTE_TITLE, an.NOTE_BODY, an.mod_date, usr.full_name, usr.user_email,
|
|
|
678 |
an.mod_date ||' by '|| usr.full_name AS lastmod
|
|
|
679 |
FROM RELEASE_MANAGER.ADDITIONAL_NOTES an,
|
|
|
680 |
RELEASE_MANAGER.USERS usr
|
|
|
681 |
WHERE an.pv_id = $opt_pvid
|
|
|
682 |
AND an.mod_user = usr.user_id
|
|
|
683 |
ORDER BY an.note_id
|
|
|
684 |
END_SQL
|
|
|
685 |
|
|
|
686 |
my @items = qw(
|
|
|
687 |
-note_id
|
|
|
688 |
note_title
|
|
|
689 |
note_body
|
|
|
690 |
mod_date
|
|
|
691 |
full_name
|
|
|
692 |
user_email
|
|
|
693 |
);
|
|
|
694 |
|
|
|
695 |
populateArrayFromSql( 'GetNotes', \@additionalNotesData, $m_sqlstr, \@items );
|
|
|
696 |
}
|
|
|
697 |
|
|
|
698 |
#-------------------------------------------------------------------------------
|
|
|
699 |
# Function : GetBuildDepDiff
|
|
|
700 |
#
|
|
|
701 |
# Description : Get the Differences in Build Deps between this verion and the previous
|
|
|
702 |
#
|
|
|
703 |
# Inputs :
|
|
|
704 |
#
|
|
|
705 |
# Returns :
|
|
|
706 |
#
|
|
|
707 |
sub GetBuildDepDiff
|
|
|
708 |
{
|
|
|
709 |
#
|
|
|
710 |
# Only if data can be calculated
|
|
|
711 |
return unless $opt_prev_pvid;
|
|
|
712 |
|
|
|
713 |
my $m_sqlstr = << "END_SQL";
|
|
|
714 |
SELECT pkg.pkg_name, comp.PV_ID,comp.OLD_PV_ID,comp.PKG_ID,comp.PKG_VERSION,comp.PREVIOUS_VERSION,comp.STATUS,usr.FULL_NAME, usr.user_email
|
|
|
715 |
FROM RELEASE_MANAGER.PACKAGES pkg,
|
|
|
716 |
RELEASE_MANAGER.USERS usr,
|
|
|
717 |
(
|
|
|
718 |
SELECT dpv.pv_id AS pv_id, -1 AS old_pv_id, dpv.pkg_id, NULL AS pkg_version, dpv.pkg_version AS previous_version, 'deleted' AS status, dpv.MODIFIER_ID
|
|
|
719 |
FROM RELEASE_MANAGER.PACKAGE_VERSIONS dpv,
|
|
|
720 |
RELEASE_MANAGER.PACKAGE_DEPENDENCIES dep,
|
|
|
721 |
(
|
|
|
722 |
SELECT olddpv.pv_id AS previous_pv_id, newdpv.pv_id AS current_pv_id
|
|
|
723 |
FROM RELEASE_MANAGER.PACKAGE_VERSIONS newdpv,
|
|
|
724 |
RELEASE_MANAGER.PACKAGE_DEPENDENCIES newdep,
|
|
|
725 |
RELEASE_MANAGER.PACKAGE_VERSIONS olddpv,
|
|
|
726 |
RELEASE_MANAGER.PACKAGE_DEPENDENCIES olddep
|
|
|
727 |
WHERE newdep.DPV_ID = newdpv.PV_ID
|
|
|
728 |
AND olddep.DPV_ID = olddpv.PV_ID
|
|
|
729 |
AND newdep.pv_id = :PV_ID
|
|
|
730 |
AND olddep.pv_id = :OLD_PV_ID
|
|
|
731 |
AND newdpv.pkg_id = olddpv.pkg_id
|
|
|
732 |
AND NVL( newdpv.v_ext , 'LINK_A_NULL' ) = NVL( olddpv.v_ext, 'LINK_A_NULL' )
|
|
|
733 |
) diff
|
|
|
734 |
WHERE dep.DPV_ID = dpv.PV_ID
|
|
|
735 |
AND dep.pv_id = :OLD_PV_ID
|
|
|
736 |
AND dpv.pv_id = diff.previous_pv_id (+)
|
|
|
737 |
AND (diff.current_pv_id IS NULL OR diff.previous_pv_id IS NULL)
|
|
|
738 |
UNION
|
|
|
739 |
SELECT dpv.pv_id AS pv_id, 0 AS old_pv_id, dpv.pkg_id, dpv.pkg_version, NULL AS previous_version, 'added' AS status, dpv.MODIFIER_ID
|
|
|
740 |
FROM RELEASE_MANAGER.PACKAGE_VERSIONS dpv,
|
|
|
741 |
RELEASE_MANAGER.PACKAGE_DEPENDENCIES dep,
|
|
|
742 |
(
|
|
|
743 |
SELECT olddpv.pv_id AS previous_pv_id,
|
|
|
744 |
newdpv.pv_id AS current_pv_id
|
|
|
745 |
FROM RELEASE_MANAGER.PACKAGE_VERSIONS newdpv,
|
|
|
746 |
RELEASE_MANAGER.PACKAGE_DEPENDENCIES newdep,
|
|
|
747 |
RELEASE_MANAGER.PACKAGE_VERSIONS olddpv,
|
|
|
748 |
RELEASE_MANAGER.PACKAGE_DEPENDENCIES olddep
|
|
|
749 |
WHERE newdep.DPV_ID = newdpv.PV_ID
|
|
|
750 |
AND olddep.DPV_ID = olddpv.PV_ID
|
|
|
751 |
AND newdep.pv_id = :PV_ID
|
|
|
752 |
AND olddep.pv_id = :OLD_PV_ID
|
|
|
753 |
AND newdpv.pkg_id = olddpv.pkg_id
|
|
|
754 |
AND NVL( newdpv.v_ext , 'LINK_A_NULL' ) = NVL( olddpv.v_ext, 'LINK_A_NULL' )
|
|
|
755 |
) diff
|
|
|
756 |
WHERE dep.DPV_ID = dpv.PV_ID
|
|
|
757 |
AND dep.pv_id = :PV_ID
|
|
|
758 |
AND dpv.pv_id = diff.current_pv_id (+)
|
|
|
759 |
AND (diff.current_pv_id IS NULL OR diff.previous_pv_id IS NULL)
|
|
|
760 |
UNION
|
|
|
761 |
SELECT newdpv.pv_id AS pv_id,
|
|
|
762 |
olddep.dpv_id AS old_pv_id,
|
|
|
763 |
newdpv.pkg_id, newdpv.pkg_version,
|
|
|
764 |
DECODE( newdpv.pv_id, olddpv.pv_id, NULL, olddpv.pkg_version ) AS previous_version,
|
|
|
765 |
DECODE( newdpv.pv_id, olddpv.pv_id, 'same', 'modified' ) AS status, newdpv.MODIFIER_ID
|
|
|
766 |
FROM RELEASE_MANAGER.PACKAGE_VERSIONS newdpv,
|
|
|
767 |
RELEASE_MANAGER.PACKAGE_DEPENDENCIES newdep,
|
|
|
768 |
RELEASE_MANAGER.PACKAGE_VERSIONS olddpv,
|
|
|
769 |
RELEASE_MANAGER.PACKAGE_DEPENDENCIES olddep
|
|
|
770 |
WHERE newdep.DPV_ID = newdpv.PV_ID
|
|
|
771 |
AND olddep.DPV_ID = olddpv.PV_ID
|
|
|
772 |
AND newdep.pv_id = :PV_ID
|
|
|
773 |
AND olddep.pv_id = :OLD_PV_ID
|
|
|
774 |
AND newdpv.pkg_id = olddpv.pkg_id
|
|
|
775 |
AND NVL( newdpv.v_ext , 'LINK_A_NULL' ) = NVL( olddpv.v_ext, 'LINK_A_NULL' )
|
|
|
776 |
) comp
|
|
|
777 |
WHERE comp.pkg_id = pkg.pkg_id
|
|
|
778 |
AND comp.modifier_id = usr.user_id
|
|
|
779 |
ORDER BY UPPER(pkg.pkg_name)
|
|
|
780 |
END_SQL
|
|
|
781 |
|
|
|
782 |
my @items = qw(
|
|
|
783 |
name
|
|
|
784 |
pvid
|
|
|
785 |
previous_pvid
|
|
|
786 |
-pkg_id
|
|
|
787 |
version
|
|
|
788 |
previous_version
|
|
|
789 |
status
|
|
|
790 |
modifier
|
|
|
791 |
modifier_email
|
|
|
792 |
);
|
|
|
793 |
|
|
|
794 |
$m_sqlstr =~ s~:PV_ID~$opt_pvid~g;
|
|
|
795 |
$m_sqlstr =~ s~:OLD_PV_ID~$opt_prev_pvid~g;
|
|
|
796 |
populateArrayFromSql( 'GetBuildDepDiff', \@buildDepDiff, $m_sqlstr, \@items );
|
|
|
797 |
}
|
|
|
798 |
|
|
|
799 |
#-------------------------------------------------------------------------------
|
|
|
800 |
# Function : GetIssues
|
|
|
801 |
#
|
|
|
802 |
# Description : Get issues for the current package and its dependencies
|
|
|
803 |
# A list of issues has already been determined. This function
|
|
|
804 |
# will simply get the data behind the issue information
|
|
|
805 |
#
|
|
|
806 |
# There are two sources of issues
|
|
|
807 |
# ClearQuest
|
|
|
808 |
# Jira - Details held externally
|
|
|
809 |
#
|
|
|
810 |
# Inputs :
|
|
|
811 |
#
|
|
|
812 |
# Returns :
|
|
|
813 |
#
|
|
|
814 |
sub GetIssues
|
|
|
815 |
{
|
|
|
816 |
GetCQIssues();
|
|
|
817 |
GetJiraIssues();
|
|
|
818 |
}
|
|
|
819 |
|
|
|
820 |
#-------------------------------------------------------------------------------
|
|
|
821 |
# Function : GetCQIssues
|
|
|
822 |
#
|
|
|
823 |
# Description : Get the body of the CQ Issues required by the package and
|
|
|
824 |
# dependent packages
|
|
|
825 |
#
|
|
|
826 |
# Already have this data
|
|
|
827 |
# Just need to put it in the right form
|
|
|
828 |
#
|
|
|
829 |
# Would be nice to get more data about the ClearQuest issues
|
|
|
830 |
# but the database is hard to access - and going away.
|
|
|
831 |
#
|
|
|
832 |
# Inputs :
|
|
|
833 |
#
|
|
|
834 |
# Returns :
|
|
|
835 |
#
|
|
|
836 |
sub GetCQIssues
|
|
|
837 |
{
|
|
|
838 |
|
|
|
839 |
my $fname = 'GetCQIssues';
|
|
|
840 |
my $m_sqlstr = << "END_SQL";
|
|
|
841 |
SELECT
|
|
|
842 |
'__enumCLEARQUEST_DEVI_ID__' || '_' || si.dbid as iss_uid,
|
|
|
843 |
__enumCLEARQUEST_DEVI_ID__ AS iss_db,
|
|
|
844 |
si.dbid AS iss_id,
|
|
|
845 |
si.new_num AS iss_num,
|
|
|
846 |
si.headline AS summary,
|
|
|
847 |
sdef.name AS status,
|
|
|
848 |
si.priority AS priority,
|
|
|
849 |
dbms_lob.substr( si.releaseinfo, 4000, 1 )as releaseinfo,
|
|
|
850 |
si.issue_type AS issue_type,
|
|
|
851 |
si.release_part1,
|
|
|
852 |
si.release_part2,
|
|
|
853 |
si.release_part3,
|
|
|
854 |
si.project,
|
|
|
855 |
si.product,
|
|
|
856 |
si.package_ref,
|
|
|
857 |
dbms_lob.substr( si.notes_log, 4000, 1 ),
|
|
|
858 |
dbms_lob.substr( si.description, 4000, 1 ),
|
|
|
859 |
NULL AS release_id,
|
|
|
860 |
NULL AS client_ref,
|
|
|
861 |
NULL AS severity,
|
|
|
862 |
NULL AS cr_internal,
|
|
|
863 |
NULL AS cr_external,
|
|
|
864 |
sp.fullname AS submitter,
|
|
|
865 |
si.submit_date,
|
|
|
866 |
ow.fullname AS owner,
|
|
|
867 |
ap.fullname AS approver
|
|
|
868 |
FROM release_manager.CQ_software_issue si INNER JOIN
|
|
|
869 |
release_manager.CQ_statedef sdef ON si.state = sdef.id INNER JOIN
|
|
|
870 |
release_manager.CQ_users sp ON si.submitter = sp.dbid INNER JOIN
|
|
|
871 |
release_manager.CQ_users ow ON si.owner = ow.dbid INNER JOIN
|
|
|
872 |
release_manager.CQ_users ap ON si.approver = ap.dbid
|
|
|
873 |
WHERE si.dbid IN ( __DEVIiss__ )
|
|
|
874 |
ORDER BY iss_num ASC
|
|
|
875 |
END_SQL
|
|
|
876 |
|
|
|
877 |
my @items = qw(
|
|
|
878 |
iss_uid
|
|
|
879 |
iss_db
|
|
|
880 |
iss_id
|
|
|
881 |
iss_num
|
|
|
882 |
summary
|
|
|
883 |
status
|
|
|
884 |
priority
|
|
|
885 |
releaseinfo
|
|
|
886 |
issue_type
|
|
|
887 |
release_part1
|
|
|
888 |
release_part2
|
|
|
889 |
release_part3
|
|
|
890 |
project
|
|
|
891 |
product
|
|
|
892 |
package_ref
|
|
|
893 |
notes_log
|
|
|
894 |
description
|
|
|
895 |
release_id
|
|
|
896 |
client_ref
|
|
|
897 |
severity
|
|
|
898 |
cr_internal
|
|
|
899 |
cr_external
|
|
|
900 |
submitter
|
|
|
901 |
submit_date
|
|
|
902 |
owner
|
|
|
903 |
approver
|
|
|
904 |
);
|
|
|
905 |
|
|
|
906 |
#
|
|
|
907 |
# Create a list of issues to extract
|
|
|
908 |
# Create a part of an 'in ( xxx xxx )' clause
|
|
|
909 |
# Push a dummy entry (-1) to ensure the list is never empty
|
|
|
910 |
#
|
|
|
911 |
my @inList;
|
|
|
912 |
push @inList, -1;
|
|
|
913 |
foreach my $entry ( keys %ClearQuestIssueData) {
|
|
|
914 |
push @inList, $ClearQuestIssueData{$entry}{iss_id};
|
|
|
915 |
}
|
|
|
916 |
|
|
|
917 |
my $inList = join(',',sort @inList);
|
|
|
918 |
|
|
|
919 |
#
|
|
|
920 |
# Insert data into the SQL string
|
|
|
921 |
#
|
|
|
922 |
$m_sqlstr =~ s~__enumCLEARQUEST_DEVI_ID__~4~g;
|
|
|
923 |
$m_sqlstr =~ s~__DEVIiss__~$inList~;
|
|
|
924 |
|
|
|
925 |
#
|
|
|
926 |
# Perform the query
|
|
|
927 |
# Merge the information from the ClearQuest Database into the hash of data from RM
|
|
|
928 |
#
|
|
|
929 |
performSqlQueryCallback($fname,
|
|
|
930 |
$m_sqlstr,
|
|
|
931 |
sub {
|
|
|
932 |
my $pHash = \%{$ClearQuestIssueData{$_[0][0]}} ;
|
|
|
933 |
populateHash( $pHash, $_[0], \@items);
|
|
|
934 |
push @ClearQuestIssues, $pHash;
|
|
|
935 |
}
|
|
|
936 |
);
|
|
|
937 |
|
|
|
938 |
#DebugDumpData("ClearQuestIssueData", \%ClearQuestIssueData);
|
|
|
939 |
#DebugDumpData("ClearQuestIssues", \@ClearQuestIssues);
|
|
|
940 |
}
|
|
|
941 |
|
|
|
942 |
#-------------------------------------------------------------------------------
|
|
|
943 |
# Function : cleanIssueTest
|
|
|
944 |
#
|
|
|
945 |
# Description : Clean up multi-line issue text
|
|
|
946 |
#
|
|
|
947 |
# Inputs : Text to clean
|
|
|
948 |
#
|
|
|
949 |
# Returns : Cleaned text
|
|
|
950 |
#
|
|
|
951 |
sub cleanIssueTest
|
|
|
952 |
{
|
|
|
953 |
my ($data) = @_;
|
|
|
954 |
#
|
|
|
955 |
# Clean multiline items
|
|
|
956 |
#
|
|
|
957 |
if ($data && $data =~ m~\n|\r~)
|
|
|
958 |
{
|
|
|
959 |
$data =~ tr~\r~\n~;
|
|
|
960 |
$data =~ tr~\n~\n~s;
|
|
|
961 |
$data =~ s~\n~<br>~g;
|
|
|
962 |
$data =~ s~<br><br>~<br>~gi;
|
|
|
963 |
}
|
|
|
964 |
return $data;
|
|
|
965 |
}
|
|
|
966 |
|
|
|
967 |
#-------------------------------------------------------------------------------
|
|
|
968 |
# Function : GetJiraIssues
|
|
|
969 |
#
|
|
|
970 |
# Description : Get the Jira issues for the current package
|
|
|
971 |
# Extract data from the Jira REST API
|
|
|
972 |
#
|
|
|
973 |
# Inputs :
|
|
|
974 |
#
|
|
|
975 |
# Returns :
|
|
|
976 |
#
|
|
|
977 |
sub GetJiraIssues
|
|
|
978 |
{
|
|
|
979 |
if (@JiraIssueList)
|
|
|
980 |
{
|
|
|
981 |
#
|
|
|
982 |
# Build up a JSON request to be posted to Jira
|
|
|
983 |
#
|
|
|
984 |
my $jsonRequest;
|
|
|
985 |
$jsonRequest->{jql} = "key in (".join(',', @JiraIssueList).")";
|
|
|
986 |
$jsonRequest->{startAt} = 0;
|
|
|
987 |
$jsonRequest->{maxResults} = scalar @JiraIssueList;
|
|
|
988 |
$jsonRequest->{validateQuery} = "false";
|
|
|
989 |
@{$jsonRequest->{fields}} = qw(key summary status priority issuetype resolution
|
|
|
990 |
description created resolutiondate project reporter
|
|
|
991 |
components assignee);
|
|
|
992 |
|
|
|
993 |
my $json_text = to_json ($jsonRequest );
|
|
|
994 |
|
|
|
995 |
#
|
|
|
996 |
# Issue the Query
|
|
|
997 |
# Tried to get LWP to do the Basic Authorization - but no joy
|
|
|
998 |
# Create the header entry my self
|
|
|
999 |
#
|
|
|
1000 |
my $rv;
|
|
|
1001 |
my $ua = LWP::UserAgent->new( timeout => 30 );
|
|
|
1002 |
$rv = $ua->post( $ENV{GBE_JIRA_URL}. "/rest/api/2/search",
|
|
|
1003 |
'Authorization' => 'Basic ' . encode_base64(join(':',$ENV{GBE_JIRA_USERNAME}, $ENV{GBE_JIRA_PASSWORD})),
|
|
|
1004 |
'Content-Type' => 'application/json',
|
|
|
1005 |
'Content' => $json_text,
|
|
|
1006 |
);
|
|
|
1007 |
|
|
|
1008 |
unless ($rv->is_success) {
|
|
|
1009 |
DebugDumpData("Jira Request", $rv);
|
|
|
1010 |
Error("Jira Issue Access:", $rv->status_line);
|
|
|
1011 |
}
|
|
|
1012 |
my $rx_json = from_json($rv->content);
|
|
|
1013 |
|
|
|
1014 |
#
|
|
|
1015 |
# Extract Issue information from the resultant json (now a hash)
|
|
|
1016 |
#
|
|
|
1017 |
foreach my $entry ( @{$rx_json->{'issues'}}) {
|
|
|
1018 |
my %data;
|
|
|
1019 |
|
|
|
1020 |
$data{'priority'} = $entry->{fields}{priority}{name};
|
|
|
1021 |
$data{'summary'} = cleanIssueTest($entry->{fields}{summary});
|
|
|
1022 |
$data{'description'} = cleanIssueTest($entry->{fields}{description});
|
|
|
1023 |
$data{'created'} = $entry->{fields}{created};
|
|
|
1024 |
$data{'reporter'} = $entry->{fields}{reporter}{displayName};
|
|
|
1025 |
$data{'reporter_email'} = $entry->{fields}{reporter}{emailAddress};
|
|
|
1026 |
$data{'status'} = $entry->{fields}{status}{name};
|
|
|
1027 |
$data{'resolution'} = $entry->{fields}{resolution}{name};
|
|
|
1028 |
$data{'resolutiondate'} = $entry->{fields}{resolutiondate};
|
|
|
1029 |
$data{'type'} = $entry->{fields}{issuetype}{name};
|
|
|
1030 |
$data{'url'} = $entry->{self};
|
|
|
1031 |
$data{'key'} = $entry->{key};
|
|
|
1032 |
$data{'project'} = $entry->{fields}{project}{name};
|
|
|
1033 |
$data{'category'} = $entry->{fields}{projectCategory}{name};
|
|
|
1034 |
$data{'assignee'} = $entry->{fields}{assignee}{displayName};
|
|
|
1035 |
$data{'assignee_email'} = $entry->{fields}{assignee}{emailAddress};
|
|
|
1036 |
|
|
|
1037 |
foreach my $item ( @{$entry->{fields}{components}} ) {
|
|
|
1038 |
push @{$data{'category'}}, $item->{name};
|
|
|
1039 |
}
|
|
|
1040 |
push @JiraIssues, \%data;
|
|
|
1041 |
}
|
|
|
1042 |
}
|
|
|
1043 |
}
|
|
|
1044 |
|
|
|
1045 |
|
|
|
1046 |
#-------------------------------------------------------------------------------
|
|
|
1047 |
# Documentation
|
|
|
1048 |
#
|
|
|
1049 |
|
|
|
1050 |
=pod
|
|
|
1051 |
|
|
|
1052 |
=for htmltoc SYSUTIL::
|
|
|
1053 |
|
|
|
1054 |
=head1 NAME
|
|
|
1055 |
|
|
|
1056 |
jats_get_releasenote_data - Get Release Note Data
|
|
|
1057 |
|
|
|
1058 |
=head1 SYNOPSIS
|
|
|
1059 |
|
|
|
1060 |
jats get_releasenote_data [options]
|
|
|
1061 |
|
|
|
1062 |
Options:
|
|
|
1063 |
-help - Brief help message
|
|
|
1064 |
-help -help - Detailed help message
|
|
|
1065 |
-man - Full documentation
|
|
|
1066 |
-verbose - Display additional progress messages
|
|
|
1067 |
-pvid=nn - PVID of package to process
|
|
|
1068 |
-outfile=name - [Optional] Name of the output XML file
|
|
|
1069 |
|
|
|
1070 |
|
|
|
1071 |
=head1 OPTIONS
|
|
|
1072 |
|
|
|
1073 |
=over 8
|
|
|
1074 |
|
|
|
1075 |
=item B<-help>
|
|
|
1076 |
|
|
|
1077 |
Print a brief help message and exits.
|
|
|
1078 |
|
|
|
1079 |
=item B<-help -help>
|
|
|
1080 |
|
|
|
1081 |
Print a detailed help message with an explanation for each option.
|
|
|
1082 |
|
|
|
1083 |
=item B<-man>
|
|
|
1084 |
|
|
|
1085 |
Prints the manual page and exits.
|
|
|
1086 |
|
|
|
1087 |
=item B<-pvid=nn>
|
|
|
1088 |
|
|
|
1089 |
This option provides identifies the PackageVersion to be processed.
|
|
|
1090 |
|
|
|
1091 |
This option is mandatory.
|
|
|
1092 |
|
|
|
1093 |
=item B<-outfile=name>
|
|
|
1094 |
|
|
|
1095 |
This option specifies the output file name.
|
|
|
1096 |
|
|
|
1097 |
If not provided by the user the output filename will be created in the current directory
|
|
|
1098 |
and it will be named after the package name and package version.
|
|
|
1099 |
|
|
|
1100 |
If the filename does not end in .xml, then .xml will be appended to the file name.
|
|
|
1101 |
|
|
|
1102 |
=back
|
|
|
1103 |
|
|
|
1104 |
=head1 DESCRIPTION
|
|
|
1105 |
|
|
|
1106 |
This utility program is used to extract sufficient information from Release Manager and other
|
|
|
1107 |
associated databases so that a Release Note can be created.
|
|
|
1108 |
|
|
|
1109 |
The extracted data is stored in an XML format. The intent is that XSLT will be used to create
|
|
|
1110 |
an HTML based release note.
|
|
|
1111 |
|
|
|
1112 |
|
|
|
1113 |
=head1 EXAMPLE
|
|
|
1114 |
|
|
|
1115 |
=head2 jats get_releasenote_data -pvid=983058 -outfile=tmpdata.xml
|
|
|
1116 |
|
|
|
1117 |
This will locate a package-version with an id of 983058, extrat required information and create
|
|
|
1118 |
an XML file called tmpdata.xml.
|
|
|
1119 |
|
|
|
1120 |
=cut
|