package Git::MoreHooks::CheckCommitBase;

use strict;
use warnings;
use utf8;

# ABSTRACT: CheckCommit base file

our $VERSION = '0.015'; # VERSION: generated by DZP::OurPkgVersion

use Git::Hooks 3.000000;
use Path::Tiny;
use Log::Any qw{$log};
use Params::Validate qw(:all);

our $USER_HOOK;

sub import {
    my ( $package, $user_hook ) = @_;
    $package .= q{};
    $USER_HOOK = $user_hook;
    return;
}

sub _call_user_hook {
    return &{$USER_HOOK}(@_);
}

sub pre_commit_callback {
    my ($git) = @_;
    my %opts = ( 'old_commit' => ':0', 'new_commit' => undef, 'gerrit-opts' => undef );
    return _call_user_hook( $git, 'pre-commit', \%opts );
}

# This routine can act both as an update or a pre-receive hook.
sub update_callback {
    $log->tracef( 'Entering update_callback(%s)', ( join q{:}, @_ ) );
    my ($git) = @_;
    my %opts = ( 'old_commit' => ':0', 'new_commit' => 0, 'gerrit-opts' => undef );
    return _call_user_hook( $git, 'update', \%opts );
}

sub pre_receive_callback {
    $log->tracef( 'Entering pre_receive_callback(%s)', ( join q{:}, @_ ) );
    my ($git) = @_;
    my %opts = ( 'old_commit' => ':0', 'new_commit' => 0, 'gerrit-opts' => undef );
    return _call_user_hook( $git, 'pre-receive', \%opts );
}

sub ref_update_callback {
    my ($git) = @_;
    my %opts = ( 'old_commit' => ':0', 'new_commit' => 0, 'gerrit-opts' => undef );
    return _call_user_hook( $git, 'ref-update', \%opts );
}

sub patchset_created_callback {
    my ( $git, $opts ) = @_;
    my %opts = ( 'old_commit' => ':0', 'new_commit' => 0, 'gerrit-opts' => $opts );
    return _call_user_hook( $git, 'patchset-created', \%opts );
}

sub draft_published_callback {
    my ( $git, $opts ) = @_;
    my %opts = ( 'old_commit' => ':0', 'new_commit' => 0, 'gerrit-opts' => $opts );
    return _call_user_hook( $git, 'draft-published', \%opts );
}

# Install hooks
PRE_COMMIT \&pre_commit_callback;
UPDATE \&update_callback;
PRE_RECEIVE \&pre_receive_callback;
REF_UPDATE \&ref_update_callback;
PATCHSET_CREATED \&patchset_created_callback;
DRAFT_PUBLISHED \&draft_published_callback;

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Git::MoreHooks::CheckCommitBase - CheckCommit base file

=head1 VERSION

version 0.015

=head1 SYNOPSIS

Use package via
L<Git::Hooks|Git::Hooks>
interface (git config file).

=head1 DESCRIPTION

Base for Commit checking hooks.

=head1 STATUS

Package Git::MoreHooks is currently being developed so changes in the existing hooks are possible.

=head1 USAGE

    use Git::MoreHooks::CheckCommitBase;
    $::ROOT_FUNC = \&my_check_function;

Alternatively:

    use Git::MoreHooks::CheckCommitBase \&my_check_function;

Git::MoreHooks::CheckCommitBase hooks itself to the hooks below:

=over

=item * B<pre-commit>

This hook is invoked during the commit.

=item * B<update>

This hook is invoked multiple times in the remote repository during
C<git push>, once per branch being updated.

=item * B<pre-receive>

This hook is invoked once in the remote repository during C<git push>.

=item * B<ref-update>

This hook is invoked when a push request is received by Gerrit Code
Review.

=item * B<patchset-created>

This hook is invoked when a push request is received by Gerrit Code
Review for a virtual branch (refs/for/*).

=item * B<draft-published>

The draft-published hook is executed when the user publishes a draft change,
making it visible to other users.

=back

=head1 CONFIGURATION

This plugin is configured by the following git options.

=head2 githooks.<check-commit-hook-name>.ref REFSPEC

By default, the message of every commit is checked. If you want to
have them checked only for some refs (usually some branch under
refs/heads/), you may specify them with one or more instances of this
option.

The refs can be specified as a complete ref name
(e.g. "refs/heads/master") or by a regular expression starting with a
caret (C<^>), which is kept as part of the regexp
(e.g. "^refs/heads/(master|fix)").

=head1 EXPORTS

This module exports the following routines that can be used directly
without using all of Git::Hooks infrastructure.

=head2 pre_commit_callback GIT

This is the routine used to implement the C<pre-commit> hook. It needs
a C<Git::More> object.

=head2 update_callback GIT

This is the routine used to implement the C<update> hook. It needs
a C<Git::More> object.

=head2 pre_receive_callback GIT, COMMIT

This is the routine used to implement the C<pre-receive> hook. It needs
a C<Git::More> object and a commit hash from C<Git::More::get_commit()>.

=head2 ref_update_callback GIT

This is the routing used to implement the C<update> and the
C<pre-receive> hooks. It needs a C<Git::More> object.

=head2 patchset_created_callback GIT, HASH

This is the routine used to implement the C<patchset-created> Gerrit
hook. It needs a C<Git::More> object and the hash containing the
arguments passed to the hook by Gerrit.

=head2 draft_published_callback GIT, HASH

This is the routine used to implement the C<draft-published> Gerrit
hook. It needs a C<Git::More> object and the hash containing the
arguments passed to the hook by Gerrit.

=head1 NOTES

Thanks go to Gustavo Leite de Mendonça Chaves for his
L<Git::Hooks|https://metacpan.org/pod/Git::Hooks> package.

=head1 SUBROUTINES/METHODS

=head1 AUTHOR

'Mikko Koivunalho <mikko.koivunalho@iki.fi>'

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2022 by Mikko Koivunalho.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
