Removed /usr/local from CDPATH
[clearscm.git] / JIRA / importComments.pl
1 #!/usr/bin/perl
2 use strict;
3 use warnings;
4
5 =pod
6
7 =head1 NAME importComments.pl
8
9 This will import the comments from Bugzilla and update the corresponding JIRA
10 Issues.
11
12 =head1 VERSION
13
14 =over
15
16 =item Author
17
18 Andrew DeFaria <Andrew@ClearSCM.com>
19
20 =item Revision
21
22 $Revision: #1 $
23
24 =item Created
25
26 Thu Mar 20 10:11:53 PDT 2014
27
28 =item Modified
29
30 $Date: 2014/05/23 $
31
32 =back
33
34 =head1 SYNOPSIS
35
36   $ importComments.pl [-bugzillaserver <bugshost>] [-login <login email>]
37                       [-jiraserver <server>]
38                       [-username <username>] [-password <password>] 
39                       [-bugids bugid,bugid,... | -file <filename>] 
40                       [-[no]exec]
41                       [-verbose] [-help] [-usage]
42
43   Where:
44
45     -v|erbose:       Display progress output
46     -he|lp:          Display full help
47     -usa|ge:         Display usage
48     -[no]e|xec:      Whether or not to update JIRA. -noexec says only 
49                      tell me what you would have updated.
50     -use|rname:      Username to log into JIRA with (Default: jira-admin)
51     -p|assword:      Password to log into JIRA with (Default: jira-admin's 
52                      password)
53     -bugzillaserver: Machine where Bugzilla lives (Default: bugs-dev)
54     -jiraserver:     Machine where Jira lives (Default: jira-dev)
55     -bugi|ds:        Comma separated list of BugIDs to process
56     -f|ile:          File of BugIDs, one per line
57
58 =head1 DESCRIPTION
59
60 This will import the comments from Bugzilla and update the corresponding JIRA
61 Issues.
62
63 =cut
64
65 use FindBin;
66 use lib "$FindBin::Bin/lib";
67
68 $| = 1;
69
70 use DBI;
71 use Display;
72 use Logger;
73 use TimeUtils;
74 use Utils;
75 use JIRAUtils;
76 use BugzillaUtils;
77
78 use Getopt::Long; 
79 use Pod::Usage;
80
81 our %opts = (
82   exec           => 0,
83   bugzillaserver => $ENV{BUGZILLASERVER} || 'bugs-dev',
84   jiraserver     => $ENV{JIRASERVER}     || 'jira-dev:8081',
85   username       => $ENV{USERNAME},
86   password       => $ENV{PASSWORD},
87   usage          => sub { pod2usage },
88   help           => sub { pod2usage (-verbose => 2)},
89   verbose        => sub { set_verbose },
90   quiet          => 0,
91 );
92
93 our ($log, %total);
94
95 sub sanitize ($) {
96   my ($str) = @_;
97
98   my $p4web    = 'http://p4web.audience.local:8080/@md=d&cd=//&c=vLW@/';
99   my $bugzilla = 'http://bugs.audience.com/show_bug.cgi?id=';
100
101   # 0x93 (147) and 0x94 (148) are "smart" quotes
102   $str =~ s/[\x93\x94]/"/gm;
103   # 0x91 (145) and 0x92 (146) are "smart" singlequotes
104   $str =~ s/[\x91\x92]/'/gm;
105   # 0x96 (150) and 0x97 (151) are emdashes
106   $str =~ s/[\x96\x97]/--/gm;
107   # 0x85 (133) is an ellipsis
108   $str =~ s/\x85/.../gm;
109   # 0x95 &bull; replacement for unordered list
110   $str =~ s/\x95/*/gm;
111
112   # Make P4Web links for "CL (\d{3,6}+)"
113   $str =~ s/CL\s*(\d{3,6}+)/CL \[$1|${p4web}$1\?ac=10\]/igm;
114
115   # Make Bugzilla links for "Bug ID (\d{1,5}+)"
116   $str =~ s/Bug\s*ID\s*(\d{1,5}+)/Bug \[$1|${bugzilla}$1\]/igm;
117
118   # Make Bugzilla links for "Bug # (\d{1,5}+)"
119   $str =~ s/Bug\s*#\s*(\d{1,5}+)/Bug \[$1|${bugzilla}$1\]/igm;
120
121   # Make Bugzilla links for "Bug (\d{1,5}+)"
122   $str =~ s/Bug\s*(\d{1,5}+)/Bug \[$1|${bugzilla}$1\]/igm;
123
124   # Convert bug URLs to be more proper
125   $str =~ s/https\:\/\/bugs\.audience\.com\/show_bug\.cgi\?id=(\d{1,5}+)/Bug \[$1|${bugzilla}$1\]/igm;
126
127   return $str;
128 } # sanitize
129
130 sub addComments ($$) {
131   my ($jiraIssue, $bugid) = @_;
132   
133   my @comments = @{getBugComments ($bugid)};
134   
135   # Note: In Bugzilla the first comment is considered the description.
136   my $description = shift @comments;
137   
138   my $result = addDescription $jiraIssue, sanitize $description;
139   
140   $total{'Descriptions added'}++;
141   
142   return $result if $result =~ /^Unable to add comment/;
143    
144   # Process the remaining comments  
145   for (@comments) {
146     $result = addJIRAComment $jiraIssue, sanitize $_;
147     
148     if ($result =~ /Comment added/) {
149       $total{'Comments imported'}++;
150     } else {
151       return $result;
152     } # if
153   } # for
154   
155   $result = '' unless $result;
156   
157   return $result;
158 } # addComments
159
160 sub main () {
161   my $startTime = time;
162
163   GetOptions (
164     \%opts,
165     'verbose',
166     'usage',
167     'help',
168     'exec!',
169     'quiet',
170     'username=s',
171     'password=s',
172     'bugids=s@',
173     'file=s',
174     'jiraserver=s',
175     'bugzillaserver=s',
176     'linkbugzilla',
177     'relinkbugzilla'
178   ) or pod2usage;
179   
180   $log = Logger->new;
181
182   if ($opts{file}) {
183     open my $file, '<', $opts{file} 
184       or $log->err ("Unable to open $opts{file} - $!", 1);
185
186     $opts{bugids} = [<$file>];
187
188     chomp @{$opts{bugids}};
189   } else {
190     my @bugids;
191
192     push @bugids, (split /,/, join (',', $_)) for (@{$opts{bugids}}); 
193
194     $opts{bugids} = [@bugids];
195   } # if
196
197   pod2usage 'Must specify -bugids <bugid>[,<bugid>,...] or -file <filename>'
198     unless $opts{bugids};
199
200   openBugzilla $opts{bugzillaserver}
201     or $log->err ("Unable to connect to $opts{bugzillaserver}", 1);
202
203   Connect2JIRA ($opts{username}, $opts{password}, $opts{jiraserver})
204     or $log->err ("Unable to connect to $opts{jiraserver}", 1);
205
206   $log->msg ("Processing comments");
207
208   for (@{$opts{bugids}}) {
209     my $jiraIssue = findIssue $_;
210
211     if ($jiraIssue =~ /^[A-Z]{1,5}-\d+$/) {
212       my $result = addComments $jiraIssue, $_;
213
214       if ($result =~ /^Unable/) {
215         $total{'Comment failures'}++;
216
217         $log->err ("Unable to add comments for $jiraIssue ($_)\n$result");
218       } elsif ($result =~ /^Comment added/) {
219         $log->msg ("Added comments for $jiraIssue ($_)");
220       } elsif ($result =~ /^Would have linked/) {
221         $total{'Comments would be added'}++;
222       } # if
223     } else {
224       $total{'Missing JIRA Issues'}++;
225
226       $log->err ("Unable to find JIRA Issue for Bug $_");
227     } # if
228   } # for
229
230   display_duration $startTime, $log;
231
232   Stats (\%total, $log) unless $opts{quiet};
233
234   return 0;
235 } # main
236
237 exit main;