v.util: make all available diff tools accessible, extend tests (#21443)

This commit is contained in:
Turiiya 2024-05-06 20:17:53 +02:00 committed by GitHub
parent 7e82654414
commit c1b21a8d55
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 16 deletions

View File

@ -36,15 +36,16 @@ const known_diff_tool_defaults = {
// .fc: '/lnt'
}
__global cached_available_tool = ?DiffTool(none)
// List of detected diff tools.
__global cache_of_available_tools = []DiffTool{}
// Allows public checking for the available tool and prevents repeated searches
// Allows public checking for the available tools and prevents repeated searches
// when using compare functions with automatic diff tool detection.
pub fn available_tool() ?DiffTool {
if cached_available_tool == none {
cached_available_tool = find_working_diff_tool()
pub fn available_tools() []DiffTool {
if cache_of_available_tools.len == 0 {
cache_of_available_tools = find_working_diff_tools()
}
return cached_available_tool
return cache_of_available_tools
}
// compare_files returns a string displaying the differences between two files.
@ -64,7 +65,7 @@ pub fn compare_files(path1 string, path2 string, opts CompareOptions) !string {
mut args := opts.args
if args == '' {
args = if defaults := diff.known_diff_tool_defaults[tool] { defaults } else { '' }
if tool == .diff {
if opts.tool == .diff {
// Ensure that the diff command supports the color option.
// E.g., some BSD installations or macOS diff (based on FreeBSD diff)
// might not include additional diffutils by default.
@ -104,7 +105,7 @@ pub fn compare_text(text1 string, text2 string, opts CompareOptions) !string {
fn (opts CompareOptions) find_tool() !(DiffTool, string) {
tool := if opts.tool == .auto {
auto_tool := available_tool() or {
auto_tool := available_tools()[0] or {
return error('error: failed to find comparison command')
}
@ -112,7 +113,7 @@ fn (opts CompareOptions) find_tool() !(DiffTool, string) {
} else {
opts.tool
}
cmd := $if windows { '${tool.str()}.exe' } $else { tool.str() }
cmd := tool.cmd()
if opts.tool == .auto {
// At this point it was already ensured that the automatically detected tool is available.
return tool, cmd
@ -123,9 +124,13 @@ fn (opts CompareOptions) find_tool() !(DiffTool, string) {
return tool, cmd
}
fn find_working_diff_tool() ?DiffTool {
// Returns a list of programmatically-compatible known diff tools. Its result is intended to be stored
// in a constant to prevent repeated searches when compare functions with automatic diff tool detection
// are used. Using a public constant will also allow for external checking of available tools.
fn find_working_diff_tools() []DiffTool {
mut tools := []DiffTool{}
for tool in diff.known_diff_tool_defaults.keys() {
cmd := $if windows { '${tool.str()}.exe' } $else { tool.str() }
cmd := tool.cmd()
os.find_abs_path_of_executable(cmd) or { continue }
if tool == .delta {
// Sanity check that the `delta` executable is actually the diff tool.
@ -136,9 +141,14 @@ fn find_working_diff_tool() ?DiffTool {
continue
}
}
return tool
tools << tool
}
return none
return tools
}
fn (dt DiffTool) cmd() string {
cmd := dt.str()
return $if windows { '${cmd}.exe' } $else { cmd }
}
fn run_tool(cmd string, dbg_location string) string {

View File

@ -5,13 +5,18 @@ import term
const tdir = os.join_path(os.vtmp_dir(), 'diff_test')
fn testsuite_begin() {
// Disable environmental overwrites that can result in different compare outputs.
os.setenv('VDIFF_CMD', '', true)
os.find_abs_path_of_executable('diff') or {
if diff.DiffTool.diff !in diff.available_tools() {
// On GitHub runners, diff should be available on all platforms.
// Prevent regressions by failing instead of skipping when it's not detected.
if os.getenv('CI') == 'true' {
exit(1)
}
eprintln('> skipping test `${@FILE}`, since this test requires `diff` to be installed')
exit(0)
}
os.mkdir_all(tdir)!
// Disable environmental overwrites that can result in different compare outputs.
os.setenv('VDIFF_CMD', '', true)
}
fn testsuite_end() {