1package Perl::Metrics::Lite::Report::Text;
2use strict;
3use warnings;
4use Text::ASCIITable;
5
6my $DEFAULT_MAX_SUB_LINES         = 60;
7my $DEFAULT_MAX_MCCABE_COMPLEXITY = 10;
8
9sub new {
10    my ( $class, %args ) = @_;
11    my $self = bless( {}, $class );
12
13    my $max_sub_lines
14        = exists $args{max_sub_lines}
15        ? $args{max_sub_lines}
16        : $DEFAULT_MAX_SUB_LINES;
17    my $max_sub_mccabe_complexity = $args{max_sub_mccabe_complexity}
18        = exists $args{max_sub_mccabe_complexity}
19        ? $args{max_sub_mccabe_complexity}
20        : $DEFAULT_MAX_MCCABE_COMPLEXITY;
21    my $show_only_error = $args{show_only_error}
22        = exists $args{show_only_error}
23        ? $args{show_only_error}
24        : 0;
25
26    $self->{max_sub_lines}             = $max_sub_lines;
27    $self->{max_sub_mccabe_complexity} = $max_sub_mccabe_complexity;
28    $self->{show_only_error}           = $show_only_error;
29
30    return $self;
31}
32
33sub report {
34    my ( $self, $analysis ) = @_;
35
36    my $file_stats = $analysis->file_stats;
37    $self->report_file_stats($file_stats);
38
39    my $sub_stats = $analysis->sub_stats;
40    $self->report_sub_stats($sub_stats);
41}
42
43sub report_file_stats {
44    my ( $self, $file_stats ) = @_;
45    _print_file_stats_report_header();
46
47    my @rows = ();
48    foreach my $file_stat ( @{$file_stats} ) {
49        push @rows,
50            {
51            path     => $file_stat->{path},
52            packages => $file_stat->{main_stats}->{packages},
53            loc      => $file_stat->{main_stats}->{lines},
54            subs     => $file_stat->{main_stats}->{number_of_methods}
55            };
56    }
57    if (@rows) {
58        my $keys = [ "path", "loc", "subs", "packages" ];
59        my $table = $self->_create_table( $keys, \@rows );
60        print $table;
61    }
62}
63
64sub _print_file_stats_report_header {
65    print "#======================================#\n";
66    print "#           File Metrics               #\n";
67    print "#======================================#\n";
68}
69
70sub report_sub_stats {
71    my ( $self, $sub_stats ) = @_;
72    $self->_print_sub_stats_report_header;
73    foreach my $file_path ( keys %{$sub_stats} ) {
74        my $sub_metrics = $sub_stats->{$file_path};
75        $self->_report_sub_metrics( $file_path, $sub_metrics );
76    }
77}
78
79sub _print_sub_stats_report_header {
80    print "#======================================#\n";
81    print "#         Subroutine Metrics           #\n";
82    print "#======================================#\n";
83}
84
85sub _report_sub_metrics {
86    my ( $self, $path, $sub_metrics ) = @_;
87    my $table = $self->_create_ascii_table_for_submetrics($sub_metrics);
88    if ($table) {
89        $self->_print_table( $path, $table );
90    }
91}
92
93sub _print_table {
94    my ( $self, $path, $table ) = @_;
95
96    print "\nPath: ${path}\n";
97    print $table;
98}
99
100sub _create_ascii_table_for_submetrics {
101    my ( $self, $sub_metrics ) = @_;
102    my @rows = ();
103    foreach my $sub_metric ( @{$sub_metrics} ) {
104        next
105            if $self->{show_only_error}
106                && $self->is_sub_metric_ok($sub_metric);
107        push @rows, $self->_create_row($sub_metric);
108    }
109
110    my $table;
111    if (@rows) {
112        my $keys = [ "method", "loc", "mccabe_complexity" ];
113        $table = $self->_create_table( $keys, \@rows );
114    }
115    return $table;
116}
117
118sub is_sub_metric_ok {
119    my ( $self, $sub_metric ) = @_;
120    return 1 if $sub_metric->{lines} < $self->{max_sub_lines};
121    return 1
122        if $sub_metric->{mccabe_complexity}
123            < $self->{max_sub_mccabe_complexity};
124    return 0;
125}
126
127sub _create_row {
128    my ( $self, $sub_metric ) = @_;
129    return {
130        method            => $sub_metric->{name},
131        loc               => $sub_metric->{lines},
132        mccabe_complexity => $sub_metric->{mccabe_complexity}
133    };
134}
135
136sub _create_table {
137    my ( $self, $keys, $rows ) = @_;
138    my $t = Text::ASCIITable->new();
139    $t->setCols(@$keys);
140    $t->addRow( @$_{@$keys} ) for @$rows;
141    $t;
142}
143
1441;
145
146__END__
147