From d4a2385cda4a1b96d497253473ea108ac0aa3bb6 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 15 Apr 2026 04:43:31 +0300 Subject: [PATCH] builder: fix bad module definition in `.vmodules` (fixes #12292) --- .../path5/vab/android/android.v | 5 +++++ .../path5/vab/android/sdk/sdk.v | 5 +++++ .../path5/vab/v.mod | 3 +++ .../path5/vab/vab.v | 8 ++++++++ .../vmodules_overrides_test.v | 17 +++++++++++++++++ vlib/v/util/module.v | 19 +++++++++++++------ 6 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 vlib/v/tests/multiple_paths_in_vmodules/path5/vab/android/android.v create mode 100644 vlib/v/tests/multiple_paths_in_vmodules/path5/vab/android/sdk/sdk.v create mode 100644 vlib/v/tests/multiple_paths_in_vmodules/path5/vab/v.mod create mode 100644 vlib/v/tests/multiple_paths_in_vmodules/path5/vab/vab.v diff --git a/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/android/android.v b/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/android/android.v new file mode 100644 index 000000000..a73d1d923 --- /dev/null +++ b/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/android/android.v @@ -0,0 +1,5 @@ +module android + +pub fn hello() string { + return 'android' +} diff --git a/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/android/sdk/sdk.v b/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/android/sdk/sdk.v new file mode 100644 index 000000000..0e9293c6a --- /dev/null +++ b/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/android/sdk/sdk.v @@ -0,0 +1,5 @@ +module sdk + +pub fn hello() string { + return 'sdk' +} diff --git a/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/v.mod b/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/v.mod new file mode 100644 index 000000000..6ce9b6570 --- /dev/null +++ b/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/v.mod @@ -0,0 +1,3 @@ +Module { + name: 'vab' +} diff --git a/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/vab.v b/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/vab.v new file mode 100644 index 000000000..3c6713cfa --- /dev/null +++ b/vlib/v/tests/multiple_paths_in_vmodules/path5/vab/vab.v @@ -0,0 +1,8 @@ +module main + +import android +import android.sdk + +fn main() { + println(android.hello() + ' ' + sdk.hello()) +} diff --git a/vlib/v/tests/multiple_paths_in_vmodules/vmodules_overrides_test.v b/vlib/v/tests/multiple_paths_in_vmodules/vmodules_overrides_test.v index 5a9553100..6387f2d18 100644 --- a/vlib/v/tests/multiple_paths_in_vmodules/vmodules_overrides_test.v +++ b/vlib/v/tests/multiple_paths_in_vmodules/vmodules_overrides_test.v @@ -19,6 +19,8 @@ const submodule_mainvv = os.join_path(basepath, 'submodule_of_third_party_main.v const submodule_cmd = '${os.quoted_path(vexe)} ${os.quoted_path(submodule_mainvv)}' +const installed_module_root = os.join_path(basepath, 'path5', 'vab') + fn test_vexe_is_set() { assert vexe != '' println('vexe: ${vexe}') @@ -52,3 +54,18 @@ fn test_importing_third_party_submodule_works() { res := os.execute(submodule_cmd) assert res.exit_code == 0, res.output } + +fn test_running_installed_module_with_short_submodule_imports_works() { + old_dir := os.getwd() + defer { + os.chdir(old_dir) or {} + } + os.chdir(installed_module_root) or {} + os.setenv('VMODULES', os.join_path(basepath, 'path5'), true) + run_cmd := '${os.quoted_path(vexe)} run vab.v' + dump(os.getenv('VMODULES')) + dump(run_cmd) + res := os.execute(run_cmd) + assert res.exit_code == 0, res.output + assert res.output.trim_space() == 'android sdk' +} diff --git a/vlib/v/util/module.v b/vlib/v/util/module.v index 561198243..9ef0d66c9 100644 --- a/vlib/v/util/module.v +++ b/vlib/v/util/module.v @@ -69,6 +69,12 @@ pub fn qualify_module(pref_ &pref.Preferences, mod string, file_path string) str return mod } clean_file_path := file_path.all_before_last(os.path_separator) + // Use absolute path so mod_path_to_full_name can walk up to find v.mod + abs_clean_file_path := if os.is_abs_path(clean_file_path) { + clean_file_path + } else { + os.join_path_single(os.getwd(), clean_file_path) + } // relative module (relative to working directory) // TODO: find most stable solution & test with -usecache // @@ -77,16 +83,17 @@ pub fn qualify_module(pref_ &pref.Preferences, mod string, file_path string) str // TODO: 2022-01-30: The lookup should be relative to the folder, in which the current file is, // TODO: 2022-01-30: *NOT* to the working folder of the compiler, which can change easily. if clean_file_path.replace(os.getwd() + os.path_separator, '') == mod { + if m1 := mod_path_to_full_name(pref_, mod, abs_clean_file_path) { + if m1 != mod { + trace_qualify(@FN, mod, file_path, 'module_res 2', m1, + 'clean_file_path - getwd == mod, m1 == f(${abs_clean_file_path})') + return m1 + } + } trace_qualify(@FN, mod, file_path, 'module_res 2', mod, 'clean_file_path - getwd == mod, clean_file_path: ${clean_file_path}') return mod } - // Use absolute path so mod_path_to_full_name can walk up to find v.mod - abs_clean_file_path := if os.is_abs_path(clean_file_path) { - clean_file_path - } else { - os.join_path_single(os.getwd(), clean_file_path) - } if m1 := mod_path_to_full_name(pref_, mod, abs_clean_file_path) { trace_qualify(@FN, mod, file_path, 'module_res 3', m1, 'm1 == f(${abs_clean_file_path})') return m1 -- 2.39.5