Dist-Conformance
view release on metacpan or search on metacpan
lib/Dist/Conformance/Check/GitHooks.pm view on Meta::CPAN
package Dist::Conformance::Check::GitHooks 0.003;
# ABSTRACT: The git hooks are tracked, match their templates, and are installed
use 5.040;
use warnings FATAL => 'all';
use re '/aasx';
use Mojo::Base 'Dist::Conformance::Check', -signatures;
use Dist::Conformance::Schema();
use Dist::Conformance::Snapshot();
sub config_schema ($) {
return {
required => [qw{directory hooks}],
properties => {
directory => $Dist::Conformance::Schema::PATH,
hooks => { type => 'object', additionalProperties => $Dist::Conformance::Schema::PATH },
differ => { %$Dist::Conformance::Schema::STATUS, default => 'info' },
replace => { type => 'boolean', default => 0 },
install => { type => 'boolean', default => 1 },
},
};
}
sub hook_path ( $self, $name ) { return $self->config->{directory} . "/$name" }
sub check ( $self, $snapshot ) {
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;
}
return;
}
__END__
=pod
=encoding UTF-8
=head1 NAME
Dist::Conformance::Check::GitHooks - The git hooks are tracked, match their templates, and are installed
=head1 VERSION
version 0.003
=head1 DESCRIPTION
Git neither versions nor clones hooks, so the hooks of the harness are tracked
in a directory of the repository, and each clone installs them.
The check fails when a hook is missing from C<directory>. It reports C<differ>
when a hook is there and its blob SHA differs from the SHA of its template:
the repository customized it, or it is older. Otherwise it passes. It compares
SHAs, so it reads no hook from a remote snapshot.
The update writes each missing hook from its template, executable. It
overwrites a hook that differs only when C<replace> is true. Then, when
C<install> is true, it installs each hook into F<.git/hooks> of the checkout,
or of the main checkout of a worktree, unless the installed hook is the same.
The check cannot see F<.git/hooks>, so a clone that never installed them passes
the check and still gets them from the update.
=head1 METHODS
=head2 hook_path
C<($name)>. The path of the hook C<$name> in the repository.
=head2 check
=head2 update
Writes the missing hooks, replaces those that differ if C<replace>, and
installs them if C<install>.
=head1 IN A FLAVOR
( run in 1.670 second using v1.01-cache-2.11-cpan-1236ad508bc )