1 # This is Debbugs.pm from the Debian devscripts package
3 # Copyright (C) 2008 Adam D. Barratt
4 # select() is Copyright (C) 2007 Don Armstrong
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with this program; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 package Devscripts::Debbugs;
24 =item select [key:value ...]
26 Uses the SOAP interface to output a list of bugs which match the given
27 selection requirements.
29 The following keys are allowed, and may be given multiple times.
43 E-mail address of the maintainer.
47 E-mail address of the submitter.
59 Tags applied to the bug. If I<users> is specified, may include
60 usertags in addition to the standard tags.
68 Address of someone who sent mail to the log.
72 Bugs which affect this package.
76 List of bugs to search within.
80 Users to use when looking up usertags.
84 Whether to search archived bugs or normal bugs; defaults to 0
85 (i.e. only search normal bugs). As a special case, if archive is
86 'both', both archived and unarchived bugs are returned.
90 For example, to select the set of bugs submitted by
91 jrandomdeveloper@example.com and tagged wontfix, one would use
93 select("submitter:jrandomdeveloper@example.com", "tag:wontfix")
100 my $soapurl='Debbugs/SOAP/1';
101 our $btsurl='http://bugs.debian.org/';
106 if ($btsurl =~ m%^https?://(.*)/?$%) {
107 $soapproxyurl = $btsurl . '/';
109 $soapproxyurl = 'http://' . $btsurl . '/';
111 $soapproxyurl =~ s%//$%/%;
112 $soapproxyurl .= 'cgi-bin/soap.cgi';
113 my $soap = SOAP::Lite->uri($soapurl)->proxy($soapproxyurl);
115 $soap->transport->env_proxy();
116 $soap->on_fault(\&getSOAPError);
123 return ($soap_broken ? 0 : 1) if defined $soap_broken;
129 if ($@ =~ m%^Can't locate SOAP/%) {
130 $soap_broken="the libsoap-lite-perl package is not installed";
132 $soap_broken="couldn't load SOAP::Lite: $@";
138 return ($soap_broken ? 0 : 1);
142 my ($soap, $result) = @_;
145 $err = $result->faultstring;
147 $err = $soap->transport->status;
152 return new SOAP::SOM;
156 die "Couldn't run usertags: $soap_broken\n" unless have_soap();
160 my $soap = init_soap();
161 my $usertags = $soap->get_usertag(@_);
163 if (@errors or not defined $usertags) {
164 my $error = join("\n", @errors);
165 die "Error retrieving usertags from SOAP server: $error\n";
168 my $result = $usertags->result();
170 if (@errors or not defined $result) {
171 my $error = join("\n", @errors);
172 die "Error retrieving usertags from SOAP server: $error\n";
179 die "Couldn't run select: $soap_broken\n" unless have_soap();
181 my %valid_keys = (package => 'package',
186 maintainer => 'maint',
187 submitter => 'submitter',
196 distribution => 'dist',
198 archive => 'archive',
199 severity => 'severity',
200 correspondent => 'correspondent',
201 affects => 'affects',
204 my %search_parameters;
205 my $soap = init_soap();
206 for my $arg (@args) {
207 my ($key,$value) = split /:/, $arg, 2;
209 if (exists $valid_keys{$key}) {
210 if ($valid_keys{$key} eq 'archive') {
211 $search_parameters{$valid_keys{$key}} = $value
214 push @{$search_parameters{$valid_keys{$key}}},
217 } elsif ($key =~/users?$/) {
218 $users{$value} = 1 if $value;
220 warn "select(): Unrecognised key: $key\n";
224 for my $user (keys %users) {
225 my $ut = usertags($user);
226 next unless defined $ut and $ut ne "";
227 for my $tag (keys %{$ut}) {
228 push @{$usertags{$tag}},
232 my $bugs = $soap->get_bugs(%search_parameters,
233 (keys %usertags)?(usertags=>\%usertags):()
236 if (@errors or not defined $bugs) {
237 my $error = join("\n", @errors);
238 die "Error while retrieving bugs from SOAP server: $error\n";
241 my $result = $bugs->result();
242 if (@errors or not defined $result) {
243 my $error = join( "\n", @errors );
244 die "Error while retrieving bugs from SOAP server: $error\n";
251 die "Couldn't run status: $soap_broken\n" unless have_soap();
254 my $soap = init_soap();
256 my $bugs = $soap->get_status(@args);
258 if (@errors or not defined $bugs) {
259 my $error = join("\n", @errors);
260 die "Error while retrieving bug statuses from SOAP server: $error\n";
263 my $result = $bugs->result();
265 if (@errors or not defined $result) {
266 my $error = join("\n", @errors);
267 die "Error while retrieving bug statuses from SOAP server: $error\n";
274 die "Couldn't run versions: $soap_broken\n" unless have_soap();
277 my %valid_keys = (package => 'package',
282 binary => 'no_source_arch',
283 notsource => 'no_source_arch',
284 archs => 'return_archs',
285 displayarch => 'return_archs',
288 my %search_parameters;
292 for my $arg (@args) {
293 my ($key,$value) = split /:/, $arg, 2;
295 if ($key =~ /^arch(itecture)?$/) {
297 } elsif ($key =~ /^dist(ribution)?$/) {
299 } elsif (exists $valid_keys{$key}) {
300 $search_parameters{$valid_keys{$key}} = $value;
304 $search_parameters{arch} = \@archs if @archs;
305 $search_parameters{dist} = \@dists if @dists;
307 my $soap = init_soap();
309 my $versions = $soap->get_versions(%search_parameters);
311 if (@errors or not defined $versions) {
312 my $error = join("\n", @errors);
313 die "Error while retrieving package versions from SOAP server: $error\n";
316 my $result = $versions->result();
318 if (@errors or not defined $result) {
319 my $error = join("\n", @errors);
320 die "Error while retrieivng package versions from SOAP server: $error";
326 sub versions_with_arch {
327 die "Couldn't run versions_with_arch: $soap_broken\n" unless have_soap();
330 my $versions = versions(@args, 'displayarch:1');
332 if (not defined $versions) {
333 die "Error while retrieivng package versions from SOAP server: $@";
340 die "Couldn't run newest_bugs: $soap_broken\n" unless have_soap();
341 my $count = shift || '';
343 return if $count !~ /^\d+$/;
345 my $soap = init_soap();
347 my $bugs = $soap->newest_bugs($count);
349 if (@errors or not defined $bugs) {
350 my $error = join("\n", @errors);
351 die "Error while retrieving newest bug list from SOAP server: $error";
354 my $result = $bugs->result();
356 if (@errors or not defined $result) {
357 my $error = join("\n", @errors);
358 die "Error while retrieving newest bug list from SOAP server: $error";
364 # debbugs currently ignores the $msg_num parameter
365 # but eventually it might not, so we support passing it
368 die "Couldn't run bug_log: $soap_broken\n" unless have_soap();
370 my $bug = shift || '';
373 return if $bug !~ /^\d+$/;
375 my $soap = init_soap();
377 my $log = $soap->get_bug_log($bug, $message);
379 if (@errors or not defined $log) {
380 my $error = join("\n", @errors);
381 die "Error while retrieving bug log from SOAP server: $error\n";
384 my $result = $log->result();
386 if (@errors or not defined $result) {
387 my $error = join("\n", @errors);
388 die "Error while retrieving bug log from SOAP server: $error\n";
394 sub binary_to_source {
395 die "Couldn't run binary_to_source: $soap_broken\n"
398 my $soap = init_soap();
404 return if not defined $binpkg or not defined $binver;
406 my $mapping = $soap->binary_to_source($binpkg, $binver, $arch);
408 if (@errors or not defined $mapping) {
409 my $error = join("\n", @errors);
410 die "Error while retrieving binary to source mapping from SOAP server: $error\n";
413 my $result = $mapping->result();
415 if (@errors or not defined $result) {
416 my $error = join("\n", @errors);
417 die "Error while retrieving binary to source mapping from SOAP server: $error\n";
423 sub source_to_binary {
424 die "Couldn't run source_to_binary: $soap_broken\n"
427 my $soap = init_soap();
432 return if not defined $srcpkg or not defined $srcver;
434 my $mapping = $soap->source_to_binary($srcpkg, $srcver);
436 if (@errors or not defined $mapping) {
437 my $error = join("\n", @errors);
438 die "Error while retrieving source to binary mapping from SOAP server: $error\n";
441 my $result = $mapping->result();
443 if (@errors or not defined $result) {
444 my $error = join("\n", @errors);
445 die "Error while retrieving source to binary mapping from SOAP server: $error\n";