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"
out_name string // "program.exe"
vroot string
mod string // module being built with -lib
}
struct Preferences {
@ -120,6 +121,29 @@ fn main() {
update_v()
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
// 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
@ -171,8 +195,7 @@ fn main() {
fn (v mut V) compile() {
mut cgen := v.cgen
cgen.genln('// Generated by V')
// Add user files to compile
v.add_user_v_files()
v.add_v_files_to_compile()
if v.pref.is_verbose {
println('all .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
fn (v mut V) add_user_v_files() {
fn (v mut V) add_v_files_to_compile() {
mut dir := v.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
@ -932,6 +955,7 @@ fn (v mut V) add_user_v_files() {
file_imports << *p.import_table
}
// Parse lib imports
/*
if v.pref.build_mode == .default_mode {
// strange ( for mod in v.table.imports ) dosent loop all items
// for mod in v.table.imports {
@ -952,16 +976,19 @@ fn (v mut V) add_user_v_files() {
}
}
else {
*/
// strange ( for mod in v.table.imports ) dosent loop all items
// for mod in v.table.imports {
for i := 0; i < v.table.imports.len; i++ {
mod := v.table.imports[i]
mod_path := v.module_path(mod)
idir := os.getwd()
mut import_path := '$idir/$mod_path'
//if !os.file_exists(import_path) || !os.is_dir(import_path){
mut import_path := '$ModPath/$mod_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){
panic('module "$mod" not found')
}
}
vfiles := v.v_files_from_dir(import_path)
if vfiles.len == 0 {
@ -974,7 +1001,6 @@ fn (v mut V) add_user_v_files() {
file_imports << *p.import_table
}
}
}
if v.pref.is_verbose {
v.log('imports:')
println(v.table.imports)
@ -989,9 +1015,12 @@ fn (v mut V) add_user_v_files() {
}
// add imports in correct order
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)
idir := os.getwd()
mut module_path := '$idir/$mod_p'
mut module_path := '$ModPath/$mod_p'
// If we are in default mode, we don't parse vlib .v files, but header .vh files in
// TmpPath/vlib
// 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 {
//println('fit $fit.file_path')
if !fit.file_path in v.files {
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')
// build 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
// v -lib ~/v/os => os.o
base := dir.all_after('/')
println('Building module ${base}...')
mod = os.dir(dir)
mod = mod.all_after('/')
println('Building module "${mod}" dir="$dir"...')
//out_name = '$TmpPath/vlib/${base}.o'
out_name = base + '.o'
out_name = mod + '.o'
// Cross compiling? Use separate dirs for each os
/*
if target_os != os.user_os() {
@ -1216,6 +1249,7 @@ fn new_v(args[]string) *V {
cgen: new_cgen(out_name_c)
vroot: vroot
pref: pref
mod: mod
}
}
@ -1362,3 +1396,4 @@ fn update_v() {
println(s)
}
}

View File

@ -156,7 +156,7 @@ fn (p mut Parser) parse() {
}
p.fgenln('\n')
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
// fully qualify the module name, eg base64 to encoding.base64
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.
pub fn dir(path string) string {
if path == '.' {
return getwd()
}
mut pos := -1
// TODO PathSeparator defined in os_win.v doesn't work when building V,
// 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
Content-Type: application/json
$h
$s
')
}
@ -71,6 +70,7 @@ $html
}
pub fn run<T>(port int) {
println('Running vweb app on http://localhost:$port ...')
l := net.listen(port) or { panic('failed to listen') return }
for {
conn := l.accept() or {