183 lines
4.7 KiB
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.')
|
||
|
}
|