[libcode-tidyall-perl] 118/374: switch to Moo, and new_with_conf_file

Jonas Smedegaard js at alioth.debian.org
Sun Sep 29 22:26:00 UTC 2013


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository libcode-tidyall-perl.

commit dd2a14e34def42711cc4144a5047960b036cbdf7
Author: Jonathan Swartz <swartz at pobox.com>
Date:   Tue Jul 24 14:02:23 2012 -0700

    switch to Moo, and new_with_conf_file
---
 lib/Code/TidyAll.pm               |  215 +++++++++++++++++++++----------------
 lib/Code/TidyAll/Plugin.pm        |   49 +++++----
 lib/Code/TidyAll/SVN/Precommit.pm |    6 +-
 lib/Code/TidyAll/t/Basic.pm       |   34 +++---
 4 files changed, 170 insertions(+), 134 deletions(-)

diff --git a/lib/Code/TidyAll.pm b/lib/Code/TidyAll.pm
index f41d1d6..74d65e3 100644
--- a/lib/Code/TidyAll.pm
+++ b/lib/Code/TidyAll.pm
@@ -11,114 +11,120 @@ use File::Find qw(find);
 use File::Zglob;
 use List::Pairwise qw(grepp mapp);
 use List::MoreUtils qw(uniq);
+use Moo;
 use Time::Duration::Parse qw(parse_duration);
 use Try::Tiny;
 use strict;
 use warnings;
 
-sub valid_params {
-    return qw(
-      backup_ttl
-      check_only
-      conf_file
-      data_dir
-      mode
-      no_backups
-      no_cache
-      output_suffix
-      plugins
-      quiet
-      refresh_cache
-      root_dir
-      verbose
-    );
-}
-my %valid_params_hash;
-
-# Incoming parameters
-use Object::Tiny ( valid_params() );
+# External
+has 'backup_ttl'    => ( is => 'ro', default => sub { '1 hour' } );
+has 'check_only'    => ( is => 'ro' );
+has 'data_dir'      => ( is => 'lazy' );
+has 'mode'          => ( is => 'ro', default => sub { 'cli' } );
+has 'no_backups'    => ( is => 'ro' );
+has 'no_cache'      => ( is => 'ro' );
+has 'output_suffix' => ( is => 'ro', default => sub { '' } );
+has 'plugins'       => ( is => 'ro', required => 1 );
+has 'quiet'         => ( is => 'ro' );
+has 'refresh_cache' => ( is => 'ro' );
+has 'root_dir'      => ( is => 'ro', required => 1 );
+has 'verbose'       => ( is => 'ro' );
 
 # Internal
-use Object::Tiny qw(
-  backup_dir
-  base_sig
-  cache
-  matched_files
-  plugin_objects
-);
+has 'backup_dir'       => ( is => 'lazy', init_arg => undef, trigger => 1 );
+has 'backup_ttl_secs'  => ( is => 'lazy', init_arg => undef );
+has 'base_sig'         => ( is => 'lazy', init_arg => undef );
+has 'cache'            => ( is => 'lazy', init_arg => undef );
+has 'conf_file'        => ( is => 'ro', init_arg => undef );
+has 'plugin_objects'   => ( is => 'lazy', init_arg => undef );
+has 'plugins_for_mode' => ( is => 'lazy', init_arg => undef );
 
 my $ini_name = 'tidyall.ini';
 
