v: support multiple paths in VMODULES env variable (#7048)
parent
376833aea7
commit
b11d285680
|
@ -37,10 +37,9 @@ enum HighlightTokenTyp {
|
||||||
const (
|
const (
|
||||||
css_js_assets = ['doc.css', 'normalize.css', 'doc.js']
|
css_js_assets = ['doc.css', 'normalize.css', 'doc.js']
|
||||||
allowed_formats = ['md', 'markdown', 'json', 'text', 'stdout', 'html', 'htm']
|
allowed_formats = ['md', 'markdown', 'json', 'text', 'stdout', 'html', 'htm']
|
||||||
exe_path = os.executable()
|
res_path = os.resource_abs_path('vdoc-resources')
|
||||||
exe_dir = os.dir(exe_path)
|
vexe = pref.vexe_path()
|
||||||
res_path = os.join_path(exe_dir, 'vdoc-resources')
|
vroot = os.dir(vexe)
|
||||||
vexe_path = os.dir(@VEXE)
|
|
||||||
html_content = '
|
html_content = '
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
@ -192,7 +191,9 @@ struct VdocHttpServerContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_http_connection(mut con net.TcpConn, ctx &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 {
|
first_line := reader.read_line() or {
|
||||||
send_http_response(mut con, 501, ctx.content_type, 'bad request')
|
send_http_response(mut con, 501, ctx.content_type, 'bad request')
|
||||||
return
|
return
|
||||||
|
@ -715,7 +716,7 @@ fn (mut cfg DocConfig) generate_docs_from_file() {
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
dir_path := if cfg.is_vlib {
|
dir_path := if cfg.is_vlib {
|
||||||
vexe_path
|
vroot
|
||||||
} else if os.is_dir(cfg.input_path) {
|
} else if os.is_dir(cfg.input_path) {
|
||||||
cfg.input_path
|
cfg.input_path
|
||||||
} else {
|
} else {
|
||||||
|
@ -935,11 +936,11 @@ fn (cfg DocConfig) get_resource(name string, minify bool) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
args := os.args[2..].clone()
|
if os.args.len < 2 || '-h' in os.args || '--help' in os.args || os.args[1..] == ['doc', 'help'] {
|
||||||
if args.len == 0 || args[0] in ['help', '-h', '--help'] {
|
os.system('$vexe help doc')
|
||||||
os.system('${@VEXE} help doc')
|
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
|
args := os.args[2..].clone()
|
||||||
mut cfg := DocConfig{
|
mut cfg := DocConfig{
|
||||||
manifest: vmod.Manifest{
|
manifest: vmod.Manifest{
|
||||||
repo_url: ''
|
repo_url: ''
|
||||||
|
@ -1050,7 +1051,7 @@ fn main() {
|
||||||
if cfg.input_path.trim_right('/') == 'vlib' {
|
if cfg.input_path.trim_right('/') == 'vlib' {
|
||||||
cfg.is_vlib = true
|
cfg.is_vlib = true
|
||||||
cfg.is_multi = 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 {
|
} else if !is_path {
|
||||||
cfg.vprintln('Input "$cfg.input_path" is not a valid path. Looking for modules named "$cfg.input_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 {
|
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
|
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.
|
// vmodules_dir returns the path to a folder, where v stores its global modules.
|
||||||
pub fn vmodules_dir() string {
|
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')
|
mut path := os.getenv('VMODULES')
|
||||||
if path == '' {
|
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`.
|
// chmod change file access attributes of `path` to `mode`.
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
module doc
|
module doc
|
||||||
|
|
||||||
|
import os
|
||||||
import v.table
|
import v.table
|
||||||
import v.parser
|
import v.parser
|
||||||
import v.ast
|
import v.ast
|
||||||
import os
|
import v.pref
|
||||||
|
|
||||||
// get_parent_mod - return the parent mod name, in dot format.
|
// get_parent_mod - return the parent mod name, in dot format.
|
||||||
// It works by climbing up the folder hierarchy, until a folder,
|
// 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 {
|
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)
|
mod_path := mod.replace('.', os.path_separator)
|
||||||
compile_dir := os.real_path(base_path)
|
compile_dir := os.real_path(base_path)
|
||||||
modules_dir := os.join_path(compile_dir, 'modules', mod_path)
|
modules_dir := os.join_path(compile_dir, 'modules', mod_path)
|
||||||
vlib_path := os.join_path(os.dir(@VEXE), 'vlib', mod_path)
|
vlib_path := os.join_path(vroot, 'vlib', mod_path)
|
||||||
vmodules_path := os.join_path(os.vmodules_dir(), mod_path)
|
mut paths := [modules_dir, vlib_path]
|
||||||
paths := [modules_dir, vlib_path, vmodules_path]
|
vmodules_paths := os.vmodules_paths()
|
||||||
|
for vmpath in vmodules_paths {
|
||||||
|
paths << os.join_path(vmpath, mod_path)
|
||||||
|
}
|
||||||
for path in paths {
|
for path in paths {
|
||||||
if !os.exists(path) || os.is_dir_empty(path) {
|
if !os.exists(path) || os.is_dir_empty(path) {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub fn new_preferences() Preferences {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut p Preferences) fill_with_defaults() {
|
fn (mut p Preferences) expand_lookup_paths() {
|
||||||
if p.vroot == '' {
|
if p.vroot == '' {
|
||||||
// Location of all vlib files
|
// Location of all vlib files
|
||||||
p.vroot = os.dir(vexe_path())
|
p.vroot = os.dir(vexe_path())
|
||||||
|
@ -25,9 +25,19 @@ pub fn (mut p Preferences) fill_with_defaults() {
|
||||||
if p.lookup_path.len == 0 {
|
if p.lookup_path.len == 0 {
|
||||||
p.lookup_path = ['@vlib', '@vmodules']
|
p.lookup_path = ['@vlib', '@vmodules']
|
||||||
}
|
}
|
||||||
for i, path in p.lookup_path {
|
mut expanded_paths := []string{}
|
||||||
p.lookup_path[i] = path.replace('@vlib', vlib_path).replace('@vmodules', default_module_path)
|
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)
|
rpath := os.real_path(p.path)
|
||||||
if p.out_name == '' {
|
if p.out_name == '' {
|
||||||
filename := os.file_name(rpath).trim_space()
|
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