user modules + `v install` from vpm

pull/1408/head
Alexander Medvednikov 2019-08-01 01:34:28 +02:00
parent d3c89273e8
commit a7e464fee9
5 changed files with 103 additions and 32 deletions

View File

@ -70,6 +70,7 @@ mut:
lang_dir string // "~/code/v" lang_dir string // "~/code/v"
out_name string // "program.exe" out_name string // "program.exe"
vroot string vroot string
mod string // module being built with -lib
} }
struct Preferences { struct Preferences {
@ -120,6 +121,29 @@ fn main() {
update_v() update_v()
return return
} }
if 'get' in args {
println('use `v install` to install modules from vpm.vlang.io')
return
}
if 'install' in args {
mod := args.last()
if args.len != 3 || mod.len < 2 {
println('usage: v install [module]')
return
}
vroot := os.dir(os.executable())
vget := '$vroot/tools/vget'
if !os.file_exists(vget) {
println('Building vget...')
os.chdir(vroot + '/tools')
vexec := os.args[0]
os.exec('$vexec vget.v')
println('Done.')
}
println('Installing module ${mod}...')
os.exec('$vget $mod')
return
}
// TODO quit if the compiler is too old // TODO quit if the compiler is too old
// u := os.file_last_mod_unix('v') // u := os.file_last_mod_unix('v')
// If there's no tmp path with current version yet, the user must be using a pre-built package // If there's no tmp path with current version yet, the user must be using a pre-built package
@ -171,8 +195,7 @@ fn main() {
fn (v mut V) compile() { fn (v mut V) compile() {
mut cgen := v.cgen mut cgen := v.cgen
cgen.genln('// Generated by V') cgen.genln('// Generated by V')
// Add user files to compile v.add_v_files_to_compile()
v.add_user_v_files()
if v.pref.is_verbose { if v.pref.is_verbose {
println('all .v files:') println('all .v files:')
println(v.files) println(v.files)
@ -888,7 +911,7 @@ fn (v &V) v_files_from_dir(dir string) []string {
} }
// Parses imports, adds necessary libs, and then user files // Parses imports, adds necessary libs, and then user files
fn (v mut V) add_user_v_files() { fn (v mut V) add_v_files_to_compile() {
mut dir := v.dir mut dir := v.dir
v.log('add_v_files($dir)') v.log('add_v_files($dir)')
// Need to store user files separately, because they have to be added after libs, but we dont know // Need to store user files separately, because they have to be added after libs, but we dont know
@ -932,6 +955,7 @@ fn (v mut V) add_user_v_files() {
file_imports << *p.import_table file_imports << *p.import_table
} }
// Parse lib imports // Parse lib imports
/*
if v.pref.build_mode == .default_mode { if v.pref.build_mode == .default_mode {
// strange ( for mod in v.table.imports ) dosent loop all items // strange ( for mod in v.table.imports ) dosent loop all items
// for mod in v.table.imports { // for mod in v.table.imports {
@ -952,27 +976,29 @@ fn (v mut V) add_user_v_files() {
} }
} }
else { else {
// strange ( for mod in v.table.imports ) dosent loop all items */
// for mod in v.table.imports { // strange ( for mod in v.table.imports ) dosent loop all items
for i := 0; i < v.table.imports.len; i++ { // for mod in v.table.imports {
mod := v.table.imports[i] for i := 0; i < v.table.imports.len; i++ {
mod_path := v.module_path(mod) mod := v.table.imports[i]
idir := os.getwd() mod_path := v.module_path(mod)
mut import_path := '$idir/$mod_path' mut import_path := '$ModPath/$mod_path'
//if !os.file_exists(import_path) || !os.is_dir(import_path){ //println('ip=$import_path')
if !os.dir_exists(import_path){
import_path = '$v.lang_dir/vlib/$mod_path'
if !os.dir_exists(import_path){ if !os.dir_exists(import_path){
import_path = '$v.lang_dir/vlib/$mod_path' panic('module "$mod" not found')
} }
vfiles := v.v_files_from_dir(import_path) }
if vfiles.len == 0 { vfiles := v.v_files_from_dir(import_path)
panic('cannot import module $mod (no .v files in "$import_path").') if vfiles.len == 0 {
} panic('cannot import module $mod (no .v files in "$import_path").')
// Add all imports referenced by these libs }
for file in vfiles { // Add all imports referenced by these libs
mut p := v.new_parser(file, Pass.imports) for file in vfiles {
p.parse() mut p := v.new_parser(file, Pass.imports)
file_imports << *p.import_table p.parse()
} file_imports << *p.import_table
} }
} }
if v.pref.is_verbose { if v.pref.is_verbose {
@ -989,9 +1015,12 @@ fn (v mut V) add_user_v_files() {
} }
// add imports in correct order // add imports in correct order
for mod in deps_resolved.imports() { for mod in deps_resolved.imports() {
// Building this module? Skip. TODO it's a hack.
if mod == v.mod {
continue
}
mod_p := v.module_path(mod) mod_p := v.module_path(mod)
idir := os.getwd() mut module_path := '$ModPath/$mod_p'
mut module_path := '$idir/$mod_p'
// If we are in default mode, we don't parse vlib .v files, but header .vh files in // If we are in default mode, we don't parse vlib .v files, but header .vh files in
// TmpPath/vlib // TmpPath/vlib
// These were generated by vfmt // These were generated by vfmt
@ -1008,8 +1037,9 @@ fn (v mut V) add_user_v_files() {
} }
} }
} }
// add remaining files (not mods) // add remaining files (not modules)
for fit in file_imports { for fit in file_imports {
//println('fit $fit.file_path')
if !fit.file_path in v.files { if !fit.file_path in v.files {
v.files << fit.file_path v.files << fit.file_path
} }
@ -1062,13 +1092,16 @@ fn new_v(args[]string) *V {
mut out_name := get_arg(joined_args, 'o', 'a.out') mut out_name := get_arg(joined_args, 'o', 'a.out')
// build mode // build mode
mut build_mode := BuildMode.default_mode mut build_mode := BuildMode.default_mode
if args.contains('-lib') { mut mod := ''
//if args.contains('-lib') {
if joined_args.contains('build module ') {
build_mode = .build build_mode = .build
// v -lib ~/v/os => os.o // v -lib ~/v/os => os.o
base := dir.all_after('/') mod = os.dir(dir)
println('Building module ${base}...') mod = mod.all_after('/')
println('Building module "${mod}" dir="$dir"...')
//out_name = '$TmpPath/vlib/${base}.o' //out_name = '$TmpPath/vlib/${base}.o'
out_name = base + '.o' out_name = mod + '.o'
// Cross compiling? Use separate dirs for each os // Cross compiling? Use separate dirs for each os
/* /*
if target_os != os.user_os() { if target_os != os.user_os() {
@ -1216,6 +1249,7 @@ fn new_v(args[]string) *V {
cgen: new_cgen(out_name_c) cgen: new_cgen(out_name_c)
vroot: vroot vroot: vroot
pref: pref pref: pref
mod: mod
} }
} }
@ -1362,3 +1396,4 @@ fn update_v() {
println(s) println(s)
} }
} }

View File

@ -156,7 +156,7 @@ fn (p mut Parser) parse() {
} }
p.fgenln('\n') p.fgenln('\n')
p.builtin_pkg = p.mod == 'builtin' p.builtin_pkg = p.mod == 'builtin'
p.can_chash = p.mod == 'ft' || p.mod == 'glfw' || p.mod=='ui' // TODO tmp remove p.can_chash = p.mod == 'ft' || p.mod == 'glfw' || p.mod=='glfw2' || p.mod=='ui' // TODO tmp remove
// Import pass - the first and the smallest pass that only analyzes imports // Import pass - the first and the smallest pass that only analyzes imports
// fully qualify the module name, eg base64 to encoding.base64 // fully qualify the module name, eg base64 to encoding.base64
fq_mod := p.table.qualify_module(p.mod, p.file_path) fq_mod := p.table.qualify_module(p.mod, p.file_path)

33
tools/vget.v 100644
View File

@ -0,0 +1,33 @@
module main
import (
http
os
json
)
const (
//url = 'http://localhost:8089'
url = 'http://vpm.vlang.io'
)
struct Mod {
id int
name string
url string
nr_downloads int
}
fn main() {
if os.args.len != 2 {
println('usage: vget [module]')
return
}
name := os.args.last()
s := http.get_text(url + '/jsmod/$name')
mod := json.decode(Mod, s) or { return }
home := os.home_dir()
os.exec('git -C "$home/.vmodules" clone $mod.url')
println(s)
}

View File

@ -483,6 +483,9 @@ pub fn ext(path string) string {
// dir returns all but the last element of path, typically the path's directory. // dir returns all but the last element of path, typically the path's directory.
pub fn dir(path string) string { pub fn dir(path string) string {
if path == '.' {
return getwd()
}
mut pos := -1 mut pos := -1
// TODO PathSeparator defined in os_win.v doesn't work when building V, // TODO PathSeparator defined in os_win.v doesn't work when building V,
// because v.c is generated for a nix system. // because v.c is generated for a nix system.

View File

@ -32,7 +32,6 @@ pub fn (ctx Context) json(s string) {
ctx.conn.write('HTTP/1.1 200 OK ctx.conn.write('HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
$h $h
$s $s
') ')
} }
@ -71,6 +70,7 @@ $html
} }
pub fn run<T>(port int) { pub fn run<T>(port int) {
println('Running vweb app on http://localhost:$port ...')
l := net.listen(port) or { panic('failed to listen') return } l := net.listen(port) or { panic('failed to listen') return }
for { for {
conn := l.accept() or { conn := l.accept() or {