Skip to content

Commit b838418

Browse files
authored
v.util: fix diff coloring, add test (#21260)
1 parent 175d74c commit b838418

File tree

2 files changed

+42
-22
lines changed

2 files changed

+42
-22
lines changed

vlib/v/util/diff/diff.v

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,6 @@ pub fn find_working_diff_command() !string {
3131
continue
3232
}
3333
if p.exit_code == 0 { // success
34-
// TODO: proper implemenation of --color flag
35-
$if !macos {
36-
if diffcmd in ['gdiff', 'diff'] {
37-
if p.output.contains('GNU diffutils') && env_diffopts == '' {
38-
return '${diffcmd} --color=always'
39-
}
40-
}
41-
}
4234
if diffcmd in ['code', 'code.cmd'] {
4335
// Make sure the diff flag `-d` is included in any case.
4436
return '${diffcmd} ${env_diffopts} -d'
@@ -51,16 +43,22 @@ pub fn find_working_diff_command() !string {
5143
}
5244

5345
pub fn color_compare_files(diff_cmd string, path1 string, path2 string) string {
54-
os.find_abs_path_of_executable(diff_cmd.all_before(' ')) or {
55-
return 'comparison command: `${diff_cmd}` not found'
56-
}
46+
cmd := diff_cmd.all_before(' ')
47+
os.find_abs_path_of_executable(cmd) or { return 'comparison command: `${cmd}` not found' }
5748
flags := $if openbsd {
5849
['-d', '-a', '-U', '2']
5950
} $else $if freebsd {
6051
['--minimal', '--text', '--unified=2']
6152
} $else {
6253
['--minimal', '--text', '--unified=2', '--show-function-line="fn "']
6354
}
55+
if cmd == 'diff' {
56+
color_diff_cmd := '${diff_cmd} --color=always ${flags.join(' ')} ${os.quoted_path(path1)} ${os.quoted_path(path2)}'
57+
color_result := os.execute(color_diff_cmd)
58+
if !color_result.output.starts_with('diff: unrecognized option') {
59+
return color_result.output.trim_right('\r\n')
60+
}
61+
}
6462
full_cmd := '${diff_cmd} ${flags.join(' ')} ${os.quoted_path(path1)} ${os.quoted_path(path2)}'
6563
return os.execute(full_cmd).output.trim_right('\r\n')
6664
}

vlib/v/util/diff/diff_test.v

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
import v.util.diff
22
import os
33

4-
fn test_compare_files() {
4+
const tdir = os.join_path(os.vtmp_dir(), 'diff_test')
5+
6+
fn testsuite_begin() {
57
os.find_abs_path_of_executable('diff') or {
6-
eprintln('> skipping test, since this test requires `diff` to be installed.')
7-
return
8+
eprintln('> skipping test, since this test requires `diff` to be installed')
9+
exit(0)
810
}
11+
os.mkdir_all(tdir)!
12+
}
13+
14+
fn testsuite_end() {
15+
os.rmdir_all(tdir) or {}
16+
}
917

18+
fn test_compare_files() {
1019
f1 := "Module{
1120
name: 'Foo'
1221
description: 'Awesome V module.'
@@ -22,13 +31,8 @@ fn test_compare_files() {
2231
dependencies: []
2332
}
2433
"
25-
tdir := os.join_path(os.vtmp_dir(), 'diff_test')
26-
os.mkdir_all(tdir)!
27-
defer {
28-
os.rmdir_all(tdir) or {}
29-
}
30-
p1 := os.join_path(tdir, 'f1.txt')
31-
p2 := os.join_path(tdir, 'f2.txt')
34+
p1 := os.join_path(tdir, '${@FN}_f1.txt')
35+
p2 := os.join_path(tdir, '${@FN}_f2.txt')
3236
os.write_file(p1, f1)!
3337
os.write_file(p2, f2)!
3438

@@ -47,16 +51,34 @@ fn test_compare_files() {
4751
assert res.contains("+\tlicense: 'MIT'"), res
4852

4953
// Test again using `find_working_diff_command()`.
54+
os.setenv('VDIFF_TOOL', 'diff', true)
5055
res = diff.color_compare_files(diff.find_working_diff_command()!, p1, p2)
5156
assert res.contains("-\tversion: '0.0.0'"), res
5257
assert res.contains("+\tversion: '0.1.0'"), res
5358
assert res.contains("+\tlicense: 'MIT'"), res
5459

5560
// Test adding a flag via env flag.
56-
os.setenv('VDIFF_OPTIONS', '--ignore-case', true)
61+
os.setenv('VDIFF_OPTIONS', '--ignore-case', true) // ignored, when VDIFF_TOOL is not explicitly set
5762
res = diff.color_compare_files(diff.find_working_diff_command()!, p1, p2)
5863
assert !res.contains("+\tname: 'foo'"), res
5964
assert res.contains("-\tversion: '0.0.0'"), res
6065
assert res.contains("+\tversion: '0.1.0'"), res
6166
assert res.contains("+\tlicense: 'MIT'"), res
6267
}
68+
69+
fn test_coloring() {
70+
if os.execute('diff --color=always').output.starts_with('diff: unrecognized option') {
71+
eprintln('> skipping test, since `diff` does not support --color=always')
72+
return
73+
}
74+
f1 := 'abc\n'
75+
f2 := 'abcd\n'
76+
p1 := os.join_path(tdir, '${@FN}_f1.txt')
77+
p2 := os.join_path(tdir, '${@FN}_f2.txt')
78+
os.write_file(p1, f1)!
79+
os.write_file(p2, f2)!
80+
res := diff.color_compare_files('diff', p1, p2)
81+
esc := rune(27)
82+
assert res.contains('${esc}[31m-abc${esc}['), res
83+
assert res.contains('${esc}[32m+abcd${esc}['), res
84+
}

0 commit comments

Comments
 (0)