File Coverage

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


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   30881 use Moo;
  2         18992  
  2         8  
10 2     2   2623 use strict;
  2         2  
  2         30  
11 2     2   5 use warnings;
  2         5  
  2         37  
12 2     2   6 use Carp;
  2         3  
  2         92  
13 2     2   806 use namespace::clean;
  2         16702  
  2         5  
14 2     2   1270 use English qw/ -no_match_vars /;
  2         5534  
  2         8  
15 2     2   1860 use WWW::Mechanize;
  2         203836  
  2         82  
16 2     2   1436 use Type::Tiny;
  2         23080  
  2         59  
17 2     2   934 use Types::Standard -types;
  2         65054  
  2         16  
18 2     2   5080 use URI;
  2         2  
  2         39  
19 2     2   6 use WWW::Mechanize;
  2         2  
  2         28  
20 2     2   1095 use JSON;
  2         17048  
  2         6  
21 2     2   208 use Try::Tiny;
  2         2  
  2         2345  
22              
23             our $VERSION = 0.08;
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 4830 my ($self) = @_;
44              
45 2         11 $self->mech->add_header(accept => 'application/json');
46              
47 2 100       31 if ($self->url =~ m{/$}) {
48 1         19 my $url = $self->url;
49 1         5 $url =~ s{/$}{};
50 1         14 $self->url($url);
51             }
52              
53 2         434 $self->_get_commands();
54              
55 2         4 my $server = $self->_get('server/index');
56 2         37 $self->version($server->{version});
57             }
58              
59             sub _get_commands {
60 2     2   2 my ($self) = @_;
61              
62 2         4 my $list = $self->_get('webservices/list', include_internals => 'true');
63              
64 2         1881 my %commands;
65 2         17 for my $ws (@{ $list->{webServices}}) {
  2         6  
66 62         316 my $name = $ws->{path};
67 62         107 $name =~ s{^api/}{};
68              
69 62         37 for my $action (@{ $ws->{actions} }) {
  62         61  
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         970 };
77             }
78             }
79              
80 2         290 $self->commands(\%commands);
81             }
82              
83             our $AUTOLOAD;
84             sub AUTOLOAD {
85 6     6   4347 my ($self, %params) = @_;
86              
87 6         9 my $api = $AUTOLOAD;
88 6         24 $api =~ s{.*::}{};
89 6         12 $api =~ s{_}{/}g;
90              
91 6 50       16 return if $api eq 'DESTROY';
92              
93 6 100       18 if (!$self->commands->{$api}) {
94 1         20 confess "Unknown command $api for SonarQube " . $self->version . '!';
95             }
96              
97 5         89 my $url = $self->url;
98 5         27 $url =~ s{//(?:[^@]+[@])}{//};
99              
100 5 100 100     60 if ($self->username && $self->password) {
101 2         84 $self->mech->credentials(_url_encode($self->username), _url_encode($self->password));
102 2         31 my ($user, $pass) = map {_url_encode($_)} ($self->username, $self->password);
  4         34  
103 2         9 $url =~ s{//}{//$user\:$pass\@};
104             }
105 5         943 $self->url($url);
106              
107 5         70 my $result;
108             try {
109 5 100   5   142 $result = $self->commands->{$api}{post} ? $self->_post($api, %params) : $self->_get($api, %params);
110             }
111             catch {
112 1     1   23 local $Data::Dumper::Indent = 0;
113 1         544 require Data::Dumper;
114 1         4537 my $args = Data::Dumper::Dumper( \%params );
115 1         49 $args = s/^\$VAR\d\s+=\s+//;
116 1         176 confess "Errored trying $AUTOLOAD($args)\n$_\n";
117 5         31 };
118              
119 4         100 return $result;
120             }
121              
122             sub _get {
123 6     6   12 my ($self, $api, %params) = @_;
124              
125 6         10 my $mech = $self->mech;
126 6         104 my $uri = URI->new($self->url . '/api/' . $api);
127 6         5084 $uri->query_form(%params);
128              
129 6         236 $mech->get($uri);
130              
131 6   100     65 return decode_json($mech->content || '{}');
132             }
133              
134             sub _post {
135 3     3   6 my ($self, $api, %params) = @_;
136              
137 3         5 my $mech = $self->mech;
138 3         46 my $uri = URI->new($self->url . '/api/' . $api);
139              
140 3         139 $mech->post($uri, \%params);
141              
142 3   100     35 return decode_json($mech->content || '{}');
143             }
144              
145             sub _url_encode {
146 9     9   606 my ($str) = @_;
147 9         15 $str =~ s/(\W)/sprintf('%%%x',ord($1))/eg;
  1         6  
148 9         40 return $str;
149             };
150              
151             1;
152              
153             __END__