From 872d3eeb34c902e142df74738f3fa25a4bc4e365 Mon Sep 17 00:00:00 2001 From: Taufek Johar Date: Sun, 13 Oct 2019 22:02:48 +0800 Subject: [PATCH] Introduce `exclude_branch_patterns` on Hook Config Context = This will allow user to skip any Hook based on branch patterns. For example, if the user wish to skip a particular Hook (i.e. Rubocop) for `staging` branch, the user could specify below ``` PreCommit: Rubocop: exclude_branch_patterns: ['staging'] ``` or using glob partial pattern ``` PreCommit: Rubocop: exclude_branch_patterns: ['stag*'] ``` By default `exclude_branch_patterns` is empty (includes all branches). --- lib/overcommit/hook/base.rb | 13 +++++ spec/overcommit/hook/base_spec.rb | 88 +++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/lib/overcommit/hook/base.rb b/lib/overcommit/hook/base.rb index bd1954d3..bcdb02a8 100644 --- a/lib/overcommit/hook/base.rb +++ b/lib/overcommit/hook/base.rb @@ -79,12 +79,17 @@ def enabled? @config['enabled'] != false end + def excluded? + exclude_branch_patterns.any? { |p| File.fnmatch(p, current_branch) } + end + def skip? @config['skip'] end def run? enabled? && + !excluded? && !(@config['requires_files'] && applicable_files.empty?) end @@ -276,5 +281,13 @@ def transform_status(status) status end end + + def exclude_branch_patterns + @config['exclude_branch_patterns'] || [] + end + + def current_branch + @current_branch ||= Overcommit::GitRepo.current_branch + end end end diff --git a/spec/overcommit/hook/base_spec.rb b/spec/overcommit/hook/base_spec.rb index 012b764c..5b3f0feb 100644 --- a/spec/overcommit/hook/base_spec.rb +++ b/spec/overcommit/hook/base_spec.rb @@ -34,4 +34,92 @@ end end end + + describe '#run?' do + let(:modified_files) { [] } + let(:hook_config) do + { + 'enabled' => enabled, + 'requires_files' => requires_files, + } + end + + before do + config.stub(:for_hook).and_return(hook_config) + context.stub(:modified_files).and_return(modified_files) + end + + subject { hook.run? } + + context 'enabled is true, requires_files is false, modified_files empty' do + let(:enabled) { true } + let(:requires_files) { false } + + it { subject.should == true } + end + + context 'enabled is false, requires_files is false, modified_files empty' do + let(:enabled) { false } + let(:requires_files) { false } + + it { subject.should == false } + end + + context 'enabled is true, requires_files is true, modified_files is not empty' do + let(:enabled) { true } + let(:requires_files) { true } + let(:modified_files) { ['file1'] } + + it { subject.should == true } + end + + context 'enabled is true, requires_files is false, modified_files is not empty' do + let(:enabled) { true } + let(:requires_files) { false } + let(:modified_files) { ['file1'] } + + it { subject.should == true } + end + + context 'with exclude_branch_patterns' do + let(:current_branch) { 'tj-test-branch' } + let(:hook_config) do + { + 'enabled' => true, + 'requires_files' => false, + 'exclude_branch_patterns' => exclude_branch_patterns + } + end + + before do + allow(Overcommit::GitRepo). + to receive(:current_branch). + and_return(current_branch) + end + + context 'exclude_branch_patterns is nil' do + let(:exclude_branch_patterns) { nil } + + it { subject.should == true } + end + + context 'exact match between exclude_branch_patterns and current_branch' do + let(:exclude_branch_patterns) { ['tj-test-branch'] } + + it { subject.should == false } + end + + context 'partial match between exclude_branch_patterns and current_branch' do + let(:exclude_branch_patterns) { ['tj-test-*'] } + + it { subject.should == false } + end + + context 'non-match between exclude_branch_patterns and current_branch' do + let(:exclude_branch_patterns) { ['test-*'] } + + it { subject.should == true } + end + end + end end