Dist-Conformance

 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 {



( run in 2.116 seconds using v1.01-cache-2.11-cpan-1236ad508bc )