Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: OR-ed plugins #77

Open
wants to merge 10 commits into
base: next
Choose a base branch
from
7 changes: 7 additions & 0 deletions lib/Git/Hooks.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,13 @@ is useful if you want to enable a plugin globally and only disable it for some
repositories. You can even re-enable it later, if you want, by mentioning it
again without the prefix.

Plugins can be OR-ed by separating them with a pipe (C<|>) instead of a space.

[githooks]
plugin = CheckFile|CheckJira CheckWhitespace

In this case CheckWhitespace C<AND> either CheckFile C<OR> CheckJira has to match.

=head2 [DEPRECATED after v3.3.0] disable PLUGIN...

B<This option is deprecated.> Please, use the C<githooks.plugin> option with an
Expand Down
20 changes: 16 additions & 4 deletions lib/Git/Repository/Plugin/GitHooks.pm
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ sub load_plugins {

my %plugins;

foreach my $plugin (map {split} $git->get_config(githooks => 'plugin')) {
foreach my $plugin (map {split /[\|\s]/} $git->get_config(githooks => 'plugin')) {
my ($negation, $prefix, $basename) = ($plugin =~ /^(\!?)((?:.+::)?)(.+)/);

if (exists $ENV{$basename} && ! $ENV{$basename}) {
Expand Down Expand Up @@ -803,10 +803,11 @@ sub fault {
my $colors = _githooks_colors($git);

my $msg;
my $prefix;

{
my $prefix = $info->{prefix} || caller;
my @context;
$prefix = $info->{prefix} || caller;
if (my $commit = $info->{commit}) {
$commit = $commit->commit
if ref $commit; # It's a Git::Repository::Log object
Expand Down Expand Up @@ -834,7 +835,7 @@ sub fault {
$msg .= "\n$colors->{details}$details$colors->{reset}\n\n";
}

push @{$git->{_plugin_githooks}{faults}}, $msg;
push @{$git->{_plugin_githooks}{faults}}, {msg => $msg, plugin => ($prefix) =~ /.*Git::Hooks::(\w+)/};

# Return true to allow for the idiom: <expression> or $git->fault(...) and <next|last|return>;
return 1;
Expand All @@ -853,7 +854,18 @@ sub get_faults {
$faults .= $colors->{header} . qx{$header} . "$colors->{reset}\n"; ## no critic (ProhibitBacktickOperators)
}

$faults .= join("\n\n", @{$git->{_plugin_githooks}{faults}});
my @conditions = split(" ", $git->get_config(githooks => 'plugin'));
map {s/(\||$)/(ok)$1/g} @conditions;

foreach my $fault (@{$git->{_plugin_githooks}{faults}}) {
map {s/($fault->{plugin})\(ok\)/$1(failed)/g} @conditions;
}

# If any parts of the condition don't have an 'OK', they've failed and we need to deny the commit
if (grep {!/\(ok\)/} @conditions) {
$faults .= join("\n\n", map {$_->{msg}} @{$git->{_plugin_githooks}{faults}});
$faults .= "\n\nOur configured plugins as they were evaluated:\n" . join(" ", @conditions) . "\n\n";
}

if ($git->{_plugin_githooks}{hookname} =~ /^commit-msg|pre-commit$/
&& ! $git->get_config_boolean(githooks => 'abort-commit')) {
Expand Down