Code-TidyAll
view release on metacpan or search on metacpan
lib/Code/TidyAll/SVN/Precommit.pm view on Meta::CPAN
package Code::TidyAll::SVN::Precommit;
use strict;
use warnings;
use Capture::Tiny qw(capture_stdout capture_stderr);
use Code::TidyAll::Util qw(tempdir_simple);
use Code::TidyAll;
use Log::Any qw($log);
use Path::Tiny qw(path);
use SVN::Look;
use Try::Tiny;
use Moo;
our $VERSION = '0.85';
# Public
has conf_name => ( is => 'ro' );
has emergency_comment_prefix => ( is => 'ro', default => 'NO TIDYALL' );
has extra_conf_files => ( is => 'ro', default => sub { [] } );
has reject_on_error => ( is => 'ro' );
has repos => ( is => 'ro', default => sub { $ARGV[0] } );
has tidyall_class => ( is => 'ro', default => 'Code::TidyAll' );
has tidyall_options => ( is => 'ro', default => sub { {} } );
has txn => ( is => 'ro', default => sub { $ARGV[1] } );
# Private
has cat_file_cache => ( init_arg => undef, is => 'ro', default => sub { {} } );
has revlook => ( init_arg => undef, is => 'lazy' );
sub _build_revlook {
my $self = shift;
return SVN::Look->new( $self->repos, '-t' => $self->txn );
}
sub check {
my ( $class, %params ) = @_;
my $fail_msg;
try {
my $self = $class->new(%params);
my $revlook = $self->revlook;
# Skip if emergency comment prefix is present
#
if ( my $prefix = $self->emergency_comment_prefix ) {
if ( index( $revlook->log_msg, $prefix ) == 0 ) {
return;
}
}
my @files = ( $self->revlook->added(), $self->revlook->updated() );
$log->info('----------------------------');
$log->infof(
'%s [%s] repos = %s; txn = %s',
scalar(localtime), $$, scalar( getpwuid($<) ),
$self->repos, $self->txn
);
$log->infof( 'looking at files: %s', join( ', ', @files ) );
my %conf_files;
foreach my $file (@files) {
if ( my $conf_file = $self->find_conf_for_file($file) ) {
my $root = $conf_file->parent;
my $rel_file = substr( $file, length($root) + 1 );
$conf_files{$conf_file}->{$rel_file}++;
}
else {
my $msg = sprintf( q{** could not find conf file upwards from '%s'}, $file );
$log->error($msg);
die $msg if $self->reject_on_error;
}
}
my @results;
for my $conf_file ( map { path($_) } keys %conf_files ) {
my $file_map = $conf_files{$conf_file};
my $root = $conf_file->parent;
my $conf_name = $conf_file->basename;
$log->error("$root, $conf_file");
my $tempdir = tempdir_simple();
my @files = keys(%$file_map);
foreach my $rel_file ( $conf_name, @{ $self->extra_conf_files }, @files ) {
# TODO: what if cat fails
my $contents = $self->cat_file( $root->child($rel_file) );
my $full_path = $tempdir->child($rel_file);
$full_path->parent->mkpath( { mode => 0755 } );
$full_path->spew_raw($contents);
}
my $tidyall = $self->tidyall_class->new_from_conf_file(
$tempdir->child($conf_name),
no_cache => 1,
check_only => 1,
mode => 'commit',
%{ $self->tidyall_options },
);
my $stdout = capture_stdout {
push( @results, $tidyall->process_paths( map { $tempdir->child($_) } @files ) );
};
if ($stdout) {
chomp($stdout);
$log->info($stdout);
}
}
if ( my @error_results = grep { $_->error } @results ) {
my $error_count = scalar(@error_results);
$fail_msg = join(
"\n",
sprintf(
'%d file%s did not pass tidyall check',
$error_count, $error_count > 1 ? 's' : q{}
),
map { join( ': ', $_->path, $_->error ) } @error_results
( run in 1.558 second using v1.01-cache-2.11-cpan-39bf76dae61 )