Skip to content

Commit

Permalink
v.util: make all available diff tools accessible, extend tests (#21443)
Browse files Browse the repository at this point in the history
  • Loading branch information
ttytm authored May 6, 2024
1 parent 7e82654 commit c1b21a8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 16 deletions.
36 changes: 23 additions & 13 deletions vlib/v/util/diff/diff.v
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -104,15 +105,15 @@ 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')
}

auto_tool
} 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
Expand All @@ -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.
Expand All @@ -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 {
Expand Down
11 changes: 8 additions & 3 deletions vlib/v/util/diff/diff_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit c1b21a8

Please sign in to comment.