Skip to content

Commit 42bb495

Browse files
committed
Fix AuthorName/AuthorEmail to respect env variables
When committing, the `GIT_AUTHOR_{NAME,EMAIL}` environment variables take precedence over Git configuration values. Ensure these are recognized by the hook. This required a change to the commit integration spec since GIT_AUTHOR_NAME/GIT_AUTHOR_EMAIL is set by git before it executes the hook, so even if you set the local configuration to an empty string it will fall back to using the global configuration.
1 parent af8257f commit 42bb495

File tree

6 files changed

+101
-52
lines changed

6 files changed

+101
-52
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Overcommit Changelog
22

3+
## master (unreleased)
4+
5+
* Fix `AuthorName`/`AuthorEmail` pre-commit hooks to respect
6+
`GIT_AUTHOR_NAME`/`GIT_AUTHOR_EMAIL` environment variables, respectively
7+
38
## 0.32.0
49

510
### New Features

lib/overcommit/hook/pre_commit/author_email.rb

+9-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@ module Overcommit::Hook::PreCommit
22
# Checks the format of an author's email address.
33
class AuthorEmail < Base
44
def run
5-
result = execute(%w[git config --get user.email])
6-
email = result.stdout.chomp
5+
email =
6+
if ENV.key?('GIT_AUTHOR_EMAIL')
7+
ENV['GIT_AUTHOR_EMAIL']
8+
else
9+
result = execute(%w[git config --get user.email])
10+
result.stdout.chomp
11+
end
712

813
unless email =~ /#{config['pattern']}/
914
return :fail,
1015
"Author has an invalid email address: '#{email}'\n" \
1116
'Set your email with ' \
12-
'`git config --global user.email your_email@example.com`'
17+
'`git config --global user.email your_email@example.com` ' \
18+
'or via the GIT_AUTHOR_EMAIL environment variable'
1319
end
1420

1521
:pass

lib/overcommit/hook/pre_commit/author_name.rb

+9-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@ module Overcommit::Hook::PreCommit
22
# Ensures that a commit author has a name with at least first and last names.
33
class AuthorName < Base
44
def run
5-
result = execute(%w[git config --get user.name])
6-
name = result.stdout.chomp
5+
name =
6+
if ENV.key?('GIT_AUTHOR_NAME')
7+
ENV['GIT_AUTHOR_NAME']
8+
else
9+
result = execute(%w[git config --get user.name])
10+
result.stdout.chomp
11+
end
712

813
unless name.split(' ').count >= 2
914
return :fail,
1015
"Author must have at least first and last name, but was: #{name}.\n" \
11-
'Set your name with `git config --global user.name "Your Name"`'
16+
'Set your name with `git config --global user.name "Your Name"` ' \
17+
'or via the GIT_AUTHOR_NAME environment variable'
1218
end
1319

1420
:pass

spec/integration/committing_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
context 'when a hook fails' do
2626
before do
27-
`git config --local user.name ""`
27+
`git config --local user.name "John"`
2828
end
2929

3030
it 'exits with a non-zero status' do

spec/overcommit/hook/pre_commit/author_email_spec.rb

+48-32
Original file line numberDiff line numberDiff line change
@@ -6,50 +6,66 @@
66
subject { described_class.new(config, context) }
77
let(:result) { double('result') }
88

9-
before do
10-
result.stub(:stdout).and_return(email)
11-
subject.stub(:execute).and_return(result)
12-
end
13-
14-
context 'when user has no email' do
15-
let(:email) { '' }
9+
shared_examples_for 'author email check' do
10+
context 'when user has no email' do
11+
let(:email) { '' }
1612

17-
it { should fail_hook }
18-
end
13+
it { should fail_hook }
14+
end
1915

20-
context 'when user has an invalid email' do
21-
let(:email) { 'Invalid Email' }
16+
context 'when user has an invalid email' do
17+
let(:email) { 'Invalid Email' }
2218

23-
it { should fail_hook }
24-
end
19+
it { should fail_hook }
20+
end
2521

26-
context 'when user has a valid email' do
27-
let(:email) { 'email@example.com' }
22+
context 'when user has a valid email' do
23+
let(:email) { 'email@example.com' }
2824

29-
it { should pass }
30-
end
25+
it { should pass }
26+
end
3127

32-
context 'when a custom pattern is specified' do
33-
let(:config) do
34-
super().merge(Overcommit::Configuration.new(
35-
'PreCommit' => {
36-
'AuthorEmail' => {
37-
'pattern' => '^[^@]+@brigade\.com$'
28+
context 'when a custom pattern is specified' do
29+
let(:config) do
30+
super().merge(Overcommit::Configuration.new(
31+
'PreCommit' => {
32+
'AuthorEmail' => {
33+
'pattern' => '^[^@]+@brigade\.com$'
34+
}
3835
}
39-
}
40-
))
41-
end
36+
))
37+
end
4238

43-
context 'and the email does not match the pattern' do
44-
let(:email) { 'email@example.com' }
39+
context 'and the email does not match the pattern' do
40+
let(:email) { 'email@example.com' }
4541

46-
it { should fail_hook }
42+
it { should fail_hook }
43+
end
44+
45+
context 'and the email matches the pattern' do
46+
let(:email) { 'email@brigade.com' }
47+
48+
it { should pass }
49+
end
4750
end
51+
end
4852

49-
context 'and the email matches the pattern' do
50-
let(:email) { 'email@brigade.com' }
53+
context 'when email is set via config' do
54+
before do
55+
result.stub(:stdout).and_return(email)
56+
subject.stub(:execute).and_return(result)
57+
end
5158

52-
it { should pass }
59+
it_should_behave_like 'author email check'
60+
end
61+
62+
context 'when email is set via environment variable' do
63+
around do |example|
64+
Overcommit::Utils.with_environment 'GIT_AUTHOR_EMAIL' => email do
65+
example.run
66+
end
5367
end
68+
69+
it_should_behave_like 'author email check'
5470
end
5571
end

spec/overcommit/hook/pre_commit/author_name_spec.rb

+29-13
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,42 @@
66
subject { described_class.new(config, context) }
77
let(:result) { double('result') }
88

9-
before do
10-
result.stub(:stdout).and_return(name)
11-
subject.stub(:execute).and_return(result)
12-
end
9+
shared_examples_for 'author name check' do
10+
context 'when user has no name' do
11+
let(:name) { '' }
12+
13+
it { should fail_hook }
14+
end
15+
16+
context 'when user has only a first name' do
17+
let(:name) { 'John' }
18+
19+
it { should fail_hook }
20+
end
1321

14-
context 'when user has no name' do
15-
let(:name) { '' }
22+
context 'when user has first and last name' do
23+
let(:name) { 'John Doe' }
1624

17-
it { should fail_hook }
25+
it { should pass }
26+
end
1827
end
1928

20-
context 'when user has only a first name' do
21-
let(:name) { 'John' }
29+
context 'when name is set via config' do
30+
before do
31+
result.stub(:stdout).and_return(name)
32+
subject.stub(:execute).and_return(result)
33+
end
2234

23-
it { should fail_hook }
35+
it_should_behave_like 'author name check'
2436
end
2537

26-
context 'when user has first and last name' do
27-
let(:name) { 'John Doe' }
38+
context 'when name is set via environment variable' do
39+
around do |example|
40+
Overcommit::Utils.with_environment 'GIT_AUTHOR_NAME' => name do
41+
example.run
42+
end
43+
end
2844

29-
it { should pass }
45+
it_should_behave_like 'author name check'
3046
end
3147
end

0 commit comments

Comments
 (0)