File Coverage

blib/lib/WebService/SonarQube.pm
Criterion Covered Total %
statement 98 98 100.0
branch 10 10 100.0
condition 7 7 100.0
subroutine 21 21 100.0
pod 1 1 100.0
total 137 137 100.0


line stmt bran cond sub pod time code
1             package WebService::SonarQube;
2              
3             # Created on: 2015-05-02 20:12:53
4             # Create by: Ivan Wills
5             # $Id$
6             # $Revision$, $HeadURL$, $Date$
7             # $Revision$, $Source$, $Date$
8              
9 2     2   123612 use Moo;
  2         15623  
  2         10  
10 2     2   4927 use strict;
  2         4  
  2         32  
11 2     2   8 use warnings;
  2         3  
  2         41  
12 2     2   9 use Carp;
  2         4  
  2         147  
13 2     2   618 use namespace::clean;
  2         19147  
  2         14  
14 2     2   1639 use English qw/ -no_match_vars /;
  2         6397  
  2         16  
15 2     2   1955 use WWW::Mechanize;
  2         252567  
  2         78  
16 2     2   915 use Type::Tiny;
  2         22866  
  2         73  
17 2     2   738 use Types::Standard -types;
  2         93487  
  2         23  
18 2     2   8081 use URI;
  2         8  
  2         49  
19 2     2   10 use WWW::Mechanize;
  2         3  
  2         32  
20 2     2   952 use JSON;
  2         14131  
  2         11  
21 2     2   231 use Try::Tiny;
  2         5  
  2         1665  
22              
23             our $VERSION = 0.09;
24              
25             has url => (
26             is => 'rw',
27             required => 1,
28             isa => Str,
29             );
30             has [qw/username password version/] => (
31             is => 'rw',
32             isa => Str,
33             );
34             has mech => (
35             is => 'rw',
36             default => sub { WWW::Mechanize->new(); },
37             );
38             has commands => (
39             is => 'rw',
40             );
41              
42             sub BUILD {
43 2     2 1 4612 my ($self) = @_;
44              
45 2         12 $self->mech->add_header(accept => 'application/json');
46              
47 2 100       58 if ($self->url =~ m{/$}) {
48 1         22 my $url = $self->url;
49 1         7 $url =~ s{/$}{};
50 1         14 $self->url($url);
51             }
52              
53 2         41 $self->_get_commands();
54              
55 2         8 my $server = $self->_get('server/index');
56 2         63 $self->version($server->{version});
57             }
58              
59             sub _get_commands {
60 2     2   4 my ($self) = @_;
61              
62 2         8 my $list = $self->_get('webservices/list', include_internals => 'true');
63              
64 2         1530 my %commands;
65 2         4 for my $ws (@{ $list->{webServices}}) {
  2         6  
66 62         509 my $name = $ws->{path};
67 62         149 $name =~ s{^api/}{};
68              
69 62         72 for my $action (@{ $ws->{actions} }) {
  62         92  
70             $commands{$name . '/' . $action->{key}} = {
71             name => $name . '_' . $action->{key},
72             url => $name . '/' . $action->{key},
73             internal => !!$action->{internal},
74             post => !!$action->{post},
75             description => $action->{description},
76 194         1377 };
77             }
78             }
79              
80 2         298 $self->commands(\%commands);
81             }
82              
83             our $AUTOLOAD;
84             sub AUTOLOAD {
85 7     7   4576 my ($self, %params) = @_;
86              
87 7         13 my $api = $AUTOLOAD;
88 7         32 $api =~ s{.*::}{};
89 7         48 $api =~ s{_}{/}g;
90              
91 7 100       67 return if $api eq 'DESTROY';
92              
93 6 100       20 if (!$self->commands->{$api}) {
94 1         26 confess "Unknown command $api for SonarQube " . $self->version . '!';
95             }
96              
97 5         93 my $url = $self->url;
98 5         35 $url =~ s{//(?:[^@]+[@])}{//};
99              
100 5 100 100     79 if ($self->username && $self->password) {
101 2         72 $self->mech->credentials(_url_encode($self->username), _url_encode($self->password));
102 2         29 my ($user, $pass) = map {_url_encode($_)} ($self->username, $self->password);
  4         41  
103 2         12 $url =~ s{//}{//$user\:$pass\@};
104             }
105 5         112 $self->url($url);
106              
107 5         128 my $result;
108             try {
109 5 100   5   240 $result = $self->commands->{$api}{post} ? $self->_post($api, %params) : $self->_get($api, %params);
110             }
111             catch {
112 1     1   31 local $Data::Dumper::Indent = 0;
113 1         446 require Data::Dumper;
114 1         4605 my $args = Data::Dumper::Dumper( \%params );
115 1         50 $args = s/^\$VAR\d\s+=\s+//;
116 1         221 confess "Errored trying $AUTOLOAD($args)\n$_\n";
117 5         37 };
118              
119 4         127 return $result;
120             }
121              
122             sub _get {
123 6     6   17 my ($self, $api, %params) = @_;
124              
125 6         13 my $mech = $self->mech;
126 6         115 my $uri = URI->new($self->url . '/api/' . $api);
127 6         5330 $uri->query_form(%params);
128              
129 6         333 $mech->get($uri);
130              
131 6   100     89 return decode_json($mech->content || '{}');
132             }
133              
134             sub _post {
135 3     3   9 my ($self, $api, %params) = @_;
136              
137 3         8 my $mech = $self->mech;
138 3         49 my $uri = URI->new($self->url . '/api/' . $api);
139              
140 3         197 $mech->post($uri, \%params);
141              
142 3   100     47 return decode_json($mech->content || '{}');
143             }
144              
145             sub _url_encode {
146 9     9   757 my ($str) = @_;
147 9         23 $str =~ s/(\W)/sprintf('%%%x',ord($1))/eg;
  1         6  
148 9         49 return $str;
149             };
150              
151             1;
152              
153             __END__