diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index 354a6f75e1..305532b8e6 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -129,7 +129,7 @@ pub fn launch_tool(is_verbose bool, tool_name string, args []string) { mut tool_source := '' if os.is_dir(tool_basename) { tool_exe = path_of_executable(os.join_path(tool_basename, tool_name)) - tool_source = os.join_path(tool_basename, tool_name + '.v') + tool_source = tool_basename } else { tool_exe = path_of_executable(tool_basename) tool_source = tool_basename + '.v' @@ -139,9 +139,10 @@ pub fn launch_tool(is_verbose bool, tool_name string, args []string) { println('launch_tool vexe : $vroot') println('launch_tool vroot : $vroot') println('launch_tool tool_args : $tool_args') + println('launch_tool tool_source : $tool_source') println('launch_tool tool_command: $tool_command') } - should_compile := should_recompile_tool(vexe, tool_source) + should_compile := should_recompile_tool(vexe, tool_source, tool_name, tool_exe) if is_verbose { println('launch_tool should_compile: $should_compile') } @@ -167,13 +168,26 @@ pub fn launch_tool(is_verbose bool, tool_name string, args []string) { exit(os.system(tool_command)) } -// NB: should_recompile_tool/2 compares unix timestamps that have 1 second resolution +// NB: should_recompile_tool/4 compares unix timestamps that have 1 second resolution // That means that a tool can get recompiled twice, if called in short succession. // TODO: use a nanosecond mtime timestamp, if available. -pub fn should_recompile_tool(vexe string, tool_source string) bool { - sfolder := os.dir(tool_source) - tool_name := os.base(tool_source).replace('.v', '') - tool_exe := os.join_path(sfolder, path_of_executable(tool_name)) +pub fn should_recompile_tool(vexe string, tool_source string, tool_name string, tool_exe string) bool { + if os.is_dir(tool_source) { + source_files := os.walk_ext(tool_source, '.v') + mut newest_sfile := '' + mut newest_sfile_mtime := 0 + for sfile in source_files { + mtime := os.file_last_mod_unix(sfile) + if mtime > newest_sfile_mtime { + newest_sfile_mtime = mtime + newest_sfile = sfile + } + } + single_file_recompile := should_recompile_tool(vexe, newest_sfile, tool_name, + tool_exe) + // eprintln('>>> should_recompile_tool: tool_source: $tool_source | $single_file_recompile | $newest_sfile') + return single_file_recompile + } // TODO Caching should be done on the `vlib/v` level. mut should_compile := false if !os.exists(tool_exe) { @@ -212,6 +226,13 @@ pub fn should_recompile_tool(vexe string, tool_source string) bool { return should_compile } +fn tool_source2name_and_exe(tool_source string) (string, string) { + sfolder := os.dir(tool_source) + tool_name := os.base(tool_source).replace('.v', '') + tool_exe := os.join_path(sfolder, path_of_executable(tool_name)) + return tool_name, tool_exe +} + pub fn quote_path(s string) string { mut qs := s if qs.contains('&') { @@ -424,7 +445,8 @@ pub fn prepare_tool_when_needed(source_name string) { vexe := os.getenv('VEXE') vroot := os.dir(vexe) stool := os.join_path(vroot, 'cmd', 'tools', source_name) - if should_recompile_tool(vexe, stool) { + tool_name, tool_exe := tool_source2name_and_exe(stool) + if should_recompile_tool(vexe, stool, tool_name, tool_exe) { time.sleep_ms(1001) // TODO: remove this when we can get mtime with a better resolution recompile_file(vexe, stool) }