Skip to content

Commit 543a418

Browse files
committed
Support custom hooks directory
Git supports the `core.hooksPath` configuration setting as of Git 2.9. Use it when installing hooks if it is defined. Closes sds#447
1 parent 4afe59d commit 543a418

File tree

5 files changed

+81
-2
lines changed

5 files changed

+81
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## master
44

55
* Add [`hadolint`](https://github.com/lukasmartinelli/hadolint) pre-commit hook
6+
* Use the `core.hooksPath` Git configuration option when installing hooks
67

78
## 0.39.1
89

lib/overcommit/git_config.rb

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'overcommit/utils'
2+
13
module Overcommit
24
# Get configuration options from git
35
module GitConfig
@@ -8,5 +10,11 @@ def comment_character
810
char = '#' if char == ''
911
char
1012
end
13+
14+
def hooks_path
15+
path = `git config --get core.hooksPath`.chomp
16+
return File.join(Overcommit::Utils.repo_root, '.git', 'hooks') if path.empty?
17+
File.absolute_path(path)
18+
end
1119
end
1220
end

lib/overcommit/installer.rb

+1-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ def update
6565
end
6666

6767
def hooks_path
68-
absolute_target = File.expand_path(@target)
69-
File.join(Overcommit::Utils.git_dir(absolute_target), 'hooks')
68+
@hooks_path ||= Dir.chdir(@target) { GitConfig.hooks_path }
7069
end
7170

7271
def old_hooks_path

spec/overcommit/git_config_spec.rb

+55
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,59 @@
2222
end
2323
end
2424
end
25+
26+
describe '.hooks_path' do
27+
subject { described_class.hooks_path }
28+
29+
context 'when not explicitly set' do
30+
around do |example|
31+
repo do
32+
example.run
33+
end
34+
end
35+
36+
it 'returns the default hook path' do
37+
expect(subject).to eq File.expand_path(File.join('.git', 'hooks'))
38+
end
39+
end
40+
41+
context 'when explicitly set to an empty string' do
42+
around do |example|
43+
repo do
44+
`git config --local core.hooksPath ""`
45+
example.run
46+
end
47+
end
48+
49+
it 'returns the default hook path' do
50+
expect(subject).to eq File.expand_path(File.join('.git', 'hooks'))
51+
end
52+
end
53+
54+
context 'when explicitly set to an absolute path' do
55+
around do |example|
56+
repo do
57+
`git config --local core.hooksPath /etc/hooks`
58+
example.run
59+
end
60+
end
61+
62+
it 'returns the absolute path' do
63+
expect(subject).to eq '/etc/hooks'
64+
end
65+
end
66+
67+
context 'when explicitly set to a relative path' do
68+
around do |example|
69+
repo do
70+
`git config --local core.hooksPath my-hooks`
71+
example.run
72+
end
73+
end
74+
75+
it 'returns the absolute path to the directory relative to the repo root' do
76+
expect(subject).to eq File.expand_path('my-hooks')
77+
end
78+
end
79+
end
2580
end

spec/overcommit/installer_spec.rb

+16
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,22 @@ def hook_files_installed?(hooks_dir)
142142
}.from(false).to(true)
143143
end
144144
end
145+
146+
context 'and a custom core.hooksPath directory is set' do
147+
around do |example|
148+
Dir.chdir(target) do
149+
FileUtils.mkdir 'my-hooks'
150+
`git config core.hooksPath my-hooks`
151+
example.run
152+
end
153+
end
154+
155+
it 'installs the hooks in the custom directory' do
156+
expect { subject }.to change { hook_files_installed?(File.join(target, 'my-hooks')) }.
157+
from(false).
158+
to(true)
159+
end
160+
end
145161
end
146162

147163
context 'and an uninstall is requested' do

0 commit comments

Comments
 (0)