-sub new {
-    my $class  = shift;
-    my %params = @_;
+sub _build_backup_dir {
+    my $self = shift;
+    return $self->data_dir . "/backups";
+}
 
-    # Read params from conf file
-    #
-    if ( my $conf_file = delete( $params{conf_file} ) ) {
-        my $conf_params = $class->_read_conf_file($conf_file);
-        my $main_params = delete( $conf_params->{'_'} ) || {};
-        %params = (
-            plugins  => $conf_params,
-            root_dir => realpath( dirname($conf_file) ),
-            %$main_params, %params
-        );
-    }
-    else {
-        die "conf_file or plugins required"  unless $params{plugins};
-        die "conf_file or root_dir required" unless $params{root_dir};
-        $params{root_dir} = realpath( $params{root_dir} );
-    }
+sub _build_backup_ttl_secs {
+    my $self = shift;
+    return parse_duration( $self->backup_ttl );
+}
 
-    # Initialize with alternate class if given
-    #
-    if ( my $tidyall_class = delete( $params{tidyall_class} ) ) {
-        die "cannot load '$tidyall_class'" unless can_load($tidyall_class);
-        return $tidyall_class->new(%params);
+sub _build_base_sig {
+    my $self = shift;
+    return $self->_sig( [ $Code::TidyAll::VERSION || 0 ] );
+}
+
+sub _build_cache {
+    my $self = shift;
+    return Code::TidyAll::Cache->new( cache_dir => $self->data_dir . "/cache" );
+}
+
+sub _build_data_dir {
+    my $self = shift;
+    return $self->root_dir . "/.tidyall.d";
+}
+
+sub _build_plugins_for_mode {
+    my $self    = shift;
+    my $plugins = $self->plugins;
+    if ( my $mode = $self->mode ) {
+        $plugins = { grepp { $self->_plugin_conf_matches_mode( $b, $mode ) } %{ $self->plugins } };
     }
+    return $plugins;
+}
+
+sub _build_plugin_objects {
+    my $self = shift;
+    return [
+        map { $self->_load_plugin( $_, $self->plugins->{$_} ) }
+        sort keys( %{ $self->plugins_for_mode } )
+    ];
+}
+
+sub BUILD {
+    my ( $self, $params ) = @_;
 
-    # Check param validity
+    # Strict constructor
     #
-    my $valid_params_hash = $valid_params_hash{$class} ||=
-      { map { ( $_, 1 ) } $class->valid_params() };
-    if ( my @bad_params = grep { !$valid_params_hash->{$_} } keys(%params) ) {
+    if ( my @bad_params = grep { !$self->can($_) } keys(%$params) ) {
         die sprintf( "unknown constructor param(s) %s",
             join( ", ", sort map { "'$_'" } @bad_params ) );
     }
 
-    $class->msg( "constructing %s with these params: %s", $class, dump_one_line( \%params ) )
-      if ( $params{verbose} );
-
-    my $self = $class->SUPER::new(%params);
-
-    $self->{data_dir}      ||= $self->root_dir . "/.tidyall.d";
-    $self->{output_suffix} ||= '';
-    $self->{mode}          ||= 'cli';
-
-    unless ( $self->no_cache ) {
-        $self->{cache} = Code::TidyAll::Cache->new( cache_dir => $self->data_dir . "/cache" );
-    }
+    $self->{root_dir}         = realpath( $self->{root_dir} );
+    $self->{plugins_for_path} = {};
 
     unless ( $self->no_backups ) {
-        $self->{backup_dir} = $self->data_dir . "/backups";
         mkpath( $self->backup_dir, 0, 0775 );
-        $self->{backup_ttl} ||= '1 hour';
-        $self->{backup_ttl} = parse_duration( $self->{backup_ttl} )
-          unless $self->{backup_ttl} =~ /^\d+$/;
         $self->_purge_backups_periodically();
     }
+}
 
-    if ( my $mode = $self->mode ) {
-        $self->{plugins} =
-          { grepp { $self->_plugin_conf_matches_mode( $b, $mode ) } %{ $self->plugins } };
+sub new_from_conf_file {
+    my ( $class, $conf_file, %params ) = @_;
+
+    my $conf_params = $class->_read_conf_file($conf_file);
+    my $main_params = delete( $conf_params->{'_'} ) || {};
+    %params = (
+        plugins  => $conf_params,
+        root_dir => realpath( dirname($conf_file) ),
+        %$main_params, %params
+    );
+
+    # Initialize with alternate class if given
+    #
+    if ( my $tidyall_class = delete( $params{tidyall_class} ) ) {
+        die "cannot load '$tidyall_class'" unless can_load($tidyall_class);
+        $class = $tidyall_class;
     }
 
-    $self->{base_sig} = $self->_sig( [ $Code::TidyAll::VERSION || 0 ] );
-    $self->{plugin_objects} =
-      [ map { $self->_load_plugin( $_, $self->plugins->{$_} ) } sort keys( %{ $self->plugins } ) ];
-    $self->{plugins_for_path} = {};
+    $class->msg( "constructing %s with these params: %s", $class, dump_one_line( \%params ) )
+      if ( $params{verbose} );
 
-    return $self;
+    return $class->new(%params);
 }
 
 sub _load_plugin {
@@ -170,7 +176,7 @@ sub process_file {
     my ( $self, $file ) = @_;
 
     my $path      = $self->_small_path($file);
-    my $cache     = $self->cache;
+    my $cache     = $self->no_cache ? undef : $self->cache;
     my $cache_key = "sig/$path";
     my $contents  = my $orig_contents = read_file($file);
     if ( $cache && ( my $sig = $cache->get($cache_key) ) ) {
@@ -282,12 +288,11 @@ sub _backup_filename {
 
 sub _purge_backups_periodically {
     my ($self) = @_;
-    if ( my $cache = $self->cache ) {
-        my $last_purge_backups = $cache->get("last_purge_backups") || 0;
-        if ( time > $last_purge_backups + $self->backup_ttl ) {
-            $self->_purge_backups();
-            $cache->set( "last_purge_backups", time() );
-        }
+    my $cache = $self->cache;
+    my $last_purge_backups = $cache->get("last_purge_backups") || 0;
+    if ( time > $last_purge_backups + $self->backup_ttl_secs ) {
+        $self->_purge_backups();
+        $cache->set( "last_purge_backups", time() );
     }
 }
 
@@ -298,7 +303,7 @@ sub _purge_backups {
         {
             follow => 0,
             wanted => sub {
-                unlink $_ if -f && /\.bak$/ && time > ( stat($_) )[9] + $self->backup_ttl;
+                unlink $_ if -f && /\.bak$/ && time > ( stat($_) )[9] + $self->backup_ttl_secs;
             },
             no_chdir => 1
         },
@@ -422,8 +427,9 @@ Code::TidyAll - Engine for tidyall, your all-in-one code tidier and validator
 
     use Code::TidyAll;
 
-    my $ct = Code::TidyAll->new(
-        conf_file => '/path/to/conf/file'
+    my $ct = Code::TidyAll->new_from_conf_file(
+        '/path/to/conf/file',
+        ...
     );
 
     # or
@@ -454,9 +460,28 @@ overview.
 
 You can call this API from your own program instead of executing C<tidyall>.
 
-=head1 CONSTRUCTOR OPTIONS
+=head1 CONSTRUCTION
+
+=head2 Construtor methods
+
+=over
+
+=item new (%params)
+
+The regular constructor. Must pass at least I<plugins> and I<root_dir>.
+
+=item new_with_conf_file ($conf_file, %params)
 
-You must either pass C<conf_file>, or both C<plugins> and C<root_dir>.
+Takes a conf file path, followed optionally by a set of key/value parameters. 
+Reads parameters out of the conf file and combines them with the passed
+parameters (the latter take precedence), and calls the regular constructor.
+
+If the conf file or params defines I<tidyall_class>, then that class is
+constructed instead of C<Code::TidyAll>.
+
+=back
+
+=head2 Constructor parameters
 
 =over
 
@@ -469,8 +494,6 @@ equivalent to what would be parsed out of the sections in C<tidyall.ini>.
 
 =item check_only
 
-=item conf_file
-
 =item data_dir
 
 =item mode
@@ -479,10 +502,12 @@ equivalent to what would be parsed out of the sections in C<tidyall.ini>.
 
 =item no_cache
 
-=item root_dir
+=item output_suffix
 
 =item quiet
 
+=item root_dir
+
 =item verbose
 
 These options are the same as the equivalent C<tidyall> command-line options,
diff --git a/lib/Code/TidyAll/Plugin.pm b/lib/Code/TidyAll/Plugin.pm
index 12266bd..0a4e062 100644
--- a/lib/Code/TidyAll/Plugin.pm
+++ b/lib/Code/TidyAll/Plugin.pm
@@ -1,29 +1,34 @@
 package Code::TidyAll::Plugin;
-use Object::Tiny qw(conf ignore name options select tidyall);
 use Code::TidyAll::Util qw(basename read_file write_file);
 use Code::TidyAll::Util::Zglob qw(zglob_to_regex);
 use Scalar::Util qw(weaken);
-use strict;
-use warnings;
-
-sub new {
-    my $class = shift;
-    my $self  = $class->SUPER::new(@_);
-    die "conf required"    unless $self->{conf};
-    die "name required"    unless $self->{name};
-    die "tidyall required" unless $self->{tidyall};
-
-    my $name = $self->{name};
-    weaken( $self->{tidyall} );
-    $self->{select} = $self->{conf}->{select}
-      or die "select required for '$name'";
-    die "select for '$name' should not begin with /" if substr( $self->{select}, 0, 1 ) eq '/';
-    $self->{ignore} = $self->{conf}->{ignore};
-    die "ignore for '$name' should not begin with /"
-      if defined( $self->{ignore} ) && substr( $self->{ignore}, 0, 1 ) eq '/';
-    $self->{options} = $self->_build_options();
-
-    return $self;
+use Moo;
+
+# External
+has 'conf'    => ( is => 'ro', required => 1 );
+has 'ignore'  => ( is => 'lazy' );
+has 'name'    => ( is => 'ro', required => 1 );
+has 'select'  => ( is => 'lazy' );
+has 'tidyall' => ( is => 'ro', required => 1, weak_ref => 1 );
+
+# Internal
+has 'options' => ( is => 'lazy', init_arg => undef );
+
+sub _build_select {
+    my $self = shift;
+    my $path = $self->conf->{select};
+    die sprintf( "select is required for '%s'", $self->name ) unless defined($path);
+    die sprintf( "select for '%s' should not begin with /", $self->name )
+      if ( substr( $path, 0, 1 ) eq '/' );
+    return $path;
+}
+
+sub _build_ignore {
+    my $self = shift;
+    my $path = $self->conf->{ignore};
+    die sprintf( "select for '%s' should not begin with /", $self->name )
+      if ( defined($path) && substr( $path, 0, 1 ) eq '/' );
+    return $path;
 }
 
 # No-ops by default; may be overridden in subclass
diff --git a/lib/Code/TidyAll/SVN/Precommit.pm b/lib/Code/TidyAll/SVN/Precommit.pm
index e75598e..a63bdf4 100644
--- a/lib/Code/TidyAll/SVN/Precommit.pm
+++ b/lib/Code/TidyAll/SVN/Precommit.pm
@@ -6,8 +6,6 @@ use Log::Any qw($log);
 use Moo;
 use SVN::Look;
 use Try::Tiny;
-use strict;
-use warnings;
 
 # Public
 has 'conf_file'        => ( is => 'ro', default => sub { "tidyall.ini" } );
@@ -70,8 +68,8 @@ sub check {
                 mkpath( dirname($full_path), 0, 0775 );
                 write_file( $full_path, $contents );
             }
-            my $tidyall = $self->tidyall_class->new(
-                conf_file  => join( "/", $tempdir, $self->conf_file ),
+            my $tidyall = $self->tidyall_class->new_from_conf_file(
+                join( "/", $tempdir, $self->conf_file ),
                 no_cache   => 1,
                 check_only => 1,
                 mode       => 'commit',
diff --git a/lib/Code/TidyAll/t/Basic.pm b/lib/Code/TidyAll/t/Basic.pm
index 8e29a73..fa815d8 100644
--- a/lib/Code/TidyAll/t/Basic.pm
+++ b/lib/Code/TidyAll/t/Basic.pm
@@ -119,13 +119,17 @@ sub test_quiet_and_verbose : Tests {
                 $ct->process_files("$root_dir/foo.txt");
             };
             if ($error) {
-                like( $output, qr/non-alpha content found/ );
+                like( $output, qr/non-alpha content found/, "non-alpha content found ($state)" );
             }
             else {
                 is( $output, "[tidied]  foo.txt\n" ) if $state eq 'normal';
                 is( $output, "" ) if $state eq 'quiet';
-                like( $output,
-                    qr/constructing Code::TidyAll with these params.*purging old backups.*\[tidied\]  foo\.txt \(\+Code::TidyAll::Test::Plugin::UpperText\)/s
+                like( $output, qr/purging old backups/, "purging old backups ($state)" )
+                  if $state eq 'verbose';
+                like(
+                    $output,
+                    qr/\[tidied\]  foo\.txt \(\+Code::TidyAll::Test::Plugin::UpperText\)/s,
+                    "foo.txt ($state)"
                 ) if $state eq 'verbose';
             }
         }
@@ -205,8 +209,9 @@ sub test_errors : Tests {
     my $self = shift;
 
     my $root_dir = $self->create_dir( { "foo/bar.txt" => "abc" } );
-    throws_ok { Code::TidyAll->new( root_dir => $root_dir ) } qr/conf_file or plugins required/;
-    throws_ok { Code::TidyAll->new( plugins  => {} ) } qr/conf_file or root_dir required/;
+    throws_ok { Code::TidyAll->new( root_dir => $root_dir ) } qr/Missing required/;
+    throws_ok { Code::TidyAll->new( plugins  => {} ) } qr/Missing required/;
+
     throws_ok {
         Code::TidyAll->new(
             root_dir    => $root_dir,
@@ -216,11 +221,12 @@ sub test_errors : Tests {
         );
     }
     qr/unknown constructor param\(s\) 'bad_param', 'worse_param'/;
+
     throws_ok {
         Code::TidyAll->new(
             root_dir => $root_dir,
             plugins  => { 'DoesNotExist' => { select => '**/*' } }
-        );
+        )->plugin_objects;
     }
     qr/could not load plugin class/;
 
@@ -239,14 +245,15 @@ sub test_conf_file : Tests {
     my $conf_file = "$root_dir/tidyall.ini";
     write_file( $conf_file, $conf1 );
 
-    my $ct = Code::TidyAll->new( conf_file => $conf_file );
+    my $ct       = Code::TidyAll->new_from_conf_file($conf_file);
     my %expected = (
-        backup_ttl => 300,
-        no_backups => undef,
-        no_cache   => 1,
-        root_dir   => dirname($conf_file),
-        data_dir   => "$root_dir/.tidyall.d",
-        plugins    => {
+        backup_ttl      => '5m',
+        backup_ttl_secs => '300',
+        no_backups      => undef,
+        no_cache        => 1,
+        root_dir        => dirname($conf_file),
+        data_dir        => "$root_dir/.tidyall.d",
+        plugins         => {
             '+Code::TidyAll::Test::Plugin::UpperText' => { select => '**/*.txt' },
             '+Code::TidyAll::Test::Plugin::RepeatFoo' => { select => '**/foo*', times => 3 }
         }
@@ -266,6 +273,7 @@ sub test_cli : Tests {
     my $output = capture_stdout {
         system( "$^X", "bin/tidyall", "$root_dir/foo.txt", "-v" );
     };
+
     my ($params_msg) = ( $output =~ /constructing Code::TidyAll with these params:(.*)/ );
     ok( defined($params_msg), "params msg" );
     like( $params_msg, qr/backup_ttl => '15m'/,                              'backup_ttl' );

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libcode-tidyall-perl.git



More information about the Pkg-perl-cvs-commits mailing list