view release on metacpan or search on metacpan
lib/Dist/Conformance.pm view on Meta::CPAN
elsif ( !$STATUSES{$status} ) {
( $status, $detail ) = ( 'fail', "the check returned the status $status, which is not pass, fail or info" );
}
$status = 'info' if $status eq 'fail' && $check->config->{level} eq 'info';
push @results, { check => $name, status => $status, detail => $detail // q{} };
}
return \@results;
}
sub update ( $self, %options ) {
my @results;
for my $check ( @{ $self->checks } ) {
my $update = Dist::Conformance::Update->new( snapshot => $self->snapshot, dry_run => $options{dry_run} // 0 );
if ( !eval { $check->update($update); 1 } ) {
$update->by_hand( 'The update died: ' . Dist::Conformance::Schema::first_line($@) );
}
push @results, { check => $check->name, changes => $update->changes, manual => $update->manual };
}
return \@results;
}
lib/Dist/Conformance/Check.pm view on Meta::CPAN
sub from_config ( $class, %arguments ) {
my $where = delete $arguments{where} // "the check $arguments{name}";
my $config = Dist::Conformance::Schema::validate( $arguments{config} // {}, $class->schema, $where );
return $class->new( %arguments, config => $config );
}
sub check ( $self, $ ) { die( ref($self) . " does not implement check\n" ) }
sub update ( $self, $update ) {
my ( $status, $detail ) = $self->check( $update->snapshot );
$update->by_hand( "$detail: " . $self->name . ' has no automatic fix' ) if $status eq 'fail';
return;
}
sub template ( $self, $path ) {
my $text = $self->source->file($path);
my $variables = $self->variables;
$text =~ s/\{\{ ([[:upper:]][[:upper:][:digit:]_]*) \}\}/exists $variables->{$1} ? $variables->{$1} : "{{$1}}"/ge;
lib/Dist/Conformance/Check.pm view on Meta::CPAN
sub config_schema ($class) {
return { required => ['file'], properties => { file => $Dist::Conformance::Schema::PATH, template => $Dist::Conformance::Schema::PATH } };
}
sub check ( $self, $snapshot ) {
my $file = $self->config->{file};
return $snapshot->contains($file) ? ( 'pass', "$file exists" ) : ( 'fail', "$file is missing" );
}
sub update ( $self, $update ) {
my $config = $self->config;
return if $update->snapshot->contains( $config->{file} );
return $self->write_template( $update, $config->{file}, $config->{template} ) if defined $config->{template};
return $update->by_hand("Write $config->{file}");
}
And in the flavor:
checks:
Readme:
lib/Dist/Conformance/Check/ClaudeMd.pm view on Meta::CPAN
sub check ( $self, $snapshot ) {
my ( $file, $mentions ) = @{ $self->config }{qw{file mentions}};
my $text = $snapshot->content($file) // return ( 'fail', "$file is missing" );
my @absent = grep { index( $text, $_ ) < 0 } @$mentions;
return ( 'fail', "$file does not name " . join ', ', @absent ) if @absent;
return ( 'pass', @$mentions ? 'names ' . join ', ', @$mentions : "$file exists" );
}
sub update ( $self, $update ) {
my ( $status, $detail ) = $self->check( $update->snapshot );
return if $status ne 'fail';
my $start = defined $self->config->{template} ? ', starting from ' . $self->config->{template} : q{};
$update->by_hand("$detail: write it by hand$start, because its prose cannot be generated");
return;
}
__END__
=pod
lib/Dist/Conformance/Check/ClaudeSettings.pm view on Meta::CPAN
my ( $file, $missing ) = @{ $self->config }{qw{file missing}};
my $settings = eval { $self->settings($snapshot) };
return ( 'fail', Dist::Conformance::Schema::first_line($@) ) if $@;
return ( $missing, "$file is missing" ) if !$settings;
my @disabled = $self->disabled($settings);
return ( $missing, 'does not enable ' . join ', ', @disabled ) if @disabled;
return ( 'pass', 'enables ' . join ', ', @{ $self->config->{plugins} } );
}
sub update ( $self, $update ) {
my $settings = eval { $self->settings( $update->snapshot ) };
if ($@) {
$update->by_hand( Dist::Conformance::Schema::first_line($@) . ': fix it by hand' );
return;
}
$settings //= {};
my @disabled = $self->disabled($settings);
return if !@disabled;
$settings->{enabledPlugins} = {} if ref $settings->{enabledPlugins} ne 'HASH';
$settings->{enabledPlugins}{$_} = Cpanel::JSON::XS::true() for @disabled;
lib/Dist/Conformance/Check/CriticProfile.pm view on Meta::CPAN
sub check ( $self, $snapshot ) {
my $file = $self->config->{file};
my $text = $snapshot->content($file) // return ( 'fail', "$file is missing" );
my ( $status, $detail ) = $self->verdict($text);
return ( $status, $detail );
}
sub update ( $self, $update ) {
my ( $file, $template ) = @{ $self->config }{qw{file template}};
my $text = $update->snapshot->content($file);
if ( defined $text ) {
my ( $status, undef, $by_hand ) = $self->verdict($text);
return if $status eq 'pass';
return $update->by_hand($by_hand) if !$self->config->{replace};
}
$self->write_template( $update, $file, $template );
return;
}
lib/Dist/Conformance/Check/DistFiles.pm view on Meta::CPAN
}
sub check ( $self, $snapshot ) {
my $marker = $self->config->{marker};
return ( $self->config->{absent}, "no $marker" ) if !$snapshot->contains($marker);
return $self->SUPER::check($snapshot);
}
sub update ( $self, $update ) {
return if !$update->snapshot->contains( $self->config->{marker} );
return $self->SUPER::update($update);
}
__END__
=pod
=encoding UTF-8
lib/Dist/Conformance/Check/GitHooks.pm view on Meta::CPAN
my $hooks = $self->config->{hooks};
my @names = sort keys %$hooks;
my @missing = $self->missing( $snapshot, map { $self->hook_path($_) } @names );
return ( 'fail', 'missing: ' . join ', ', @missing ) if @missing;
my @differ = grep { $snapshot->sha( $self->hook_path($_) ) ne Dist::Conformance::Snapshot::blob_sha( ( $self->template( $hooks->{$_} ) )[0] ) } @names;
return ( $self->config->{differ}, 'customized or outdated: ' . join ', ', map { $self->hook_path($_) } @differ ) if @differ;
return ( 'pass', 'match the templates' );
}
sub update ( $self, $update ) {
my ( $hooks, $replace, $install ) = @{ $self->config }{qw{hooks replace install}};
my $snapshot = $update->snapshot;
for my $name ( sort keys %$hooks ) {
my $path = $self->hook_path($name);
my ($text) = $self->template( $hooks->{$name} );
my $have = $snapshot->content($path);
if ( !defined $have || ( $replace && $have ne $text ) ) {
$have = $text if $self->write_template( $update, $path, $hooks->{$name}, oct 755 );
}
$update->install_hook( $name, $have ) if $install && defined $have;
lib/Dist/Conformance/Check/ToolConfiguration.pm view on Meta::CPAN
}
sub check ( $self, $snapshot ) {
my @missing = $self->missing( $snapshot, sort keys %{ $self->config->{files} } );
return ( 'fail', 'missing: ' . join ', ', @missing ) if @missing;
return ( 'pass', 'all present' );
}
sub update ( $self, $update ) {
my $files = $self->config->{files};
for my $path ( $self->missing( $update->snapshot, sort keys %$files ) ) {
if ( defined $files->{$path} ) {
$self->write_template( $update, $path, $files->{$path} );
}
else {
$update->by_hand("Write $path by hand: the flavor names no template for it");
}
}
return;
lib/Dist/Conformance/Check/Workflows.pm view on Meta::CPAN
if ( !%$required ) {
my @have = grep { index( $_, q{/} ) < 0 } $snapshot->under($directory);
return ( 'info', @have ? 'present: ' . join ', ', @have : 'none' );
}
my @missing = $self->missing_workflows($snapshot);
return ( 'fail', 'missing: ' . join ', ', map { "$directory/$_" } @missing ) if @missing;
return ( 'pass', 'all present' );
}
sub update ( $self, $update ) {
my ( $directory, $required ) = @{ $self->config }{qw{directory required}};
for my $name ( $self->missing_workflows( $update->snapshot ) ) {
if ( defined $required->{$name} ) {
$self->write_template( $update, "$directory/$name", $required->{$name} );
}
else {
$update->by_hand("Write $directory/$name by hand: the flavor names no template for it");
}
}
return;
t/Dist-Conformance-Update.t view on Meta::CPAN
use Test2::Plugin::NoWarnings;
use FindBin::libs;
use File::Temp();
use Mojo::File();
use Fixture();
use Dist::Conformance::Snapshot::Directory();
use Dist::Conformance::Snapshot::Tree();
use Dist::Conformance::Update();
sub update_of ( $root, $dry_run = 0 ) {
return Dist::Conformance::Update->new( snapshot => Dist::Conformance::Snapshot::Directory->new( root => $root ), dry_run => $dry_run );
}
subtest new => sub {
like( dies { Dist::Conformance::Update->new }, qr/needs\ a\ snapshot\ that\ it\ can\ write/, 'a snapshot is required' );
my $tree = Dist::Conformance::Snapshot::Tree->new( paths => {}, fetch => sub { } );
like( dies { Dist::Conformance::Update->new( snapshot => $tree ) }, qr/needs\ a\ snapshot\ that\ it\ can\ write/, 'and a tree cannot be updated' );
};
subtest write => sub {