[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