From fbad48b5d95811b4bc9262736eb02c82a2d07d5e Mon Sep 17 00:00:00 2001 From: Subhomoy Haldar Date: Mon, 11 Jul 2022 23:38:53 +0530 Subject: [PATCH] v.builder: retain executable after `v run`, if the executable was already existing (#15021) --- vlib/v/builder/builder.v | 6 ++++ vlib/v/builder/builder_test.v | 55 +++++++++++++++++++++++++++++++++++ vlib/v/builder/compile.v | 6 ++-- vlib/v/builder/rebuilding.v | 2 +- 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 vlib/v/builder/builder_test.v diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index f3b0c86223..85db9e736c 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -41,6 +41,7 @@ pub mut: mod_invalidates_mods map[string][]string // changes in mod `os`, force invalidation of mods, that do `import os` path_invalidates_mods map[string][]string // changes in a .v file from `os`, invalidates `os` crun_cache_keys []string // target executable + top level source files; filled in by Builder.should_rebuild + executable_exists bool // if the executable already exists, don't remove new executable after `v run` } pub fn new_builder(pref &pref.Preferences) Builder { @@ -67,6 +68,10 @@ pub fn new_builder(pref &pref.Preferences) Builder { if pref.show_callgraph || pref.show_depgraph { dotgraph.start_digraph() } + mut executable_name := pref.out_name + $if windows { + executable_name += '.exe' + } return Builder{ pref: pref table: table @@ -74,6 +79,7 @@ pub fn new_builder(pref &pref.Preferences) Builder { transformer: transformer.new_transformer_with_table(table, pref) compiled_dir: compiled_dir cached_msvc: msvc + executable_exists: os.is_file(executable_name) } } diff --git a/vlib/v/builder/builder_test.v b/vlib/v/builder/builder_test.v new file mode 100644 index 0000000000..354f6f1e1f --- /dev/null +++ b/vlib/v/builder/builder_test.v @@ -0,0 +1,55 @@ +module main + +import os +import arrays + +const test_path = 'v_run_check' + +fn arrays_are_equivalent(a []string, b []string) bool { + if a.len != b.len { + return false + } + for item in a { + if item !in b { + return false + } + } + return true +} + +fn test_conditional_executable_removal() ? { + // Setup the sample project + dir := os.join_path(os.temp_dir(), test_path) + + os.rmdir_all(dir) or {} + os.mkdir(dir) or {} + + defer { + os.rmdir_all(dir) or {} + } + + os.chdir(dir)? + os.execute_or_exit('${os.quoted_path(@VEXE)} init') + + mut executable := test_path + $if windows { + executable += '.exe' + } + + original_file_list := os.ls(dir)? + new_file_list := arrays.concat(original_file_list, executable) + + assert os.execute('${os.quoted_path(@VEXE)} run .').output == 'Hello World!\n' + + assert arrays_are_equivalent(os.ls(dir)?, original_file_list) + + assert os.execute('${os.quoted_path(@VEXE)} .').output == '' + + assert os.execute('./$executable').output == 'Hello World!\n' + + assert arrays_are_equivalent(os.ls(dir)?, new_file_list) + + assert os.execute('${os.quoted_path(@VEXE)} run .').output == 'Hello World!\n' + + assert arrays_are_equivalent(os.ls(dir)?, new_file_list) +} diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index 828e397704..a470854522 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -144,8 +144,10 @@ fn (mut v Builder) cleanup_run_executable_after_exit(exefile string) { v.pref.vrun_elog('keeping executable: $exefile , because -keepc was passed') return } - v.pref.vrun_elog('remove run executable: $exefile') - os.rm(exefile) or {} + if !v.executable_exists { + v.pref.vrun_elog('remove run executable: $exefile') + os.rm(exefile) or {} + } } // 'strings' => 'VROOT/vlib/strings' diff --git a/vlib/v/builder/rebuilding.v b/vlib/v/builder/rebuilding.v index 44a5773c00..076b958e32 100644 --- a/vlib/v/builder/rebuilding.v +++ b/vlib/v/builder/rebuilding.v @@ -259,7 +259,7 @@ fn (mut b Builder) handle_usecache(vexe string) { pub fn (mut b Builder) should_rebuild() bool { mut exe_name := b.pref.out_name $if windows { - exe_name = exe_name + '.exe' + exe_name += '.exe' } if !os.is_file(exe_name) { return true