118 lines
3.3 KiB
V
118 lines
3.3 KiB
V
// Copyright (c) 2020-2024 Joe Conigliaro. All rights reserved.
|
|
// Use of this source code is governed by an MIT license
|
|
// that can be found in the LICENSE file.
|
|
module pref
|
|
|
|
import os
|
|
|
|
fn (p &Preferences) effective_vroot() string {
|
|
if p.vroot.len > 0 {
|
|
return p.vroot
|
|
}
|
|
return os.getwd()
|
|
}
|
|
|
|
pub fn (p &Preferences) get_vlib_module_path(mod string) string {
|
|
mod_path := mod.replace('.', os.path_separator)
|
|
return module_path_join(module_path_join(p.effective_vroot(), 'vlib'), mod_path)
|
|
}
|
|
|
|
fn module_path_join(base string, name string) string {
|
|
if base.len == 0 {
|
|
return name
|
|
}
|
|
if name.len == 0 {
|
|
return base
|
|
}
|
|
last := base[base.len - 1]
|
|
if last == `/` || last == `\\` {
|
|
return base + name
|
|
}
|
|
return base + os.path_separator + name
|
|
}
|
|
|
|
fn module_root_for_file(path string) string {
|
|
mut dir := os.dir(path)
|
|
for dir.len > 0 {
|
|
if os.exists(module_path_join(dir, 'v.mod')) {
|
|
return dir
|
|
}
|
|
parent := os.dir(dir)
|
|
if parent == dir {
|
|
break
|
|
}
|
|
dir = parent
|
|
}
|
|
return ''
|
|
}
|
|
|
|
fn find_module_path_in_parent_dirs(mod_path string, importing_file_path string) ?string {
|
|
mut dir := os.dir(importing_file_path)
|
|
for dir.len > 0 {
|
|
parent_relative_path := module_path_join(dir, mod_path)
|
|
if dir_exists(parent_relative_path) {
|
|
return parent_relative_path
|
|
}
|
|
parent := os.dir(dir)
|
|
if parent == dir {
|
|
break
|
|
}
|
|
dir = parent
|
|
}
|
|
return none
|
|
}
|
|
|
|
// check for relative and then vlib
|
|
pub fn (p &Preferences) get_module_path(mod string, importing_file_path string) string {
|
|
mod_path := mod.replace('.', os.path_separator)
|
|
vroot := p.effective_vroot()
|
|
// relative to file importing it
|
|
relative_path := module_path_join(os.dir(importing_file_path), mod_path)
|
|
if dir_exists(relative_path) {
|
|
return relative_path
|
|
}
|
|
module_root := module_root_for_file(importing_file_path)
|
|
if module_root != '' {
|
|
root_relative_path := module_path_join(module_root, mod_path)
|
|
if dir_exists(root_relative_path) {
|
|
return root_relative_path
|
|
}
|
|
}
|
|
if parent_relative_path := find_module_path_in_parent_dirs(mod_path, importing_file_path) {
|
|
return parent_relative_path
|
|
}
|
|
cwd_relative_path := module_path_join(os.getwd(), mod_path)
|
|
if dir_exists(cwd_relative_path) {
|
|
return cwd_relative_path
|
|
}
|
|
// TODO: is this the best order?
|
|
// vlib
|
|
vlib_path := module_path_join(module_path_join(vroot, 'vlib'), mod_path)
|
|
if dir_exists(vlib_path) {
|
|
return vlib_path
|
|
}
|
|
// V1 compiler modules under vlib/v use legacy bare sibling imports
|
|
// (`import token` from vlib/v/checker, with sources in vlib/v/token).
|
|
vlib_v_path := module_path_join(module_path_join(vroot, 'vlib'), 'v')
|
|
normalized_importer := importing_file_path.replace('\\', '/')
|
|
normalized_vlib_v := vlib_v_path.replace('\\', '/')
|
|
if normalized_importer.starts_with(normalized_vlib_v + '/')
|
|
|| normalized_importer.starts_with('vlib/v/') {
|
|
legacy_v_path := module_path_join(vlib_v_path, mod_path)
|
|
if dir_exists(legacy_v_path) {
|
|
return legacy_v_path
|
|
}
|
|
}
|
|
// ~/.vmodules
|
|
vmodules_path := module_path_join(p.vmodules_path, mod_path)
|
|
if dir_exists(vmodules_path) {
|
|
// V convention: if a module dir has a src/ subdirectory, use that
|
|
src_path := module_path_join(vmodules_path, 'src')
|
|
if dir_exists(src_path) {
|
|
return src_path
|
|
}
|
|
return vmodules_path
|
|
}
|
|
panic('Preferences.get_module_path: cannot find module path for `${mod}`')
|
|
}
|