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' // .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. // when using compare functions with automatic diff tool detection.
pub fn available_tool() ?DiffTool { pub fn available_tools() []DiffTool {
if cached_available_tool == none { if cache_of_available_tools.len == 0 {
cached_available_tool = find_working_diff_tool() 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. // 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 mut args := opts.args
if args == '' { if args == '' {
args = if defaults := diff.known_diff_tool_defaults[tool] { defaults } else { '' } 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. // Ensure that the diff command supports the color option.
// E.g., some BSD installations or macOS diff (based on FreeBSD diff) // E.g., some BSD installations or macOS diff (based on FreeBSD diff)
// might not include additional diffutils by default. // 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) { fn (opts CompareOptions) find_tool() !(DiffTool, string) {
tool := if opts.tool == .auto { tool := if opts.tool == .auto {
auto_tool := available_tool() or { auto_tool := available_tools()[0] or {
return error('error: failed to find comparison command') return error('error: failed to find comparison command')
} }
@ -112,7 +113,7 @@ fn (opts CompareOptions) find_tool() !(DiffTool, string) {
} else { } else {
opts.tool opts.tool
} }
cmd := $if windows { '${tool.str()}.exe' } $else { tool.str() } cmd := tool.cmd()
if opts.tool == .auto { if opts.tool == .auto {
// At this point it was already ensured that the automatically detected tool is available. // At this point it was already ensured that the automatically detected tool is available.
return tool, cmd return tool, cmd
@ -123,9 +124,13 @@ fn (opts CompareOptions) find_tool() !(DiffTool, string) {
return tool, cmd 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() { 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 } os.find_abs_path_of_executable(cmd) or { continue }
if tool == .delta { if tool == .delta {
// Sanity check that the `delta` executable is actually the diff tool. // Sanity check that the `delta` executable is actually the diff tool.
@ -136,9 +141,14 @@ fn find_working_diff_tool() ?DiffTool {
continue 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 { 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') const tdir = os.join_path(os.vtmp_dir(), 'diff_test')
fn testsuite_begin() { fn testsuite_begin() {
// Disable environmental overwrites that can result in different compare outputs. if diff.DiffTool.diff !in diff.available_tools() {
os.setenv('VDIFF_CMD', '', true) // On GitHub runners, diff should be available on all platforms.
os.find_abs_path_of_executable('diff') or { // 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') eprintln('> skipping test `${@FILE}`, since this test requires `diff` to be installed')
exit(0) exit(0)
} }
os.mkdir_all(tdir)! os.mkdir_all(tdir)!
// Disable environmental overwrites that can result in different compare outputs.
os.setenv('VDIFF_CMD', '', true)
} }
fn testsuite_end() { fn testsuite_end() {