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   145654 use Moo;
  2         23780  
  2         10  
10 2     2   3258 use strict;
  2         6  
  2         54  
11 2     2   11 use warnings;
  2         6  
  2         52  
12 2     2   11 use Carp;
  2         4  
  2         116  
13 2     2   1123 use namespace::clean;
  2         24243  
  2         13  
14 2     2   1720 use English qw/ -no_match_vars /;
  2         7454  
  2         14  
15 2     2   2387 use WWW::Mechanize;
  2         318393  
  2         100  
16 2     2   1460 use Type::Tiny;
  2         32582  
  2         85  
17 2     2   1246 use Types::Standard -types;
  2         125970  
  2         23  
18 2     2   10161 use URI;
  2         6  
  2         52  
19 2     2   12 use WWW::Mechanize;
  2         5  
  2         41  
20 2     2   1330 use JSON;
  2         20502  
  2         12  
21 2     2   277 use Try::Tiny;
  2         5  
  2         2557  
22              
23             our $VERSION = '0.10';
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 6717 my ($self) = @_;
44              
45 2         11 $self->mech->add_header(accept => 'application/json');
46              
47 2 100       64 if ($self->url =~ m{/$}) {
48 1         49 my $url = $self->url;
49 1         11 $url =~ s{/$}{};
50 1         16 $self->url($url);
51             }
52              
53 2         73 $self->_get_commands();
54              
55 2         9 my $server = $self->_get('server/index');
56 2         72 $self->version($server->{version});
57             }
58              
59             sub _get_commands {
60 2     2   6 my ($self) = @_;
61              
62 2         7 my $list = $self->_get('webservices/list', include_internals => 'true');
63              
64 2         2417 my %commands;
65 2         4 for my $ws (@{ $list->{webServices}}) {
  2         7  
66 62         629 my $name = $ws->{path};
67 62         192 $name =~ s{^api/}{};
68              
69 62         94 for my $action (@{ $ws->{actions} }) {
  62         117  
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         1724 };
77             }
78             }
79              
80 2         383 $self->commands(\%commands);
81             }
82              
83             our $AUTOLOAD;
84             sub AUTOLOAD {
85 7     7   6055 my ($self, %params) = @_;
86              
87 7         15 my $api = $AUTOLOAD;
88 7         44 $api =~ s{.*::}{};
89 7         23 $api =~ s{_}{/}g;
90              
91 7 100       75 return if $api eq 'DESTROY';
92              
93 6 100       26 if (!$self->commands->{$api}) {
94 1         25 confess "Unknown command $api for SonarQube " . $self->version . '!';
95             }
96              
97 5         111 my $url = $self->url;
98 5         38 $url =~ s{//(?:[^@]+[@])}{//};
99              
100 5 100 100     85 if ($self->username && $self->password) {
101 2         101 $self->mech->credentials(_url_encode($self->username), _url_encode($self->password));
102 2         37 my ($user, $pass) = map {_url_encode($_)} ($self->username, $self->password);
  4         49  
103 2         13 $url =~ s{//}{//$user\:$pass\@};
104             }
105 5         124 $self->url($url);
106              
107 5         158 my $result;
108             try {
109 5 100   5   256 $result = $self->commands->{$api}{post} ? $self->_post($api, %params) : $self->_get($api, %params);
110             }
111             catch {
112 1     1   36 local $Data::Dumper::Indent = 0;
113 1         668 require Data::Dumper;
114 1         6165 my $args = Data::Dumper::Dumper( \%params );
115 1         75 $args = s/^\$VAR\d\s+=\s+//;
116 1         208 confess "Errored trying $AUTOLOAD($args)\n$_\n";
117 5         40 };
118              
119 4         145 return $result;
120             }
121              
122             sub _get {
123 6     6   18 my ($self, $api, %params) = @_;
124              
125 6         16 my $mech = $self->mech;
126 6         131 my $uri = URI->new($self->url . '/api/' . $api);
127 6         8524 $uri->query_form(%params);
128              
129 6         470 $mech->get($uri);
130              
131 6   100     158 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         76 my $uri = URI->new($self->url . '/api/' . $api);
139              
140 3         244 $mech->post($uri, \%params);
141              
142 3   100     56 return decode_json($mech->content || '{}');
143             }
144              
145             sub _url_encode {
146 9     9   831 my ($str) = @_;
147 9         24 $str =~ s/(\W)/sprintf('%%%x',ord($1))/eg;
  1         7  
148 9         55 return $str;
149             };
150              
151             1;
152              
153             __END__