File Coverage

blib/lib/Perl/Critic/Policy/Tics/ProhibitLongLines.pm
Criterion Covered Total %
statement 59 60 98.3
branch 11 16 68.7
condition 2 6 33.3
subroutine 14 15 93.3
pod 5 6 83.3
total 91 103 88.3


line stmt bran cond sub pod time code
1 6     6   4863 use strict;
  6         11  
  6         178  
2 6     6   29 use warnings;
  6         8  
  6         290  
3             package Perl::Critic::Policy::Tics::ProhibitLongLines;
4             # ABSTRACT: 80 x 40 for life!
5             $Perl::Critic::Policy::Tics::ProhibitLongLines::VERSION = '0.009';
6             #pod =head1 DESCRIPTION
7             #pod
8             #pod Please keep your code to about eighty columns wide, the One True Terminal
9             #pod Width. Going over that occasionally is okay, but only once in a while.
10             #pod
11             #pod This policy always throws a violation for extremely long lines. It will also
12             #pod throw a violation if there are too many lines that are slightly longer than the
13             #pod preferred maximum length. If a only few lines exceed the preferred maximum
14             #pod width, they're let slide and only extremely long lines are violations.
15             #pod
16             #pod =head1 CONFIGURATION
17             #pod
18             #pod There are three configuration options for this policy:
19             #pod
20             #pod base_max - the preferred maximum line length (default: 80)
21             #pod hard_max - the length beyond which a line is "extremely long"
22             #pod (default: base_max * 1.5)
23             #pod
24             #pod pct_allowed - the percentage of total lines which may fall between base_max
25             #pod and hard_max before those violations are reported (default: 1)
26             #pod
27             #pod =cut
28              
29 6     6   27 use Perl::Critic::Utils;
  6         11  
  6         96  
30 6     6   5216 use parent qw(Perl::Critic::Policy);
  6         13  
  6         35  
