Skip to content

Commit fcd5315

Browse files
Add functional tests for mailmap handling.
1 parent e33f1d2 commit fcd5315

3 files changed

Lines changed: 305 additions & 4 deletions

File tree

internal/git/config/config.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ func repoMailmapPath(gitRootPath string) string {
1818
return path
1919
}
2020

21+
// Looks up a file pointed to by the mailmap.file setting in the git config.
2122
func globalMailmapPath() (string, error) {
2223
ctx, cancel := context.WithCancel(context.Background())
2324
defer cancel()
@@ -54,8 +55,10 @@ func globalMailmapPath() (string, error) {
5455
return p, nil
5556
}
5657

57-
// NOTE: We do NOT respect the git config here, we just assume the conventional
58-
// path for this file in the repo.
58+
// NOTE: We do NOT respect the blame.ignoreRevsFile option in the git config
59+
// here, we just assume the conventional path for this file in the repo.
60+
//
61+
// The option can be specified multiple times which makes it a tad complicated.
5962
func ignoreRevsPath(gitRootPath string) string {
6063
path := filepath.Join(gitRootPath, ".git-blame-ignore-revs")
6164
return path

test/functional/lib/cmd.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,19 @@ def initialize(exec_path, rundir)
1212
@rundir = rundir
1313
end
1414

15-
def run(*args, cache_home: nil, n_procs: nil)
15+
def run(*args, cache_home: nil, config_home: nil, n_procs: nil)
1616
env_hash = {}
1717

1818
if cache_home
19-
env_hash['XDG_CACHE_HOME'] = cache_home
19+
env_hash['XDG_CACHE_HOME'] = cache_home.to_s
2020
else
2121
env_hash['GIT_WHO_DISABLE_CACHE'] = '1'
2222
end
2323

24+
if config_home
25+
env_hash['XDG_CONFIG_HOME'] = config_home.to_s
26+
end
27+
2428
unless n_procs.nil?
2529
env_hash['GOMAXPROCS'] = n_procs.to_s
2630
end

test/functional/mailmap_test.rb

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
require 'csv'
2+
require 'fileutils'
3+
require 'pathname'
4+
require 'tmpdir'
5+
6+
require 'minitest/autorun'
7+
8+
require 'lib/cmd'
9+
require 'lib/repo'
10+
11+
# Tests how git who handles mailmap files.
12+
#
13+
# We read mailmap files from potentially two places: the conventional "local"
14+
# .mailmap file in the repo, but also a "global" mailmap file at an arbitrary
15+
# path pointed to by the mailmap.file git config option.
16+
#
17+
# We want to respect any mappings defined in those files when producing results.
18+
# Because mailmapping might change the author name and email that should be
19+
# attached to any cached commits, changing either the local or global mailmaps
20+
# should invalidate the cache.
21+
class TestMailmap < Minitest::Test
22+
def teardown
23+
# Err, cleanup if a test failed and didn't remove this file
24+
FileUtils.rm_rf Pathname.new(BigRepo.path) / ".mailmap"
25+
end
26+
27+
def test_local_mailmap
28+
Dir.mktmpdir do |dir|
29+
# Try with no mailmap
30+
cmd = GitWho.new(GitWho.built_bin_path, BigRepo.path)
31+
stdout_s = cmd.run 'table', '--csv', '-e', cache_home: dir
32+
refute_empty(stdout_s)
33+
34+
data = CSV.parse(stdout_s, headers: true)
35+
assert_equal data[0]['name'], 'Benoit Chesneau'
36+
assert_equal data[0]['email'], 'bchesneau@gmail.com'
37+
assert_equal data[0]['commits'], '1147'
38+
39+
# Try with mailmap, does it invalidate cache?
40+
mailmap_path = Pathname.new(BigRepo.path) / ".mailmap"
41+
File.write(mailmap_path, LOCAL_MAILMAP)
42+
43+
stdout_s = cmd.run 'table', '--csv', '-e', cache_home: dir
44+
refute_empty(stdout_s)
45+
46+
data = CSV.parse(stdout_s, headers: true)
47+
assert_equal data[0]['name'], 'Benoit Chesneau'
48+
assert_equal data[0]['email'], 'bchesneau@gmail.com'
49+
assert_equal data[0]['commits'], '1322'
50+
51+
# Try without mailmap again, does it invalidate cache?
52+
File.delete(mailmap_path)
53+
54+
stdout_s = cmd.run 'table', '--csv', '-e', cache_home: dir
55+
refute_empty(stdout_s)
56+
57+
data = CSV.parse(stdout_s, headers: true)
58+
assert_equal data[0]['name'], 'Benoit Chesneau'
59+
assert_equal data[0]['email'], 'bchesneau@gmail.com'
60+
assert_equal data[0]['commits'], '1147'
61+
end
62+
end
63+
64+
def test_global_mailmap
65+
Dir.mktmpdir do |dir|
66+
dir = Pathname.new(dir)
67+
cache_home = dir / ".cache"
68+
config_home = dir / ".config"
69+
cache_home.mkdir
70+
config_home.mkdir
71+
72+
# Try with no mailmap
73+
cmd = GitWho.new(GitWho.built_bin_path, BigRepo.path)
74+
stdout_s = cmd.run(
75+
'table',
76+
'--csv',
77+
'-e',
78+
cache_home: cache_home,
79+
config_home: config_home,
80+
)
81+
refute_empty(stdout_s)
82+
83+
data = CSV.parse(stdout_s, headers: true)
84+
assert_equal data[3]['name'], 'Randall Leeds'
85+
assert_equal data[3]['email'], 'randall@bleeds.info'
86+
assert_equal data[3]['commits'], '110'
87+
88+
# Try with mailmap, does it invalidate cache?
89+
git_dir = config_home / "git"
90+
git_dir.mkdir
91+
92+
mailmap_path = git_dir / ".mailmap"
93+
File.write(mailmap_path, GLOBAL_MAILMAP)
94+
95+
git_config_path = git_dir / "config"
96+
File.write(git_config_path, "[mailmap]\n\tfile = #{mailmap_path}")
97+
98+
stdout_s = cmd.run(
99+
'table',
100+
'--csv',
101+
'-e',
102+
cache_home: cache_home,
103+
config_home: config_home,
104+
)
105+
refute_empty(stdout_s)
106+
107+
data = CSV.parse(stdout_s, headers: true)
108+
assert_equal data[2]['name'], 'Randall Leeds'
109+
assert_equal data[2]['email'], 'randall@bleeds.info'
110+
assert_equal data[2]['commits'], '157'
111+
112+
# Try without mailmap again, does it invalidate cache?
113+
File.delete(git_config_path)
114+
115+
stdout_s = cmd.run(
116+
'table',
117+
'--csv',
118+
'-e',
119+
cache_home: cache_home,
120+
config_home: config_home,
121+
)
122+
refute_empty(stdout_s)
123+
124+
data = CSV.parse(stdout_s, headers: true)
125+
assert_equal data[3]['name'], 'Randall Leeds'
126+
assert_equal data[3]['email'], 'randall@bleeds.info'
127+
assert_equal data[3]['commits'], '110'
128+
end
129+
end
130+
131+
def test_both_mailmap
132+
Dir.mktmpdir do |dir|
133+
dir = Pathname.new(dir)
134+
cache_home = dir / ".cache"
135+
config_home = dir / ".config"
136+
cache_home.mkdir
137+
config_home.mkdir
138+
139+
# Try with no mailmap
140+
cmd = GitWho.new(GitWho.built_bin_path, BigRepo.path)
141+
stdout_s = cmd.run(
142+
'table',
143+
'--csv',
144+
'-e',
145+
cache_home: cache_home,
146+
config_home: config_home,
147+
)
148+
refute_empty(stdout_s)
149+
150+
data = CSV.parse(stdout_s, headers: true)
151+
assert_equal data[0]['name'], 'Benoit Chesneau'
152+
assert_equal data[0]['email'], 'bchesneau@gmail.com'
153+
assert_equal data[0]['commits'], '1147'
154+
assert_equal data[3]['name'], 'Randall Leeds'
155+
assert_equal data[3]['email'], 'randall@bleeds.info'
156+
assert_equal data[3]['commits'], '110'
157+
158+
# Try with one mailmap, does it invalidate cache?
159+
local_mailmap_path = Pathname.new(BigRepo.path) / ".mailmap"
160+
File.write(local_mailmap_path, LOCAL_MAILMAP)
161+
162+
stdout_s = cmd.run(
163+
'table',
164+
'--csv',
165+
'-e',
166+
cache_home: cache_home,
167+
config_home: config_home,
168+
)
169+
refute_empty(stdout_s)
170+
171+
data = CSV.parse(stdout_s, headers: true)
172+
assert_equal data[0]['name'], 'Benoit Chesneau'
173+
assert_equal data[0]['email'], 'bchesneau@gmail.com'
174+
assert_equal data[0]['commits'], '1322'
175+
assert_equal data[3]['name'], 'Randall Leeds'
176+
assert_equal data[3]['email'], 'randall@bleeds.info'
177+
assert_equal data[3]['commits'], '110'
178+
179+
# Try with two mailmaps, does it invalidate cache?
180+
git_dir = config_home / "git"
181+
git_dir.mkdir
182+
183+
global_mailmap_path = git_dir / ".mailmap"
184+
File.write(global_mailmap_path, GLOBAL_MAILMAP)
185+
186+
git_config_path = git_dir / "config"
187+
File.write(git_config_path, "[mailmap]\n\tfile = #{global_mailmap_path}")
188+
189+
stdout_s = cmd.run(
190+
'table',
191+
'--csv',
192+
'-e',
193+
cache_home: cache_home,
194+
config_home: config_home,
195+
)
196+
refute_empty(stdout_s)
197+
198+
data = CSV.parse(stdout_s, headers: true)
199+
assert_equal data[0]['name'], 'Benoit Chesneau'
200+
assert_equal data[0]['email'], 'bchesneau@gmail.com'
201+
assert_equal data[0]['commits'], '1322'
202+
assert_equal data[2]['name'], 'Randall Leeds'
203+
assert_equal data[2]['email'], 'randall@bleeds.info'
204+
assert_equal data[2]['commits'], '157'
205+
206+
# Try with the other mailmap, does it invalidate cache?
207+
File.delete(local_mailmap_path)
208+
209+
stdout_s = cmd.run(
210+
'table',
211+
'--csv',
212+
'-e',
213+
cache_home: cache_home,
214+
config_home: config_home,
215+
)
216+
refute_empty(stdout_s)
217+
218+
data = CSV.parse(stdout_s, headers: true)
219+
assert_equal data[0]['name'], 'Benoit Chesneau'
220+
assert_equal data[0]['email'], 'bchesneau@gmail.com'
221+
assert_equal data[0]['commits'], '1147'
222+
assert_equal data[2]['name'], 'Randall Leeds'
223+
assert_equal data[2]['email'], 'randall@bleeds.info'
224+
assert_equal data[2]['commits'], '157'
225+
226+
# Try with no mailmap, does it invalidate cache?
227+
File.delete(git_config_path)
228+
229+
stdout_s = cmd.run(
230+
'table',
231+
'--csv',
232+
'-e',
233+
cache_home: cache_home,
234+
config_home: config_home,
235+
)
236+
refute_empty(stdout_s)
237+
238+
data = CSV.parse(stdout_s, headers: true)
239+
assert_equal data[0]['name'], 'Benoit Chesneau'
240+
assert_equal data[0]['email'], 'bchesneau@gmail.com'
241+
assert_equal data[0]['commits'], '1147'
242+
assert_equal data[3]['name'], 'Randall Leeds'
243+
assert_equal data[3]['email'], 'randall@bleeds.info'
244+
assert_equal data[3]['commits'], '110'
245+
end
246+
end
247+
248+
# If git config points to a nonexistent file
249+
def test_bad_configured_global_mailmap_path
250+
Dir.mktmpdir do |dir|
251+
dir = Pathname.new(dir)
252+
cache_home = dir / ".cache"
253+
config_home = dir / ".config"
254+
cache_home.mkdir
255+
config_home.mkdir
256+
257+
git_dir = config_home / "git"
258+
git_dir.mkdir
259+
mailmap_path = git_dir / ".mailmap"
260+
# NOTE: We aren't creating the file!
261+
262+
git_config_path = git_dir / "config"
263+
File.write(git_config_path, "[mailmap]\n\tfile = #{mailmap_path}")
264+
265+
cmd = GitWho.new(GitWho.built_bin_path, BigRepo.path)
266+
stdout_s = cmd.run(
267+
'table',
268+
'--csv',
269+
'-e',
270+
cache_home: cache_home,
271+
config_home: config_home,
272+
)
273+
refute_empty(stdout_s)
274+
275+
data = CSV.parse(stdout_s, headers: true)
276+
assert_equal data[0]['name'], 'Benoit Chesneau'
277+
assert_equal data[0]['email'], 'bchesneau@gmail.com'
278+
assert_equal data[0]['commits'], '1147'
279+
assert_equal data[3]['name'], 'Randall Leeds'
280+
assert_equal data[3]['email'], 'randall@bleeds.info'
281+
assert_equal data[3]['commits'], '110'
282+
end
283+
end
284+
end
285+
286+
LOCAL_MAILMAP = <<~HEREDOC
287+
Benoit Chesneau <bchesneau@gmail.com> <benoitc@enlil.local>
288+
Benoit Chesneau <bchesneau@gmail.com> <benoitc@e-engura.org>
289+
Benoit Chesneau <bchesneau@gmail.com> <benoitc@pollen.nymphormation.org>
290+
HEREDOC
291+
292+
GLOBAL_MAILMAP = <<~HEREDOC
293+
Randall Leeds <randall@bleeds.info> <randall.leeds@gmail.com>
294+
HEREDOC

0 commit comments

Comments
 (0)