v: support multiple paths in VMODULES env variable (#7048)
parent
376833aea7
commit
b11d285680
|
@ -37,10 +37,9 @@ enum HighlightTokenTyp {
|
|||
const (
|
||||
css_js_assets = ['doc.css', 'normalize.css', 'doc.js']
|
||||
allowed_formats = ['md', 'markdown', 'json', 'text', 'stdout', 'html', 'htm']
|
||||
exe_path = os.executable()
|
||||
exe_dir = os.dir(exe_path)
|
||||
res_path = os.join_path(exe_dir, 'vdoc-resources')
|
||||
vexe_path = os.dir(@VEXE)
|
||||
res_path = os.resource_abs_path('vdoc-resources')
|
||||
vexe = pref.vexe_path()
|
||||
vroot = os.dir(vexe)
|
||||
html_content = '
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
@ -192,7 +191,9 @@ struct VdocHttpServerContext {
|
|||
}
|
||||
|
||||
fn handle_http_connection(mut con net.TcpConn, ctx &VdocHttpServerContext) {
|
||||
mut reader := io.new_buffered_reader(reader: io.make_reader(con))
|
||||
mut reader := io.new_buffered_reader({
|
||||
reader: io.make_reader(con)
|
||||
})
|
||||
first_line := reader.read_line() or {
|
||||
send_http_response(mut con, 501, ctx.content_type, 'bad request')
|
||||
return
|
||||
|
@ -715,7 +716,7 @@ fn (mut cfg DocConfig) generate_docs_from_file() {
|
|||
exit(1)
|
||||
}
|
||||
dir_path := if cfg.is_vlib {
|
||||
vexe_path
|
||||
vroot
|
||||
} else if os.is_dir(cfg.input_path) {
|
||||
cfg.input_path
|
||||
} else {
|
||||
|
@ -935,11 +936,11 @@ fn (cfg DocConfig) get_resource(name string, minify bool) string {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
args := os.args[2..].clone()
|
||||
if args.len == 0 || args[0] in ['help', '-h', '--help'] {
|
||||
os.system('${@VEXE} help doc')
|
||||
if os.args.len < 2 || '-h' in os.args || '--help' in os.args || os.args[1..] == ['doc', 'help'] {
|
||||
os.system('$vexe help doc')
|
||||
exit(0)
|
||||
}
|
||||
args := os.args[2..].clone()
|
||||
mut cfg := DocConfig{
|
||||
manifest: vmod.Manifest{
|
||||
repo_url: ''
|
||||
|
@ -1050,7 +1051,7 @@ fn main() {
|
|||
if cfg.input_path.trim_right('/') == 'vlib' {
|
||||
cfg.is_vlib = true
|
||||
cfg.is_multi = true
|
||||
cfg.input_path = os.join_path(vexe_path, 'vlib')
|
||||
cfg.input_path = os.join_path(vroot, 'vlib')
|
||||
} else if !is_path {
|
||||
cfg.vprintln('Input "$cfg.input_path" is not a valid path. Looking for modules named "$cfg.input_path"...')
|
||||
mod_path := doc.lookup_module(cfg.input_path) or {
|
||||
|
|
18
vlib/os/os.v
18
vlib/os/os.v
|
@ -1354,13 +1354,27 @@ pub fn temp_dir() string {
|
|||
return path
|
||||
}
|
||||
|
||||
fn default_vmodules_path() string {
|
||||
return os.join_path(os.home_dir(), '.vmodules')
|
||||
}
|
||||
// vmodules_dir returns the path to a folder, where v stores its global modules.
|
||||
pub fn vmodules_dir() string {
|
||||
paths := vmodules_paths()
|
||||
if paths.len > 0 {
|
||||
return paths[0]
|
||||
}
|
||||
return os.default_vmodules_path()
|
||||
}
|
||||
|
||||
// vmodules_paths returns a list of paths, where v looks up for modules.
|
||||
// You can customize it through setting the environment variable VMODULES
|
||||
pub fn vmodules_paths() []string {
|
||||
mut path := os.getenv('VMODULES')
|
||||
if path == '' {
|
||||
path = os.join_path(os.home_dir(), '.vmodules')
|
||||
path = os.default_vmodules_path()
|
||||
}
|
||||
return path
|
||||
list := path.split(os.path_delimiter).map(it.trim_right(os.path_separator))
|
||||
return list
|
||||
}
|
||||
|
||||
// chmod change file access attributes of `path` to `mode`.
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
module doc
|
||||
|
||||
import os
|
||||
import v.table
|
||||
import v.parser
|
||||
import v.ast
|
||||
import os
|
||||
import v.pref
|
||||
|
||||
// get_parent_mod - return the parent mod name, in dot format.
|
||||
// It works by climbing up the folder hierarchy, until a folder,
|
||||
|
@ -61,12 +62,17 @@ fn get_parent_mod(input_dir string) ?string {
|
|||
}
|
||||
|
||||
pub fn lookup_module_with_path(mod string, base_path string) ?string {
|
||||
vexe := pref.vexe_path()
|
||||
vroot := os.dir(vexe)
|
||||
mod_path := mod.replace('.', os.path_separator)
|
||||
compile_dir := os.real_path(base_path)
|
||||
modules_dir := os.join_path(compile_dir, 'modules', mod_path)
|
||||
vlib_path := os.join_path(os.dir(@VEXE), 'vlib', mod_path)
|
||||
vmodules_path := os.join_path(os.vmodules_dir(), mod_path)
|
||||
paths := [modules_dir, vlib_path, vmodules_path]
|
||||
vlib_path := os.join_path(vroot, 'vlib', mod_path)
|
||||
mut paths := [modules_dir, vlib_path]
|
||||
vmodules_paths := os.vmodules_paths()
|
||||
for vmpath in vmodules_paths {
|
||||
paths << os.join_path(vmpath, mod_path)
|
||||
}
|
||||
for path in paths {
|
||||
if !os.exists(path) || os.is_dir_empty(path) {
|
||||
continue
|
||||
|
|
|
@ -16,7 +16,7 @@ pub fn new_preferences() Preferences {
|
|||
return p
|
||||
}
|
||||
|
||||
pub fn (mut p Preferences) fill_with_defaults() {
|
||||
fn (mut p Preferences) expand_lookup_paths() {
|
||||
if p.vroot == '' {
|
||||
// Location of all vlib files
|
||||
p.vroot = os.dir(vexe_path())
|
||||
|
@ -25,9 +25,19 @@ pub fn (mut p Preferences) fill_with_defaults() {
|
|||
if p.lookup_path.len == 0 {
|
||||
p.lookup_path = ['@vlib', '@vmodules']
|
||||
}
|
||||
for i, path in p.lookup_path {
|
||||
p.lookup_path[i] = path.replace('@vlib', vlib_path).replace('@vmodules', default_module_path)
|
||||
mut expanded_paths := []string{}
|
||||
for path in p.lookup_path {
|
||||
match path {
|
||||
'@vlib' { expanded_paths << vlib_path }
|
||||
'@vmodules' { expanded_paths << os.vmodules_paths() }
|
||||
else { expanded_paths << path }
|
||||
}
|
||||
}
|
||||
p.lookup_path = expanded_paths
|
||||
}
|
||||
|
||||
pub fn (mut p Preferences) fill_with_defaults() {
|
||||
p.expand_lookup_paths()
|
||||
rpath := os.real_path(p.path)
|
||||
if p.out_name == '' {
|
||||
filename := os.file_name(rpath).trim_space()
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import yyy
|
||||
import xxx
|
||||
import zzz
|
||||
|
||||
fn main() {
|
||||
all := [xxx.f(), yyy.f(), zzz.f()]
|
||||
println(all)
|
||||
assert all == ['x','y','z']
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
## this folder is the first one that will be put in vmodules.
|
||||
## V uses that to put there its cache too.
|
||||
## Just ignore it for now.
|
||||
cache/
|
|
@ -0,0 +1,4 @@
|
|||
module xxx
|
||||
pub fn f() string {
|
||||
return 'x'
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
module yyy
|
||||
pub fn f() string {
|
||||
return 'y'
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
module zzz
|
||||
pub fn f() string {
|
||||
return 'z'
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import os
|
||||
|
||||
const (
|
||||
vexe = os.getenv('VEXE')
|
||||
vroot = os.dir(vexe)
|
||||
basepath = os.real_path(os.join_path(vroot, 'vlib', 'v', 'tests', 'multiple_paths_in_vmodules'))
|
||||
mainvv = os.join_path(basepath, 'main.vv')
|
||||
)
|
||||
|
||||
fn test_vexe_is_set() {
|
||||
assert vexe != ''
|
||||
println('vexe: $vexe')
|
||||
}
|
||||
|
||||
fn test_compiling_without_vmodules_fails() {
|
||||
os.chdir(vroot)
|
||||
os.setenv('VMODULES', '', true)
|
||||
res := os.exec('"$vexe" run "$mainvv"') or {
|
||||
panic(err)
|
||||
}
|
||||
assert res.exit_code == 1
|
||||
assert res.output.trim_space() == 'builder error: cannot import module "yyy" (not found)'
|
||||
}
|
||||
|
||||
fn test_compiling_with_vmodules_works() {
|
||||
os.chdir(vroot)
|
||||
vmpaths := ['path1', 'path2', 'path3'].map(os.join_path(basepath, it))
|
||||
os.setenv('VMODULES', vmpaths.join(os.path_delimiter), true)
|
||||
res := os.exec('"$vexe" run "$mainvv"') or {
|
||||
panic(err)
|
||||
}
|
||||
assert res.exit_code == 0
|
||||
assert res.output.trim_space() == "['x', 'y', 'z']"
|
||||
}
|
Loading…
Reference in New Issue