31              
32 15     15 1 189 sub default_severity { $SEVERITY_LOW }
33 0     0 1 0 sub default_themes { qw(tics) }
34 9     9 1 455024 sub applies_to { 'PPI::Document' }
35              
36 18     18 0 899 sub supported_parameters { qw(base_max hard_max pct_allowed) }
37              
38             my %_default = (
39             base_max => 80,
40             pct_allowed => 1,
41             );
42              
43             sub new {
44 9     9 1 108947 my ($class, %arg) = @_;
45 9         98 my $self = $class->SUPER::new(%arg);
46              
47 9         14756 my %merge = (%_default, %arg);
48              
49 9 50 33     117 Carp::croak "base_max for Tics::ProhibitLongLines must be an int, one or more"
50             unless $merge{base_max} =~ /\A\d+\z/ and $merge{base_max} >= 1;
51              
52 9 50       122 $merge{hard_max} = $merge{base_max} * 1.5 unless exists $merge{hard_max};
53              
54             Carp::croak "base_max for Tics::ProhibitLongLines must be an int, one or more"
55 6 50   6   1335 unless do { no warnings; ($merge{hard_max} = int($merge{hard_max})) >= 1 };
  6         13  
  6         3334  
  9         17  
  9         44  
56              
57 9 50 33     73 Carp::croak "pct_allowed for Tics::ProhibitLongLines must be a positive int"
58             unless $merge{pct_allowed} =~ /\A\d+\z/ and $merge{pct_allowed} >= 0;
59              
60 9         25 $self->{$_} = $merge{$_} for $self->supported_parameters;
61              
62 9         68 bless $self => $class;
63             }
64              
65              
66             sub violates {
67 9     9 1 102 my ($self, $elem, $doc) = @_;
68              
69 9         74 $elem->prune('PPI::Token::Data');
70 9         105029 $elem->prune('PPI::Token::End');
71              
72 9         107924 my @lines = split /(?:\x0d\x0a|\x0a\x0d|\x0d|\x0a)/, $elem->serialize;
73              
74 9         33054 my @soft_violations;
75             my @hard_violations;
76              
77 9         34 my $base = $self->{base_max};
78 9         29 my $limit = $self->{hard_max};
79              
80 9         125 my $top = $elem->top();
81 9 50       259 my $fn = $top->can('filename') ? $top->filename() : undef;
82              
83 9         29 LINE: for my $ln (1 .. @lines) {
84 546         560 my $length = length $lines[ $ln - 1 ];
85              
86 546 100       1867 next LINE unless $length > $base;
87              
88 15 100       41 if ($length > $limit) {
89 2         24 my $viol = Perl::Critic::Tics::Violation::VirtualPos->new(
90             "Line is over hard length limit of $limit characters.",
91             "Keep lines to about $limit columns wide.",
92             $doc,
93             $self->get_severity,
94             );
95              
96 2         4738 $viol->_set_location([ $ln, 1, 1, $ln, $fn ], $lines[ $ln - 1 ]);
97              
98 2         7 push @hard_violations, $viol;
99             } else {
100 13         107 my $viol = Perl::Critic::Tics::Violation::VirtualPos->new(
101             "Line is over base length limit of $base characters.",
102             "Keep lines to about $limit columns wide.",
103             $doc,
104             $self->get_severity,
105             );
106              
107 13         32557 $viol->_set_location([ $ln, 1, 1, $ln, $fn ], $lines[ $ln - 1 ]);
108              
109 13         38 push @soft_violations, $viol;
110             }
111             }
112              
113 9         79 my $allowed = sprintf '%u', @lines * ($self->{pct_allowed} / 100);
114              
115 9         21 my $viols = @soft_violations + @hard_violations;
116 9 100       32 if ($viols > $allowed) {
117 4         41 return(@hard_violations, @soft_violations);
118             } else {
119 5         72 return @hard_violations;
120             }
121             }
122              
123             {
124             package # hide
125             Perl::Critic::Tics::Violation::VirtualPos;
126 6     6   41 BEGIN {require Perl::Critic::Violation; our @ISA = 'Perl::Critic::Violation';}
  6         768  
127             sub _set_location {
128 15     15   36 my ($self, $pos, $line) = @_;
129 15         51 $self->{__PACKAGE__}{pos} = $pos;
130 15         40 $self->{__PACKAGE__}{line} = $line;
131             }
132 37     37   17741 sub location { $_[0]->{__PACKAGE__}{pos} }
133 2     2   747 sub source { $_[0]->{__PACKAGE__}{line} }
134             }
135              
136             1;
137              
138             __END__
139              
140             =pod
141              
142             =encoding UTF-8
143              
144             =head1 NAME
145              
146             Perl::Critic::Policy::Tics::ProhibitLongLines - 80 x 40 for life!
147              
148             =head1 VERSION
149              
150             version 0.009
151              
152             =head1 DESCRIPTION
153              
154             Please keep your code to about eighty columns wide, the One True Terminal
155             Width. Going over that occasionally is okay, but only once in a while.
156              
157             This policy always throws a violation for extremely long lines. It will also
158             throw a violation if there are too many lines that are slightly longer than the
159             preferred maximum length. If a only few lines exceed the preferred maximum
160             width, they're let slide and only extremely long lines are violations.
161              
162             =head1 CONFIGURATION
163              
164             There are three configuration options for this policy:
165              
166             base_max - the preferred maximum line length (default: 80)
167             hard_max - the length beyond which a line is "extremely long"
168             (default: base_max * 1.5)
169              
170             pct_allowed - the percentage of total lines which may fall between base_max
171             and hard_max before those violations are reported (default: 1)
172              
173             =head1 AUTHOR
174              
175             Ricardo SIGNES <rjbs@cpan.org>
176              
177             =head1 COPYRIGHT AND LICENSE
178              
179             This software is copyright (c) 2007 by Ricardo SIGNES.
180              
181             This is free software; you can redistribute it and/or modify it under
182             the same terms as the Perl 5 programming language system itself.
183              
184             =cut