File Coverage

blib/lib/App/Kritika.pm
Criterion Covered Total %
statement 55 67 82.0
branch 13 32 40.6
condition 3 7 42.8
subroutine 7 9 77.7
pod 0 2 0.0
total 78 117 66.6


line stmt bran cond sub pod time code
1             package App::Kritika;
2              
3 1     1   670 use strict;
  1         2  
  1         22  
4 1     1   3 use warnings;
  1         1  
  1         27  
5              
6             our $VERSION = '0.05';
7              
8 1     1   4 use JSON ();
  1         1  
  1         13  
9 1     1   3 use Cwd qw(abs_path);
  1         1  
  1         40  
10 1     1   555 use HTTP::Tiny;
  1         30693  
  1         731  
11              
12             sub new {
13 4     4 0 18852 my $class = shift;
14 4         19 my (%params) = @_;
15              
16 4         6 my $self = {};
17 4         5 bless $self, $class;
18              
19 4   50     16 $self->{base_url} = $params{base_url} || 'https://kritika.io';
20 4 50       9 $self->{token} = $params{token} or die 'token required';
21 4         5 $self->{root} = $params{root};
22              
23 4   33     18 $self->{ua} = $params{ua} || HTTP::Tiny->new;
24              
25 4         14 $self->{diff_ref} = $params{diff_ref};
26 4         7 $self->{diff_snapshot} = $params{diff_snapshot};
27 4         6 $self->{diff_branch} = $params{diff_branch};
28              
29 4         8 $self->{branch} = $params{branch};
30 4 50       7 $self->{branch} = $self->_detect_branch unless defined $self->{branch};
31              
32 4         5 $self->{revision} = $params{revision};
33             $self->{revision} = $self->_detect_revision
34 4 50       5 unless defined $self->{revision};
35              
36 4         12 return $self;
37             }
38              
39             sub validate {
40 4     4 0 532 my $self = shift;
41 4         6 my (@paths) = @_;
42              
43 4         7 my $files = [];
44              
45 4         7 foreach my $path (@paths) {
46 4         198 $path = abs_path($path);
47              
48 4         8 my $content = do {
49 4         11 local $/;
50 4 50       107 open my $fh, '<', $path or die "Can't open file '$path': $!";
51 4         96 <$fh>;
52             };
53              
54 4 50       13 if ( my $root = $self->{root} ) {
55 4         161 $root = abs_path($root);
56 4         72 $path =~ s{^$root}{};
57 4         13 $path =~ s{^/}{};
58             }
59              
60 4         27 push @$files,
61             {
62             path => $path,
63             content => $content
64             };
65             }
66              
67 4         6 my $ua = $self->{ua};
68              
69             my $response = $ua->post(
70             "$self->{base_url}/validate",
71             {
72             headers => {
73             Authorization => 'Token ' . $self->{token},
74             Accept => 'application/json',
75             'X-Version' => $VERSION,
76             },
77             content => JSON->new->canonical(1)->encode(
78             {
79             branch => $self->{branch},
80             revision => $self->{revision},
81             files => $files,
82             $self->{diff_ref}
83             ? ( diff_ref =>
84             $self->_detect_revision( $self->{diff_ref} ) )
85             : (),
86             $self->{diff_snapshot}
87             ? ( diff_snapshot => $self->{diff_snapshot} )
88             : (),
89             $self->{diff_branch}
90             ? ( diff_branch => $self->{diff_branch} )
91 4 50       127 : (),
    50          
    50          
92             }
93             )
94             }
95             );
96              
97 4 100       215 if ( $response->{status} eq '599' ) {
98 1         2 my $content = $response->{content};
99 1 50       3 $content = substr( $content, 0, 64 ) . '[...]' if length $content > 64;
100 1         9 die "Internal error: $response->{status} $content";
101             }
102              
103 3 100       7 unless ( $response->{success} ) {
104             my $message =
105 1   50     2 eval { JSON::decode_json( $response->{content} )->{message} }
106             || 'Unknown Error';
107              
108 1         7 die "Remote error: $response->{status} $response->{reason}: $message\n";
109             }
110              
111 2         17 return JSON::decode_json( $response->{content} );
112             }
113              
114             sub _detect_branch {
115 0     0     my $self = shift;
116              
117 0 0         die "Doesn't look like a git repository\n" unless -d "$self->{root}/.git";
118              
119 0           my ($branch) = `cd $self->{root}; git branch` =~ m/^\*\s+(.*)$/m;
120 0 0         die "Can't detect current branch\n" unless $branch;
121              
122 0           return $branch;
123             }
124              
125             sub _detect_revision {
126 0     0     my $self = shift;
127 0           my ($ref) = @_;
128              
129 0 0         $ref = 'HEAD' unless defined $ref;
130              
131 0 0         die "Doesn't look like a git repository\n" unless -d "$self->{root}/.git";
132              
133 0           my ($revision) =
134             `cd $self->{root}; git rev-parse '$ref'` =~ m/([a-f0-9]+)/i;
135 0 0         die "Can't detect current revision\n" unless $revision;
136              
137 0           return $revision;
138             }
139              
140             1;
141             __END__