File Coverage

blib/lib/Test/Perl/Critic/Git.pm
Criterion Covered Total %
statement 98 99 98.9
branch 12 20 60.0
condition 9 16 56.2
subroutine 16 16 100.0
pod 2 2 100.0
total 137 153 89.5


line stmt bran cond sub pod time code
1             package Test::Perl::Critic::Git;
2              
3 1     1   58336 use Cwd;
  1         2  
  1         60  
4 1     1   522 use utf8;
  1         12  
  1         4  
5 1     1   39 use 5.018;
  1         4  
6 1     1   4 use strict;
  1         1  
  1         16  
7 1     1   4 use warnings;
  1         1  
  1         26  
8 1     1   375 use Git::Diff;
  1         20651  
  1         30  
9 1     1   514 use Perl::Critic;
  1         870948  
  1         43  
10 1     1   8 use Test::Builder;
  1         2  
  1         34  
11 1     1   6 use Perl::Critic::Utils;
  1         2  
  1         12  
12 1     1   716 use Perl::Critic::Violation;
  1         2  
  1         423  
13              
14             $Test::Perl::Critic::Git::VERSION = '0.000104';
15             $Test::Perl::Critic::Git::TEST = Test::Builder->new;
16             %Test::Perl::Critic::Git::CRITIC_ARGS = ();
17             %Test::Perl::Critic::Git::GIT_ARGS = ();
18              
19             sub _matching_files {
20 1     1   9 my ( $ar_dirs, $hr_changed_files ) = @_;
21 1         14 my @a_perlfiles = Perl::Critic::Utils::all_perl_files( @{$ar_dirs} );
  1         34  
22              
23 1         2736 require File::Spec;
24 1         3422 my $s_current_dir = Cwd::cwd;
25              
26 1         20 my @a_files = ();
27 1         12 for my $s_file (@a_perlfiles) {
28 7         26 for ( keys %{$hr_changed_files} ) {
  7         31  
29 7 50 33     221 push @a_files, $_ if ( $s_file eq File::Spec->catfile( $s_current_dir, $_ ) || $s_file eq $_ );
30             }
31             }
32 1         56 return \@a_files;
33             }
34              
35             sub _run_builder {
36 3     3   14 my ( $b_switch, $hr_files, $s_message ) = @_;
37 3         6 my $i_files_to_test = 0;
38 3         8 for my $s_file ( sort keys %{$hr_files} ) {
  3         19  
39 2         9 my $hr_file = $hr_files->{$s_file};
40 2 50       6 next if scalar @{ $hr_file->{violations} } == 0;
  2         17  
41 2         7 $i_files_to_test++;
42 2         5 my @a_violations = grep { exists $hr_file->{addition}->{ $_->line_number } } @{ $hr_file->{violations} };
  2         9  
  2         6  
43 2 100       17 if ( scalar @a_violations > 0 ) {
44 1         27 $Test::Perl::Critic::Git::TEST->diag(qq{Perl::Critic had errors in "$s_file":});
45 1         550 $Test::Perl::Critic::Git::TEST->diag($_) for @a_violations;
46 1   50     585 $Test::Perl::Critic::Git::TEST->ok( $b_switch, $s_message // '' );
47 1         273 next;
48             }
49 1         10 $Test::Perl::Critic::Git::TEST->ok( !$b_switch, ( $s_message . ' ' ) . $s_file );
50 1         395 $i_files_to_test--;
51             }
52 3 50 66     66 return $Test::Perl::Critic::Git::TEST->ok( ( ( !$b_switch && !$i_files_to_test ) || ( $b_switch && $i_files_to_test ) ) ? 1 : 0, $s_message // '' );
      100        
53             }
54              
55             sub import {
56 2     2   739 my ( $self, $hr_critic_args, $hr_git_args ) = @_;
57 2         4 my $s_caller = caller;
58             {
59 1     1   6 no strict 'refs'; ## no critic qw(ProhibitNoStrict)
  1         2  
  1         463  
  2         3  
60 2         3 *{ $s_caller . '::critic_on_changed_ok' } = \&critic_on_changed_ok;
  2         11  
61 2         4 *{ $s_caller . '::critic_on_changed_not_ok' } = \&critic_on_changed_not_ok;
  2         6  
62             }
63              
64             # -format is supported for backward compatibility.
65 2 50       8 $hr_critic_args->{-verbose} = $hr_critic_args->{-format} if exists $hr_critic_args->{-format};
66 2         3 %Test::Perl::Critic::Git::CRITIC_ARGS = %{$hr_critic_args};
  2         4  
67 2 50       7 %Test::Perl::Critic::Git::GIT_ARGS = $hr_git_args ? %{$hr_git_args} : ();
  0         0  
68 2         8 return $Test::Perl::Critic::Git::TEST->exported_to($s_caller);
69             }
70              
71             sub critic_on_changed_ok {
72 2     2 1 2470 my ( $ar_dirs, $s_message ) = @_;
73 2 100 66     4239 $ar_dirs = [Cwd::cwd] if !$ar_dirs || scalar @{$ar_dirs} == 0;
  1         6  
74 2         73 my $hr_files = Git::Diff->new(%Test::Perl::Critic::Git::GIT_ARGS)->changes_by_line;
75 2 50       142 $hr_files = { map { ( $hr_files->{$_} ? ( $_, $hr_files->{$_} ) : () ) } @{ _matching_files( $ar_dirs, $hr_files ) } };
  1         12  
  2         32  
76              
77 2         59 my $o_critic = Perl::Critic->new(%Test::Perl::Critic::Git::CRITIC_ARGS);
78 2         916069 Perl::Critic::Violation::set_format( $o_critic->config->verbose );
79 2         121 $hr_files->{$_}->{violations} = [ $o_critic->critique($_) ] for keys %{$hr_files};
  2         13  
80              
81 2         3001 return _run_builder( 0, $hr_files, $s_message );
82             }
83              
84             sub critic_on_changed_not_ok {
85 1     1 1 678 my ( $ar_dirs, $s_message ) = @_;
86 1 50 33     11 $ar_dirs = [Cwd::cwd] if !$ar_dirs || scalar @{$ar_dirs} == 0;
  1         7  
87 1         7 my $hr_files = Git::Diff->new(%Test::Perl::Critic::Git::GIT_ARGS)->changes_by_line;
88 1 50       24 $hr_files = { map { ( $hr_files->{$_} ? ( $_, $hr_files->{$_} ) : () ) } @{ _matching_files( $ar_dirs, $hr_files ) } };
  1         11  
  1         4  
89              
90 1         7 my $o_critic = Perl::Critic->new(%Test::Perl::Critic::Git::CRITIC_ARGS);
91 1         443362 Perl::Critic::Violation::set_format( $o_critic->config->verbose );
92 1         46 $hr_files->{$_}->{violations} = [ $o_critic->critique($_) ] for keys %{$hr_files};
  1         12  
93              
94 1         1357 return _run_builder( 1, $hr_files, $s_message );
95             }
96              
97             1;
98              
99             __END__
100              
101             =encoding utf8
102              
103             =head1 NAME
104              
105             Test::Perl::Critic::Git - Test module to run perl critic on changed git files
106              
107             =head1 VERSION
108              
109             Version 0.000104
110              
111             =head1 SUBROUTINES/METHODS
112              
113             =head2 critic_on_changed_ok
114              
115             Params:
116              
117             $hr_critic_args - direct import params for L<Perl::Critic|Perl::Critic>
118              
119             $hr_git_args - direct import params for L<Git|Git>
120              
121             =head2 critic_on_changed_ok
122              
123             Run perl critic on changed files and and raises errors, or even not :-D
124              
125             =head2 critic_on_changed_not_ok
126              
127             Same as critic_on_changed_ok but vice versa
128              
129             =head1 SYNOPSIS
130              
131             eval "use Test::Perl::Critic::Git";
132             plan skip_all => "Test::Perl::Critic::Git required for testing perl critic" if $@;
133              
134             Test::Perl::Critic::Git->import({
135             -severity => 'brutal',
136             -profile => File::Spec->catfile($Bin, 'critic', 'profilerc'),
137             ...
138             });
139              
140             critic_on_changed_ok([
141             '.',
142             ...
143             ]);
144              
145             =head1 DIAGNOSTICS
146              
147             =head1 DEPENDENCIES
148              
149             =over 4
150              
151             =item * Internal usage
152              
153             L<Carp|Carp>, L<Git::Diff|Git::Diff>, L<Perl::Critic|Perl::Critic>, L<Test::Builder|Test::Builder>,
154             L<Perl::Critic::Utils|Perl::Critic::Utils>, L<Perl::Critic::Violation|Perl::Critic::Violation>
155              
156             =back
157              
158             =head1 INCOMPATIBILITIES
159              
160             =head1 BUGS AND LIMITATIONS
161              
162             A list of current bugs and issues can be found at the CPAN site
163              
164             https://gitlab.com/mziescha/test-perl-critic-git/issues
165              
166             To report a new bug or problem, use the link on this page.
167              
168             =head1 DESCRIPTION
169              
170             Test module to run perl critic on changed git files
171              
172             =head1 CONFIGURATION AND ENVIRONMENT
173              
174             configurable by import sub
175              
176             =head1 AUTHOR
177              
178             Mario Zieschang, C<< <mziescha at cpan.org> >>
179              
180             =head1 LICENSE AND COPYRIGHT
181              
182             =cut