mirror of
https://github.com/vlang/v.git
synced 2025-09-14 15:02:33 +03:00
225 lines
6.2 KiB
V
225 lines
6.2 KiB
V
module main
|
|
|
|
import os
|
|
import v.vmod
|
|
import v.help
|
|
import net.urllib
|
|
|
|
fn vpm_install(requested_modules []string, opts []string) {
|
|
if settings.is_help {
|
|
help.print_and_exit('vpm')
|
|
}
|
|
|
|
modules := if requested_modules.len == 0 {
|
|
// Run `v install` in a directory of another V module without passing modules as arguments
|
|
// to install its dependencies.
|
|
if os.exists('./v.mod') {
|
|
println('Detected v.mod file inside the project directory. Using it...')
|
|
manifest := vmod.from_file('./v.mod') or { panic(err) }
|
|
if manifest.dependencies.len == 0 {
|
|
println('Nothing to install.')
|
|
exit(0)
|
|
}
|
|
manifest.dependencies.clone()
|
|
} else {
|
|
eprintln('Specify a module for installation.')
|
|
help.print_and_exit('vpm')
|
|
return
|
|
}
|
|
} else {
|
|
requested_modules.clone()
|
|
}
|
|
|
|
mut external_modules := modules.filter(it.starts_with('https://'))
|
|
mut vpm_modules := modules.filter(it !in external_modules)
|
|
installed_modules := get_installed_modules()
|
|
|
|
if installed_modules.len > 0 && '--once' in opts {
|
|
mut already_installed := []string{}
|
|
if external_modules.len > 0 {
|
|
mut i_deleted := []int{}
|
|
for i, raw_url in external_modules {
|
|
url := urllib.parse(raw_url) or {
|
|
eprintln('Errors while parsing module url "${raw_url}" : ${err}')
|
|
continue
|
|
}
|
|
mod_name := url.path.all_after_last('/')
|
|
if mod_name in installed_modules {
|
|
already_installed << mod_name
|
|
i_deleted << i
|
|
}
|
|
}
|
|
for i in i_deleted.reverse() {
|
|
external_modules.delete(i)
|
|
}
|
|
}
|
|
if vpm_modules.len > 0 {
|
|
mut i_deleted := []int{}
|
|
for i, mod_name in vpm_modules {
|
|
if mod_name in installed_modules {
|
|
already_installed << mod_name
|
|
i_deleted << i
|
|
continue
|
|
}
|
|
}
|
|
for i in i_deleted.reverse() {
|
|
vpm_modules.delete(i)
|
|
}
|
|
}
|
|
if already_installed.len > 0 {
|
|
verbose_println('Already installed modules: ${already_installed}')
|
|
if already_installed.len == modules.len {
|
|
verbose_println('All modules are already installed.')
|
|
exit(0)
|
|
}
|
|
}
|
|
}
|
|
|
|
if vpm_modules.len > 0 {
|
|
vpm_install_from_vpm(vpm_modules)
|
|
}
|
|
if external_modules.len > 0 {
|
|
source := if '--hg' in opts { Source.hg } else { Source.git }
|
|
vpm_install_from_vcs(external_modules, source)
|
|
}
|
|
}
|
|
|
|
fn install_module(vcs string, name string, url string, final_module_path string) ! {
|
|
cmd := '${vcs} ${supported_vcs_install_cmds[vcs]} "${url}" "${final_module_path}"'
|
|
verbose_println(' command: ${cmd}')
|
|
println('Installing module "${name}" from "${url}" to "${final_module_path}" ...')
|
|
res := os.execute(cmd)
|
|
if res.exit_code != 0 {
|
|
verbose_println(' command output: ${res.output}')
|
|
return error('Failed installing module "${name}" to "${final_module_path}" .')
|
|
}
|
|
}
|
|
|
|
fn vpm_install_from_vpm(module_names []string) {
|
|
mut errors := 0
|
|
for n in module_names {
|
|
name := n.trim_space().replace('_', '-')
|
|
mod := get_module_meta_info(name) or {
|
|
errors++
|
|
eprintln('Errors while retrieving meta data for module ${name}:')
|
|
eprintln(err)
|
|
continue
|
|
}
|
|
mut vcs := mod.vcs
|
|
if vcs == '' {
|
|
vcs = supported_vcs_systems[0]
|
|
}
|
|
if vcs !in supported_vcs_systems {
|
|
errors++
|
|
eprintln('Skipping module "${name}", since it uses an unsupported VCS {${vcs}} .')
|
|
continue
|
|
}
|
|
ensure_vcs_is_installed(vcs) or {
|
|
errors++
|
|
eprintln(err)
|
|
continue
|
|
}
|
|
minfo := get_mod_name_info(mod.name)
|
|
if os.exists(minfo.final_module_path) {
|
|
vpm_update([name])
|
|
continue
|
|
}
|
|
install_module(vcs, name, mod.url, minfo.final_module_path) or {
|
|
errors++
|
|
eprintln(err)
|
|
continue
|
|
}
|
|
increment_module_download_count(name) or {
|
|
errors++
|
|
eprintln('Errors while incrementing the download count for ${name}:')
|
|
}
|
|
resolve_dependencies(name, minfo.final_module_path, module_names)
|
|
}
|
|
if errors > 0 {
|
|
exit(1)
|
|
}
|
|
}
|
|
|
|
fn vpm_install_from_vcs(modules []string, vcs_key Source) {
|
|
vcs := vcs_key.str()
|
|
mut errors := 0
|
|
for raw_url in modules {
|
|
url := urllib.parse(raw_url) or {
|
|
errors++
|
|
eprintln('Errors while parsing module url "${raw_url}" : ${err}')
|
|
continue
|
|
}
|
|
// Module identifier based on URL.
|
|
// E.g.: `https://github.com/owner/awesome-v-project` -> `owner/awesome_v_project`
|
|
mut ident := url.path#[1..].replace('-', '_')
|
|
owner, repo_name := ident.split_once('/') or {
|
|
errors++
|
|
eprintln('Errors while retrieving module name for: "${url}"')
|
|
continue
|
|
}
|
|
mut final_module_path := os.real_path(os.join_path(settings.vmodules_path, owner.to_lower(),
|
|
repo_name.to_lower()))
|
|
if os.exists(final_module_path) {
|
|
vpm_update([ident])
|
|
continue
|
|
}
|
|
ensure_vcs_is_installed(vcs) or {
|
|
errors++
|
|
eprintln(err)
|
|
continue
|
|
}
|
|
install_module(vcs, repo_name, url.str(), final_module_path) or {
|
|
errors++
|
|
eprintln(err)
|
|
continue
|
|
}
|
|
vmod_path := os.join_path(final_module_path, 'v.mod')
|
|
if os.exists(vmod_path) {
|
|
manifest := vmod.from_file(vmod_path) or {
|
|
eprintln(err)
|
|
return
|
|
}
|
|
minfo := get_mod_name_info(manifest.name)
|
|
if final_module_path != minfo.final_module_path {
|
|
println('Relocating module from "${ident}" to "${manifest.name}" ("${minfo.final_module_path}") ...')
|
|
if os.exists(minfo.final_module_path) {
|
|
eprintln('Warning module "${minfo.final_module_path}" already exists!')
|
|
eprintln('Removing module "${minfo.final_module_path}" ...')
|
|
os.rmdir_all(minfo.final_module_path) or {
|
|
errors++
|
|
eprintln('Errors while removing "${minfo.final_module_path}" :')
|
|
eprintln(err)
|
|
continue
|
|
}
|
|
}
|
|
os.mv(final_module_path, minfo.final_module_path) or {
|
|
errors++
|
|
eprintln('Errors while relocating module "${repo_name}" :')
|
|
eprintln(err)
|
|
os.rmdir_all(final_module_path) or {
|
|
errors++
|
|
eprintln('Errors while removing "${final_module_path}" :')
|
|
eprintln(err)
|
|
continue
|
|
}
|
|
continue
|
|
}
|
|
println('Module "${repo_name}" relocated to "${manifest.name}" successfully.')
|
|
publisher_dir := os.dir(final_module_path)
|
|
if os.is_dir_empty(publisher_dir) {
|
|
os.rmdir(publisher_dir) or {
|
|
errors++
|
|
eprintln('Errors while removing "${publisher_dir}" :')
|
|
eprintln(err)
|
|
}
|
|
}
|
|
final_module_path = minfo.final_module_path
|
|
}
|
|
ident = manifest.name
|
|
}
|
|
resolve_dependencies(ident, final_module_path, modules)
|
|
}
|
|
if errors > 0 {
|
|
exit(1)
|
|
}
|
|
}
|