package Hydra::Plugin::CoverityScan;
use strict;
use warnings;
use parent 'Hydra::Plugin';
use File::Basename;
use LWP::UserAgent;
use Hydra::Helper::CatalystUtils;
sub isEnabled {
my ($self) = @_;
return defined $self->{config}->{coverityscan};
}
sub buildFinished {
my ($self, $build, $dependents) = @_;
my $cfg = $self->{config}->{coverityscan};
my @config = defined $cfg ? ref $cfg eq "ARRAY" ? @$cfg : ($cfg) : ();
my $proj;
my $jobName = showJobName $build;
foreach my $p (@config) {
next unless $jobName =~ /^$p->{jobs}$/;
next if $build->buildstatus == 4 || $build->buildstatus == 3;
$proj = $p; last;
}
return unless defined $proj;
my $project = $proj->{project};
my $email = $proj->{email};
my $token = $proj->{token};
my $scanurl = $proj->{scanurl} || "http://scan5.coverity.com/cgi-bin/upload.py";
die "coverity project name not configured" unless defined $project;
die "email must be specified for Coverity project '".$project."'"
unless defined $email;
die "access token must be specified for Coverity project '".$project."'"
unless defined $token;
my $storePath = ($build->buildoutputs)[0]->path;
my $tarballs = "$storePath/tarballs";
my $covTarball;
opendir my $tarballs_handle, $tarballs or die;
while (my $file = readdir $tarballs_handle) {
next unless $file =~ /.*-coverity-int\.(tgz|lzma|xz|bz2|zip)$/;
$covTarball = "$tarballs/$file"; last;
}
closedir $tarballs_handle;
unless (defined $covTarball) {
print STDERR "CoverityScan.pm: Coverity tarball not found in $tarballs; skipping upload...\n";
return;
}
my @exts = qw(.xz .bz2 .lzma .zip .tgz);
my ($dir, $file, $ext) = fileparse($covTarball, @exts);
my $mimetype;
if ($ext eq '.xz') { $mimetype = "application/x-xz"; }
elsif ($ext eq '.lzma') { $mimetype = "application/x-xz"; }
elsif ($ext eq '.zip') { $mimetype = "application/zip"; }
elsif ($ext eq '.bz2') { $mimetype = "application/x-bzip2"; }
elsif ($ext eq '.tgz') { $mimetype = "application/x-gzip"; }
else { die "couldn't parse extension of $covTarball"; }
die "couldn't detect mimetype of $covTarball" unless defined $mimetype;
my $pkgNameRE = "(?:(?:[A-Za-z0-9]|(?:-[^0-9]))+)";
my $versionRE = "(?:[A-Za-z0-9\.\-]+)";
my $shortName = basename($covTarball);
my $version;
$version = $2 if $shortName =~ /^($pkgNameRE)-($versionRE)-coverity-int.*$/;
die "CoverityScan.pm: Couldn't parse build version for upload! ($shortName)"
unless defined $version;
my $jobid = $build->id;
my $desc = "Hydra Coverity Build ($jobName) - $jobid:$version";
print STDERR "uploading $desc ($shortName) to Coverity Scan\n";
my $ua = LWP::UserAgent->new();
my $resp = $ua->post($scanurl,
Content_Type => 'form-data',
Content => [
project => $project,
email => $email,
token => $token,
version => $version,
description => $desc,
file => [ $covTarball, $shortName,
Content_Type => $mimetype,
],
],
);
my $results = $resp->decoded_content;
if ($results =~ /ERROR!/) {
print STDERR "CoverityScan.pm: upload error - ", $resp->decoded_content, "\n";
return;
}
unless ($results =~ /Your request has been submitted/) {
print STDERR "CoverityScan.pm: upload error, didn't find expected response - ", $resp->decoded_content, "\n";
}
}
1;