diff --git a/lib/Git/Hooks/CheckJira.pm b/lib/Git/Hooks/CheckJira.pm index fce6788..8fbd880 100644 --- a/lib/Git/Hooks/CheckJira.pm +++ b/lib/Git/Hooks/CheckJira.pm @@ -9,7 +9,7 @@ use Log::Any '$log'; use Git::Hooks; use Git::Repository::Log; use Path::Tiny; -use List::MoreUtils qw/last_index uniq/; +use List::MoreUtils qw/any last_index uniq/; my $PKG = __PACKAGE__; my $CFG = __PACKAGE__ =~ s/.*::/githooks./r; @@ -124,6 +124,16 @@ sub _jql_query { return $cache->{jql}{$jql}; } +sub _skip_logs { + my ($git, $commit) = @_; + + my $cache = $git->cache($PKG); + $cache->{skip_logs_regexes} = [map {qr/$_/} $git->get_config($CFG => 'skip-logs')] + unless exists $cache->{skip_logs_regexes}; + my $message = $commit->message; + return any {$message =~ $_} $cache->{skip_logs_regexes}->@*; +} + sub _disconnect_jira { my ($git) = @_; delete $git->cache($PKG)->{jira}; @@ -378,6 +388,8 @@ sub check_commit_msg { if ($commit->parent() > 1 && $git->get_config_boolean($CFG => 'skip-merges')) { return 1; + } elsif (_skip_logs($git, $commit)) { + return 1; } else { return _check_jira_keys($git, $commit, $ref, uniq(grok_msg_jiras($git, $commit->message))); } @@ -572,6 +584,17 @@ may configure it in a Git configuration file like this: # fixVersion named after the same major.minor version number. fixversion = ^refs/heads/(\\d+\\.\\d+)\\. ^$+ + # Skip commits created by git-merge. Although, it's better to use the + # skip-merges directive for this. See below. + skip-logs = ^Merge\\s + # Skip commits created by git-revert + skip-logs = ^(?:Reapply|Revert)\\s + # Skip commits with a special mark in them + skip-logs = DONT-CheckJira + + # Skip merge commits + skip-merges + =head1 DESCRIPTION This L plugin hooks itself to the hooks below to guarantee that @@ -952,6 +975,15 @@ In this case, the visibility isn't restricted at all. =back +=head2 skip-logs REGEXP + +Use this multi-valued directive to make CheckJira don't check +commits which log messages match any of the REGEXes specified with it. + +As the examples in the L section shows, you may want to make CheckJira +skip commits automatically created by C commands, or to skip commits +with a special mark in them. + =head2 skip-merges BOOL By default, all commits are checked. You can exempt merge commits from being diff --git a/lib/Git/Repository/Plugin/GitHooks.pm b/lib/Git/Repository/Plugin/GitHooks.pm index 6fbc039..36c93ca 100644 --- a/lib/Git/Repository/Plugin/GitHooks.pm +++ b/lib/Git/Repository/Plugin/GitHooks.pm @@ -607,40 +607,38 @@ sub get_config { local $/ = "\c@"; $git->run(qw/config --null --list/); }; + $config //= ''; if (defined $CONFIG_ENCODING) { require Encode; $config = Encode::decode($CONFIG_ENCODING, $config); } - if (defined $config) { - # The --null option to git-config makes it output a null character - # after each option/value. The option and value are separated by a - # newline, unless there is no value, in which case, there is no - # newline. - while ($config =~ /([^\cJ]+)(\cJ[^\c@]*|)\c@/sg) { - my ($option, $value) = ($1, $2); - if ($option =~ /(.+)\.(.+)/) { - my ($osection, $okey) = (lc $1, lc $2); - if ($value =~ s/^\cJ//) { - ## no critic (ProhibitDeepNests) - if ($value eq 'undef') { - # The 'undef' string is a special mark telling us to - # disregard every previous value already set for - # this variable. - delete $config{$osection}{$okey}; - } else { - push @{$config{$osection}{$okey}}, $value; - } + # The --null option to git-config makes it output a null character + # after each option/value. The option and value are separated by a + # newline, unless there is no value, in which case, there is no + # newline. + while ($config =~ /([^\cJ]+)(\cJ[^\c@]*|)\c@/sg) { + my ($option, $value) = ($1, $2); + if ($option =~ /(.+)\.(.+)/) { + my ($osection, $okey) = (lc $1, lc $2); + if ($value =~ s/^\cJ//) { + if ($value eq 'undef') { + # The 'undef' string is a special mark telling us to + # disregard every previous value already set for + # this variable. + delete $config{$osection}{$okey}; } else { - # An option without a value is considered a boolean - # true. We mark it explicitly so instead of leaving it - # undefined because Perl would consider it false. - push @{$config{$osection}{$okey}}, 'true'; + push @{$config{$osection}{$okey}}, $value; } } else { - croak __PACKAGE__, ": Cannot grok config variable name '$option'.\n"; + # An option without a value is considered a boolean + # true. We mark it explicitly so instead of leaving it + # undefined because Perl would consider it false. + push @{$config{$osection}{$okey}}, 'true'; } + } else { + croak __PACKAGE__, ": Cannot grok config variable name '$option'.\n"; } }