[Bps-public-commit] app-aws-cloudwatch-monitor-check-mailsummary branch add-check-module created. 5e77f312c46d8b3d6f443ea8aca3697d5c55a9e0

BPS Git Server git at git.bestpractical.com
Thu Nov 25 00:31:07 UTC 2021


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "app-aws-cloudwatch-monitor-check-mailsummary".

The branch, add-check-module has been created
        at  5e77f312c46d8b3d6f443ea8aca3697d5c55a9e0 (commit)

- Log -----------------------------------------------------------------
commit 5e77f312c46d8b3d6f443ea8aca3697d5c55a9e0
Author: Blaine Motsinger <blaine at bestpractical.com>
Date:   Wed Nov 24 18:30:43 2021 -0600

    WIP - Add initial check module and tests
    
    saving the work in the branch.
    needs to be broken into commits.

diff --git a/README b/README
index d89fffc..5427efb 100644
--- a/README
+++ b/README
@@ -1,3 +1,51 @@
 NAME
     App::AWS::CloudWatch::Monitor::Check::MailSummary - gather mail traffic
     summary data
+
+SYNOPSIS
+     my $plugin  = App::AWS::CloudWatch::Monitor::Check::MailSummary->new();
+     my $metrics = $plugin->check( $args_arrayref );
+
+     perl bin/aws-cloudwatch-monitor --check MailSummary --maillog-path /var/log/mail.log --maillog-time 23:00
+
+DESCRIPTION
+    "App::AWS::CloudWatch::Monitor::Check::MailSummary" is a
+    "App::AWS::CloudWatch::Monitor::Check" module which gathers mail traffic
+    summary data for a specified hour.
+
+METRICS
+    The following metrics are gathered and returned.
+
+    mail-Received
+    mail-Delivered
+    mail-Deferred
+    mail-Bounced
+    mail-Rejected
+
+METHODS
+    check
+        Gathers the metric data and returns an arrayref of hashrefs with
+        keys "MetricName", "Unit", "RawValue".
+
+ARGUMENTS
+    --maillog-path </path/to/maillog>
+        The "--maillog-path" argument is required and defines the full path,
+        with filename, where the maillog can be read.
+
+         perl bin/aws-cloudwatch-monitor --check MailSummary --maillog-path /var/log/mail.log
+
+    --maillog-time <hh:mm>
+        The optional "--maillog-time" argument may be defined to specify
+        which hour to get mailstats for.
+
+         perl bin/aws-cloudwatch-monitor --check MailSummary --maillog-path /var/log/mail.log --maillog-time 23:00
+
+        "maillog-time" must be formatted 24hr and minute (hh:mm).
+
+        If "maillog-time" isn't defined, mailstats are gathered for the
+        previous hour.
+
+DEPENDENCIES
+    <App::AWS::CloudWatch::Monitor::Check::MailSummary> depends on the
+    external program, "pflogsumm".
+
diff --git a/lib/App/AWS/CloudWatch/Monitor/Check/MailSummary.pm b/lib/App/AWS/CloudWatch/Monitor/Check/MailSummary.pm
new file mode 100644
index 0000000..f3229f0
--- /dev/null
+++ b/lib/App/AWS/CloudWatch/Monitor/Check/MailSummary.pm
@@ -0,0 +1,156 @@
+package App::AWS::CloudWatch::Monitor::Check::MailSummary;
+
+use strict;
+use warnings;
+
+use parent 'App::AWS::CloudWatch::Monitor::Check';
+
+use Getopt::Long qw(:config pass_through);
+use Time::Piece;
+use Time::Seconds;
+
+our $VERSION = '0.01';
+
+sub check {
+    my $self = shift;
+    my $arg  = shift;
+
+    Getopt::Long::GetOptionsFromArray( $arg, \my %opt, 'maillog-path=s', 'maillog-time=s' );
+
+    die "Option: maillog-path is required" unless $opt{'maillog-path'};
+
+    my $t;
+    if ( $opt{'maillog-time'} ) {
+        die 'Option: maillog-time must be 24hr hour and minute (hh:mm)'
+            unless $opt{'maillog-time'} =~ /^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/;
+
+        $t = Time::Piece->strptime( $opt{'maillog-time'}, '%H:%M' );
+    }
+    else {
+        $t = localtime;
+    }
+
+    my $now = $t->hour;
+    $now = '0' . $now if $now < 10;
+    $now = $now . '00';
+
+    $t -= ONE_HOUR;
+    my $start_hour = $t->hour;
+    $start_hour = '0' . $start_hour if $start_hour < 10;
+    $start_hour = $start_hour . '00';
+
+    my $time_key = $start_hour . '-' . ( $start_hour == 2300 ? 2400 : $now );
+    my $scope    = ( $time_key eq '2300-2400' ? 'yesterday' : 'today' );
+
+    # TODO: find pflogsumm bin location
+    my @pflogsumm_command = ( qw{ /usr/sbin/pflogsumm -d }, $scope, $opt{'maillog-path'}, qw{ --detail 0 } );
+    my ( $exit, $stdout, $stderr ) = $self->run_command( \@pflogsumm_command );
+
+    if ($exit) {
+        die "$stderr\n";
+    }
+
+    return unless $stdout;
+
+    my $traffic_summary_per_hour = {};
+    foreach my $line ( @{$stdout} ) {
+        next unless $line =~ /(\d{4}-\d{4})\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/;
+
+        $traffic_summary_per_hour->{$1} = {
+            Received  => $2,
+            Delivered => $3,
+            Deferred  => $4,
+            Bounced   => $5,
+            Rejected  => $6,
+        };
+    }
+
+    my $metrics;
+    foreach my $key ( sort keys %{ $traffic_summary_per_hour->{$time_key} } ) {
+        push @{$metrics},
+            {
+            MetricName => "mail-$key",
+            Unit       => 'Count',
+            RawValue   => $traffic_summary_per_hour->{$time_key}{$key},
+            },
+    }
+
+    return $metrics;
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+App::AWS::CloudWatch::Monitor::Check::MailSummary - gather mail traffic summary data
+
+=head1 SYNOPSIS
+
+ my $plugin  = App::AWS::CloudWatch::Monitor::Check::MailSummary->new();
+ my $metrics = $plugin->check( $args_arrayref );
+
+ perl bin/aws-cloudwatch-monitor --check MailSummary --maillog-path /var/log/mail.log --maillog-time 23:00
+
+=head1 DESCRIPTION
+
+C<App::AWS::CloudWatch::Monitor::Check::MailSummary> is a C<App::AWS::CloudWatch::Monitor::Check> module which gathers mail traffic summary data for a specified hour.
+
+=head1 METRICS
+
+The following metrics are gathered and returned.
+
+=over
+
+=item mail-Received
+
+=item mail-Delivered
+
+=item mail-Deferred
+
+=item mail-Bounced
+
+=item mail-Rejected
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item check
+
+Gathers the metric data and returns an arrayref of hashrefs with keys C<MetricName>, C<Unit>, C<RawValue>.
+
+=back
+
+=head1 ARGUMENTS
+
+=over
+
+=item --maillog-path </path/to/maillog>
+
+The C<--maillog-path> argument is required and defines the full path, with filename, where the maillog can be read.
+
+ perl bin/aws-cloudwatch-monitor --check MailSummary --maillog-path /var/log/mail.log
+
+=item --maillog-time <hh:mm>
+
+The optional C<--maillog-time> argument may be defined to specify which hour to get mailstats for.
+
+ perl bin/aws-cloudwatch-monitor --check MailSummary --maillog-path /var/log/mail.log --maillog-time 23:00
+
+C<maillog-time> must be formatted 24hr and minute (hh:mm).
+
+If C<maillog-time> isn't defined, mailstats are gathered for the previous hour.
+
+=back
+
+=head1 DEPENDENCIES
+
+<App::AWS::CloudWatch::Monitor::Check::MailSummary> depends on the external program, C<pflogsumm>.
+
+=cut
diff --git a/t/00_load.t b/t/00_load.t
new file mode 100644
index 0000000..c8ffbbf
--- /dev/null
+++ b/t/00_load.t
@@ -0,0 +1,38 @@
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::RealBin/../lib", "$FindBin::RealBin/lib";
+use App::AWS::CloudWatch::Monitor::Check::MailSummary::Test;
+
+use File::Find ();
+use File::Spec ();
+
+foreach my $module (find_all_perl_modules()) {
+    use_ok($module) or BAIL_OUT;
+}
+
+done_testing();
+
+sub find_all_perl_modules {
+    my $base = "$FindBin::RealBin/../";
+
+    my @modules;
+    File::Find::find(
+        sub {
+            my $file = $File::Find::name;
+            return unless $file =~ /\.pm$/;
+            return if $file =~ /Test\.pm$/;
+
+            my $rel_path = File::Spec->abs2rel( $file, $base );
+            $rel_path =~ s/^[t\/]*lib\///;
+            $rel_path =~ s/\//::/g;
+            $rel_path =~ s/\.pm$//;
+
+            push( @modules, $rel_path );
+        },
+        $base,
+    );
+
+    return @modules;
+}
diff --git a/t/996_perl-tidy.t b/t/996_perl-tidy.t
new file mode 100644
index 0000000..d4a8a51
--- /dev/null
+++ b/t/996_perl-tidy.t
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+
+use FindBin;
+use Test::More;
+
+unless ( $ENV{TEST_AUTHOR} ) {
+    my $msg = 'Author test. Set $ENV{TEST_AUTHOR} to a true value to run.';
+    plan( skip_all => $msg );
+}
+
+eval { require Test::PerlTidy; };
+
+if ($@) {
+    my $msg = 'Test::PerlTidy required to criticise code';
+    plan( skip_all => $msg );
+}
+
+Test::PerlTidy::run_tests(
+    path       => "$FindBin::RealBin/../lib",
+    perltidyrc => "$FindBin::RealBin/perltidyrc",
+);
diff --git a/t/997_perl-critic.t b/t/997_perl-critic.t
new file mode 100644
index 0000000..40637c2
--- /dev/null
+++ b/t/997_perl-critic.t
@@ -0,0 +1,23 @@
+use strict;
+use warnings;
+
+use FindBin;
+use File::Spec;
+use Test::More;
+
+unless ( $ENV{TEST_AUTHOR} ) {
+    my $msg = 'Author test. Set $ENV{TEST_AUTHOR} to a true value to run.';
+    plan( skip_all => $msg );
+}
+
+eval { require Test::Perl::Critic; };
+
+if ($@) {
+    my $msg = 'Test::Perl::Critic required to criticise code';
+    plan( skip_all => $msg );
+}
+
+my $rcfile = File::Spec->catfile( 't', 'perlcriticrc' );
+Test::Perl::Critic->import( -profile => $rcfile );
+
+all_critic_ok("$FindBin::RealBin/../lib");
diff --git a/t/998_pod-checker.t b/t/998_pod-checker.t
new file mode 100644
index 0000000..503ec4d
--- /dev/null
+++ b/t/998_pod-checker.t
@@ -0,0 +1,19 @@
+use strict;
+use warnings;
+
+use FindBin;
+use Test::More;
+
+unless ( $ENV{TEST_AUTHOR} ) {
+    my $msg = 'Author test. Set $ENV{TEST_AUTHOR} to a true value to run.';
+    plan( skip_all => $msg );
+}
+
+eval { require Test::Pod; };
+
+if ($@) {
+    my $msg = 'Test::Pod required to criticise code';
+    plan( skip_all => $msg );
+}
+
+Test::Pod::all_pod_files_ok( Test::Pod::all_pod_files("$FindBin::RealBin/../lib") );
diff --git a/t/999_pod-coverage.t b/t/999_pod-coverage.t
new file mode 100644
index 0000000..5bc38e5
--- /dev/null
+++ b/t/999_pod-coverage.t
@@ -0,0 +1,21 @@
+use strict;
+use warnings;
+
+use FindBin ();
+use lib "$FindBin::RealBin/lib";
+
+use Test::More;
+
+unless ( $ENV{TEST_AUTHOR} ) {
+    my $msg = 'Author test. Set $ENV{TEST_AUTHOR} to a true value to run.';
+    plan( skip_all => $msg );
+}
+
+eval { require Test::Pod::Coverage; };
+
+if ($@) {
+    my $msg = 'Test::Pod::Coverage required to criticise code';
+    plan( skip_all => $msg );
+}
+
+Test::Pod::Coverage::all_pod_coverage_ok();
diff --git a/t/check-args.t b/t/check-args.t
new file mode 100644
index 0000000..e488d0c
--- /dev/null
+++ b/t/check-args.t
@@ -0,0 +1,75 @@
+use strict;
+use warnings;
+
+use FindBin ();
+use lib "$FindBin::RealBin/../lib", "$FindBin::RealBin/lib";
+use App::AWS::CloudWatch::Monitor::Check::MailSummary::Test;
+
+my $class = 'App::AWS::CloudWatch::Monitor::Check::MailSummary';
+use_ok($class);
+
+my $test_data = App::AWS::CloudWatch::Monitor::Check::MailSummary::Test::load_test_data( 'success.txt' );
+
+no warnings 'once';
+$App::AWS::CloudWatch::Monitor::Check::stdout = $test_data;
+
+MAILLOG_PATH: {
+    note( 'maillog-path arg' );
+
+    note( 'failure missing' );
+
+    my $args = [];
+    my $obj  = $class->new();
+
+    my $expected_response = 'Option: maillog-path is required';
+    dies_ok { $obj->check( $args ) } 'dies if missing';
+    like( $@, qr/$expected_response/, "response indicates $expected_response" );
+}
+
+MAILLOG_TIME: {
+    note( 'maillog-time arg' );
+
+    my $expected_metrics = [
+        {
+            'RawValue'   => '25',
+            'MetricName' => 'mail-Bounced',
+            'Unit'       => 'Count',
+        },
+        {
+            'Unit'       => 'Count',
+            'MetricName' => 'mail-Deferred',
+            'RawValue'   => '0',
+        },
+        {
+            'Unit'       => 'Count',
+            'MetricName' => 'mail-Delivered',
+            'RawValue'   => '118',
+        },
+        {
+            'Unit'       => 'Count',
+            'MetricName' => 'mail-Received',
+            'RawValue'   => '61',
+        },
+        {
+            'RawValue'   => '1',
+            'MetricName' => 'mail-Rejected',
+            'Unit'       => 'Count',
+        },
+    ];
+
+    my $args = [ '--maillog-path', '/var/fake/mail.log', '--maillog-time', '14:00' ];
+
+    my $obj     = $class->new();
+    my $metrics = $obj->check( $args );
+
+    is_deeply( $metrics, $expected_metrics, 'return contains the expected metrics' );
+
+    note( 'failure incorrect format' );
+
+    my $expected_response = 'Option: maillog-time must be 24hr hour and minute \(hh:mm\)';
+    $args = [ '--maillog-path', '/var/fake/mail.log', '--maillog-time', '1400' ];
+    dies_ok { $obj->check( $args ) } 'dies if incorrect format';
+    like( $@, qr/$expected_response/, "response indicates $expected_response" );
+}
+
+done_testing();
diff --git a/t/check.t b/t/check.t
new file mode 100644
index 0000000..21e0665
--- /dev/null
+++ b/t/check.t
@@ -0,0 +1,50 @@
+use strict;
+use warnings;
+
+use FindBin ();
+use lib "$FindBin::RealBin/../lib", "$FindBin::RealBin/lib";
+use App::AWS::CloudWatch::Monitor::Check::MailSummary::Test;
+
+my $class = 'App::AWS::CloudWatch::Monitor::Check::MailSummary';
+use_ok($class);
+
+my $test_data = App::AWS::CloudWatch::Monitor::Check::MailSummary::Test::load_test_data( 'success.txt' );
+
+HAPPY_PATH: {
+    note( 'happy path' );
+
+    no warnings 'once';
+    $App::AWS::CloudWatch::Monitor::Check::stdout = $test_data;
+
+    my $obj = $class->new();
+    my $metrics = $obj->check();
+
+    ok( $metrics, 'return is truthy' );
+    ok( ref $metrics eq 'ARRAY' && scalar @{$metrics}, 'return is an ARRAYREF containing members' );
+
+    my $found_metric_names = 0;
+    foreach my $metric ( @{$metrics} ) {
+        $found_metric_names += 1 if grep { $metric->{MetricName} eq "mail-$_" } (qw{ Received Delivered Deferred Bounced Rejected });
+        my $found_metric_keys = grep { defined $metric->{$_} } (qw{ MetricName Unit RawValue });
+        ok( $found_metric_keys == 3, $metric->{MetricName} . ' metric contains the required keys' );
+    }
+
+    ok( @{$metrics} == 5 && $found_metric_names == 5, 'return contains the expected metrics' );
+}
+
+FAILURES: {
+    note( 'run_command failure' );
+
+    no warnings 'once';
+    $App::AWS::CloudWatch::Monitor::Check::exit = 1;
+    my $expected_error = 'more olives on the pizza';
+    $App::AWS::CloudWatch::Monitor::Check::stderr = $expected_error;
+
+    my $args = [ '--maillog-path', '/var/fake/mail.log' ];
+    my $obj  = $class->new();
+
+    dies_ok { $obj->check( $args ) } 'dies if run_command returns exit code';
+    like( $@, qr/$expected_error/, 'response propagates stderr from run_command' );
+}
+
+done_testing();
diff --git a/t/data/success.txt b/t/data/success.txt
new file mode 100644
index 0000000..77e6b73
--- /dev/null
+++ b/t/data/success.txt
@@ -0,0 +1,58 @@
+Postfix log summaries for Mar 23
+
+Grand Totals
+------------
+messages
+
+   1050   received
+   1393   delivered
+      0   forwarded
+      0   deferred
+     96   bounced
+      4   rejected (0%)
+      0   reject warnings
+      0   held
+      0   discarded (0%)
+
+  97262k  bytes received
+ 126983k  bytes delivered
+    179   senders
+    100   sending hosts/domains
+    328   recipients
+     76   recipient hosts/domains
+
+
+Per-Hour Traffic Summary
+------------------------
+    time          received  delivered   deferred    bounced     rejected
+    --------------------------------------------------------------------
+    0000-0100          37         42          0          0          0 
+    0100-0200          34         62          0          8          0 
+    0200-0300          32         31          0          1          1 
+    0300-0400          31         32          0          1          0 
+    0400-0500          26         25          0          1          0 
+    0500-0600          30         30          0          0          0 
+    0600-0700          48         64          0          0          0 
+    0700-0800          57         77          0          2          0 
+    0800-0900          77         80          0          3          1 
+    0900-1000          90         93          0          5          0 
+    1000-1100          52         67          0          2          0 
+    1100-1200          54         69          0          7          0 
+    1200-1300          57         83          0          7          0 
+    1300-1400          61        118          0         25          1 
+    1400-1500          70         85          0          0          0 
+    1500-1600         109        190          0         25          0 
+    1600-1700         102        122          0          7          1 
+    1700-1800          74        111          0          2          0 
+    1800-1900           9         12          0          0          0 
+    1900-2000           0          0          0          0          0 
+    2000-2100           0          0          0          0          0 
+    2100-2200           0          0          0          0          0 
+    2200-2300           0          0          0          0          0 
+    2300-2400           0          0          0          0          0 
+
+Fatal Errors: none
+
+Panics: none
+
+Master daemon messages: none
diff --git a/t/lib/App/AWS/CloudWatch/Monitor/Check.pm b/t/lib/App/AWS/CloudWatch/Monitor/Check.pm
new file mode 100644
index 0000000..7341927
--- /dev/null
+++ b/t/lib/App/AWS/CloudWatch/Monitor/Check.pm
@@ -0,0 +1,80 @@
+package App::AWS::CloudWatch::Monitor::Check;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.01';
+
+our $exit   = 0;
+our $stdout = [];
+our $stderr = '';
+
+sub new {
+    my $class = shift;
+    my $self  = {};
+
+    return bless $self, $class;
+}
+
+sub run_command {
+    my $self    = shift;
+    my $command = shift;
+
+    return ( $exit, $stdout, $stderr );
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+App::AWS::CloudWatch::Monitor::Check - mock parent for Check modules
+
+=head1 SYNOPSIS
+
+ use parent 'App::AWS::CloudWatch::Monitor::Check';
+
+=head1 DESCRIPTION
+
+C<App::AWS::CloudWatch::Monitor::Check> provides a contructor and methods for child modules in tests.
+
+This module is only to allow testing check modules, and not meant to be initialized directly, but through child modules in tests.
+
+=head1 CONSTRUCTOR
+
+=over
+
+=item new
+
+Returns the C<App::AWS::CloudWatch::Monitor::Check> object.
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_command
+
+Method to mock C<run_command> output for tests.  Returns a list with three members consisting of:
+
+=over
+
+=item C<exit code>
+
+The C<exit code> can be set in the package variable, C<App::AWS::CloudWatch::Monitor::Check::exit>.
+
+=item output from C<STDOUT>
+
+The C<STDOUT> can be set in the package variable, C<App::AWS::CloudWatch::Monitor::Check::stdout>.
+
+=item output from C<STDERR>
+
+The C<STDERR> can be set in the package variable, C<App::AWS::CloudWatch::Monitor::Check::stderr>.
+
+=back
+
+=cut
diff --git a/t/lib/App/AWS/CloudWatch/Monitor/Check/MailSummary/Test.pm b/t/lib/App/AWS/CloudWatch/Monitor/Check/MailSummary/Test.pm
new file mode 100644
index 0000000..671ccc8
--- /dev/null
+++ b/t/lib/App/AWS/CloudWatch/Monitor/Check/MailSummary/Test.pm
@@ -0,0 +1,84 @@
+package App::AWS::CloudWatch::Monitor::Check::MailSummary::Test;
+
+use strict;
+use warnings;
+
+use parent 'Test::More';
+
+our $VERSION = '0.01';
+
+sub import {
+    my $class = shift;
+    my %args  = @_;
+
+    if ( $args{tests} ) {
+        $class->builder->plan( tests => $args{tests} )
+            unless $args{tests} eq 'no_declare';
+    }
+    elsif ( $args{skip_all} ) {
+        $class->builder->plan( skip_all => $args{skip_all} );
+    }
+
+    Test::More->export_to_level(1);
+
+    require Test::Exception;
+    Test::Exception->export_to_level(1);
+
+    return;
+}
+
+sub load_test_data {
+    my $filename       = shift;
+    my $test_data_file = "$FindBin::RealBin/data/$filename";
+
+    die "filename argument is required\n"
+        unless $filename;
+
+    open( my $test_data_file_fh, '<', $test_data_file )
+        or die "$test_data_file does not exist or cannot be read";
+
+    my $test_data = [];
+    while ( my $line = <$test_data_file_fh> ) {
+        chomp $line;
+        push @{$test_data}, $line;
+    }
+    close($test_data_file_fh);
+
+    return $test_data;
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+App::AWS::CloudWatch::Monitor::Check::MailSummary::Test - testing module for App::AWS::CloudWatch::Monitor::Check::MailSummary
+
+=head1 SYNOPSIS
+
+ use App::AWS::CloudWatch::Monitor::Check::MailSummary::Test;
+
+ ok($got eq $expected, $test_name);
+
+=head1 DESCRIPTION
+
+C<App::AWS::CloudWatch::Monitor::Check::MailSummary::Test> sets up the testing environment and modules needed to test the MailSummary check module in isolation.
+
+Methods from C<Test::More> and C<Test::Exception> are exported and available for the tests.
+
+=head1 SUBROUTINES
+
+=over
+
+=item load_test_data
+
+Reads and returns output from files in C<t/data/>.
+
+Takes C<filename> as an argument for which file to read.
+
+=back
+
+=cut
diff --git a/t/perlcriticrc b/t/perlcriticrc
new file mode 100644
index 0000000..f065624
--- /dev/null
+++ b/t/perlcriticrc
@@ -0,0 +1,200 @@
+### PERLCRITIC OPTIONS
+color = 1
+verbose = %m at %f line %l [%p]\n
+severity = 2
+force = 1
+
+
+### POLICY SETTINGS
+# we don't unpack @_ right away as we mostly use named vars with defaults
+[-Subroutines::RequireArgUnpacking]
+
+# errstr for DBI is okay, and probably others since I like that convention.
+[-Variables::ProhibitPackageVars]
+#packages = DBI
+
+# HEREDOC doesn't adhere to my tidy eye
+[-ValuesAndExpressions::ProhibitImplicitNewlines]
+
+# don't require extended format for shortish regex
+# keeping this in here for documentation purposes
+[-RegularExpressions::RequireExtendedFormatting]
+#minimum_regex_length_to_complain_about = 60
+
+# don't require Carp
+[-ErrorHandling::RequireCarping]
+
+# postfix is okay, unless it's really weird
+[-ControlStructures::ProhibitPostfixControls]
+
+# needless ruleset for modern Perl versions
+[-ValuesAndExpressions::ProhibitInterpolationOfLiterals]
+
+# don't use backticks
+[InputOutput::ProhibitBacktickOperators]
+only_in_void_context = 1
+
+# 3 arg open is modern Perl
+[InputOutput::ProhibitTwoArgOpen]
+
+# close filehandles as soon as possible after opening them.
+[InputOutput::RequireBriefOpen]
+lines = 17
+
+# forbid a bare `## no critic'
+# shouldn't be turning off critic anyway
+[Miscellanea::ProhibitUnrestrictedNoCritic]
+
+# Minimize complexity in code that is outside of subroutines.
+[-Modules::ProhibitExcessMainComplexity]
+max_mccabe = 28
+
+# write `require Module' instead of `require 'Module.pm''.
+[Modules::RequireBarewordIncludes]
+
+# end each module with an explicitly `1;' instead of some funky expression.
+# sorry Charles ;)
+[Modules::RequireEndWithOne]
+
+# always make the 'package' explicit.
+[Modules::RequireExplicitPackage]
+
+# package declaration must match filename.
+[Modules::RequireFilenameMatchesPackage]
+
+# Give every module a `$VERSION' number.
+[Modules::RequireVersionVar]
+
+# don't use vague variable or subroutine names like 'last' or 'record'.
+[NamingConventions::ProhibitAmbiguousNames]
+forbid = last left right no abstract contract record second close
+
+# write `@{ $array_ref }' instead of `@$array_ref'.
+# consistency mostly.  I don't really care either way, but should be consistent.
+[References::ProhibitDoubleSigils]
+
+## REGEX
+[RegularExpressions::ProhibitUnusedCapture]
+[RegularExpressions::ProhibitUnusualDelimiters]
+[-RegularExpressions::RequireDotMatchAnything]
+[-RegularExpressions::RequireLineBoundaryMatching]
+[-RegularExpressions::ProhibitEnumeratedClasses]
+[-RegularExpressions::ProhibitFixedStringMatches]
+
+# don't name things the same as other things
+[Subroutines::ProhibitBuiltinHomonyms]
+
+# too many arguments
+[Subroutines::ProhibitManyArgs]
+
+# don't write `sub my_function (@@) {}'.
+[Subroutines::ProhibitSubroutinePrototypes]
+
+# prevent unused private subroutines.
+[Subroutines::ProhibitUnusedPrivateSubroutines]
+
+# prevent access to private subs in other packages.
+[Subroutines::ProtectPrivateSubs]
+
+# end every path through a subroutine with an explicit `return' statement.
+[Subroutines::RequireFinalReturn]
+
+# shouldn't be turning these off or not defining these
+[TestingAndDebugging::ProhibitNoStrict]
+[TestingAndDebugging::ProhibitNoWarnings]
+[TestingAndDebugging::RequireUseStrict]
+[TestingAndDebugging::RequireUseWarnings]
+
+# unless is okay sometimes
+[-ControlStructures::ProhibitUnlessBlocks]
+
+# don't require constants inplace of magic variables
+# I'm still on the fence about this
+[-ValuesAndExpressions::ProhibitMagicNumbers]
+
+# don't prohibit constant pragma
+[-ValuesAndExpressions::ProhibitConstantPragma]
+
+# don't prohibit long numbers
+[-ValuesAndExpressions::RequireNumberSeparators]
+
+# don't require check of close
+[-InputOutput::RequireCheckedClose]
+
+# allow error strings from syscalls
+[Variables::ProhibitPunctuationVars]
+allow = $! $0
+
+# don't care about noisy quotes
+[-ValuesAndExpressions::ProhibitNoisyQuotes]
+
+# don't care about empty quotes
+[-ValuesAndExpressions::ProhibitEmptyQuotes]
+
+# set sub complexity to 30
+[Subroutines::ProhibitExcessComplexity]
+max_mccabe = 30
+
+# dont prohibit C style for loops
+[-ControlStructures::ProhibitCStyleForLoops]
+
+
+## TODO: re-evaluate these
+# when working on old modules, export is okay
+[-Modules::ProhibitAutomaticExportation]
+
+# Write ` !$foo && $bar || $baz ' instead of ` not $foo && $bar or $baz'.
+[ValuesAndExpressions::ProhibitMixedBooleanOperators]
+
+# Use `my' instead of `local', except when you have to.
+[Variables::ProhibitLocalVars]
+
+# Don't ask for storage you don't need.
+[Variables::ProhibitUnusedVariables]
+
+# don't use 'grep' in void contexts.
+[BuiltinFunctions::ProhibitVoidGrep]
+
+# don't use 'map' in void contexts.
+[BuiltinFunctions::ProhibitVoidMap]
+
+# don't use 'grep' in boolean context
+[BuiltinFunctions::ProhibitBooleanGrep]
+
+# Write `bless {}, $class;' instead of just `bless {};'.
+[ClassHierarchies::ProhibitOneArgBless]
+
+# Use spaces instead of tabs.
+[CodeLayout::ProhibitHardTabs]
+
+# Don't use whitespace at the end of lines.
+[CodeLayout::ProhibitTrailingWhitespace]
+
+# Use the same newline through the source.
+[CodeLayout::RequireConsistentNewlines]
+
+# Must run code through perltidy.
+[CodeLayout::RequireTidyCode]
+
+# Put a comma at the end of every multi-line list declaration, including the last one.
+[CodeLayout::RequireTrailingCommas]
+
+# Don't write long "if-elsif-elsif-elsif-elsif...else" chains.
+[ControlStructures::ProhibitCascadingIfElse]
+
+# Don't use operators like `not', `!~', and `le' within `until' and `unless'.
+[ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions]
+
+# Don't write code after an unconditional `die, exit, or next'.
+[ControlStructures::ProhibitUnreachableCode]
+
+
+## POD
+# The `=head1 NAME' section should match the package.
+# [Documentation::RequirePackageMatchesPodName]
+
+# All POD should be after `__END__'.
+# [Documentation::RequirePodAtEnd]
+
+# Organize your POD into the customary sections.
+[-Documentation::RequirePodSections]
diff --git a/t/perltidyrc b/t/perltidyrc
new file mode 100644
index 0000000..4348b2a
--- /dev/null
+++ b/t/perltidyrc
@@ -0,0 +1,34 @@
+-l=140   # Max line width is 140 cols
+-i=4     # Indent level is 4 cols
+-ci=4    # Continuation indent is 4 cols
+-vt=4    # Maximal vertical tightness
+-cti=0   # No extra indentation for closing brackets
+-pt=1    # Medium parenthesis tightness
+-sbt=1   # Medium square bracket tightness
+-bt=1    # Medium brace tightness (for non-code blocks)
+-bbt=1   # Medium block brace tightness (for code blocks)
+--nospace-for-semicolon
+-nolq    # Don't outdent long quoted strings
+         # Break before all operators:
+-wbb="% + - * / x != == >= <= =~ < > | & **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x="
+
+-fpsc=0  # Don't try to line up all comments to a fixed column
+-hsc     # Align hanging side comments
+-bbs     # Ensure a blank line before every sub definition (except one-liners)
+-bbb     # Ensure a blank line before code blocks (for, while, if, ....)
+
+-bar     # K&R style code braces
+-nolc    # Long comments indented, even when this make the total line length "too long"
+-noll    # Long lines indented, even when this make the total line length "too long"
+-nola    # Don't treat labels as special cases when indenting
+
+-nst     # Do NOT output to STDOUT (since we want to use -b)
+-b       # Backup the input file to .bak and perform all tidying in the original file
+-se      # Write errors to STDERR
+
+-it=4    # iterations
+--block-brace-vertical-tightness=1
+--nospace-terminal-semicolon
+--noadd-semicolons
+-nbl     # --noopening-brace-on-new-line
+--backup-file-extension=/    # delete bak file
-----------------------------------------------------------------------


hooks/post-receive
-- 
app-aws-cloudwatch-monitor-check-mailsummary


More information about the Bps-public-commit mailing list