v/tools/vpm.v

183 lines
4.7 KiB
V

module main
import (
http
os
json
)
const (
//url = 'http://localhost:8089'
url = 'https://vpm.best'
valid_vpm_commands = ['help', 'search', 'install', 'update', 'remove']
)
struct Mod {
id int
name string
url string
nr_downloads int
}
fn main() {
ensure_vmodules_dir_exist()
change_to_vmodules_dir()
// This tool is intended to be launched by the v frontend,
// so its first argument is the path to the v frontend executable.
args := os.args // args are: vpm vexepath SUBCOMMAND module names
if args.len < 3 {
vpm_help([]string)
exit(5)
}
vpm_command := args[2]
module_names := args[3..]
//println('module names: ') println(module_names)
match vpm_command {
'help' { vpm_help(module_names) }
'search' { vpm_search(module_names) }
'install' { vpm_install(module_names) }
'update' { vpm_update(module_names) }
'remove' { vpm_remove(module_names) }
else {
println('Error: you tried to run "v $vpm_command"')
println('... but the v package management tool vpm only knows about these commands:')
for validcmd in valid_vpm_commands {
println(' v $validcmd')
}
exit(3)
}
}
}
fn vpm_search(module_names []string){
if user_asks_for_help(module_names) {
println('Usage:')
println(' v search keyword1 [keyword2] [...]')
println(' ^^^^^^^^^^^^^^^^^ will search https://vpm.vlang.io/ for matching modules,')
println(' and will show details about them')
exit(0)
}
if module_names.len == 0 {
println(' v search requires *at least one* keyword')
exit(2)
}
todo('search')
}
fn vpm_install(module_names []string){
if user_asks_for_help(module_names) {
println('Usage:')
println(' v install module [module] [module] [...]')
println(' ^^^^^^^^^^^^^ will install the modules you specified')
exit(0)
}
if module_names.len == 0 {
println(' v install requires *at least one* module name')
exit(2)
}
mut errors := 0
for name in module_names {
modurl := url + '/jsmod/$name'
r := http.get(modurl) or { panic(err) }
if r.status_code == 404 {
println('Skipping module "$name", since $url reported that "$name" does not exist.')
errors++
continue
}
if r.status_code != 200 {
println('Skipping module "$name", since $url responded with $r.status_code http status code. Please try again later.')
errors++
continue
}
s := r.text
mod := json.decode(Mod, s) or {
errors++
println('Skipping module "$name", since its information is not in json format.')
continue
}
if( '' == mod.url || '' == mod.name ){
errors++
// a possible 404 error, which means a missing module?
println('Skipping module "$name", since it is missing name or url information.')
continue
}
final_module_path := get_vmodules_dir_path() + '/' + mod.name.replace('.', '/')
println('Installing module "$name" from $mod.url to $final_module_path ...')
_ = os.exec('git clone --depth=1 $mod.url $final_module_path') or {
errors++
println('Could not install module "$name" to "$final_module_path" .')
println('Error details: $err')
continue
}
}
if errors > 0 {
exit(1)
}
}
fn vpm_update(module_names []string){
if user_asks_for_help(module_names) {
println('Usage: ')
println(' a) v update module [module] [module] [...]')
println(' ^^^^^^^^^^^^ will update the listed modules to their latest versions')
println(' b) v update')
println(' ^^^^^^^^^^^^ will update ALL installed modules to their latest versions')
exit(0)
}
todo('update')
}
fn vpm_remove(module_names []string){
if user_asks_for_help(module_names) {
println('Usage: ')
println(' a) v remove module [module] [module] [...]')
println(' ^^^^^^^^^^^^ will remove the listed modules')
println(' b) v remove')
println(' ^^^^^^^^^^^^ will remove ALL installed modules')
exit(0)
}
todo('remove')
}
fn get_vmodules_dir_path() string {
return os.home_dir() + '.vmodules'
}
fn ensure_vmodules_dir_exist() {
home_vmodules := get_vmodules_dir_path()
if !os.dir_exists( home_vmodules ) {
println('Creating $home_vmodules/ ...')
os.mkdir(home_vmodules)
}
}
fn change_to_vmodules_dir() {
os.chdir(get_vmodules_dir_path())
}
fn todo(vpm_command string){
println('TODO: v $vpm_command')
exit(4)
}
fn user_asks_for_help(module_names []string) bool {
return ('-h' in module_names) || ('--help' in module_names) || ('help' in module_names)
}
fn vpm_help(module_names []string){
println('Usage:')
println(' b) v search keyword1 [keyword2] [...]')
println(' c) v install module [module] [module] [...]')
println(' d) v update [module] [...]')
println(' e) v remove [module] [...]')
println('')
println(' You can also pass -h or --help after each vpm command from the above, to see more details about it.')
}