Skip to content

Commit

Permalink
tools: cleanup, prepare vpm version installs (vlang#19821)
Browse files Browse the repository at this point in the history
  • Loading branch information
ttytm authored Nov 10, 2023
1 parent 33e865c commit 11bc808
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 159 deletions.
121 changes: 58 additions & 63 deletions cmd/tools/vpm/common.v
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
module main

import json
import os
import v.vmod
import sync.pool
import net.http
import net.urllib
import sync.pool
import v.vmod
import json
import term
import log

struct Module {
mut:
// Fields that can be populated via VPM API.
// Fields determined by the url or the info received from the VPM API.
name string
url string
vcs string
// Fields based on input / environment.
// Fields based on preference / environment.
version string // specifies the requested version.
install_path string
is_installed bool
Expand Down Expand Up @@ -44,7 +44,7 @@ struct ErrorOptions {
}

fn parse_query(query []string) ([]Module, []Module) {
mut vpm_modules, mut extended_modules := []Module{}, []Module{}
mut vpm_modules, mut external_modules := []Module{}, []Module{}
mut errors := 0
for m in query {
ident, version := m.rsplit_once('@') or { m, '' }
Expand Down Expand Up @@ -86,15 +86,15 @@ fn parse_query(query []string) ([]Module, []Module) {
mod.installed_version = v.output.all_after_last('/').trim_space()
}
if is_external {
extended_modules << mod
external_modules << mod
} else {
vpm_modules << mod
}
}
if errors > 0 && errors == query.len {
exit(1)
}
return vpm_modules, extended_modules
return vpm_modules, external_modules
}

fn has_vmod(url string) bool {
Expand All @@ -120,12 +120,12 @@ fn get_mod_date_info(mut pp pool.PoolProcessor, idx int, wid int) &ModuleDateInf
mut result := &ModuleDateInfo{
name: pp.get_item[string](idx)
}
final_module_path := get_path_of_existing_module(result.name) or { return result }
vcs := vcs_used_in_dir(final_module_path) or { return result }
path := get_path_of_existing_module(result.name) or { return result }
vcs := vcs_used_in_dir(path) or { return result }
is_hg := vcs.cmd == 'hg'
mut outputs := []string{}
for step in vcs.args.outdated {
cmd := '${vcs.cmd} ${vcs.args.path} "${final_module_path}" ${step}'
cmd := '${vcs.cmd} ${vcs.args.path} "${path}" ${step}'
res := os.execute(cmd)
if res.exit_code < 0 {
verbose_println('Error command: ${cmd}')
Expand All @@ -151,20 +151,20 @@ fn get_mod_vpm_info(name string) !ModuleVpmInfo {
return error('invalid module name `${name}`.')
}
mut errors := []string{}
for server_url in vpm_server_urls {
modurl := server_url + '/api/packages/${name}'
for url in vpm_server_urls {
modurl := url + '/api/packages/${name}'
verbose_println('Retrieving metadata for `${name}` from `${modurl}`...')
r := http.get(modurl) or {
errors << 'Http server did not respond to our request for `${modurl}`.'
errors << 'Error details: ${err}'
continue
}
if r.status_code == 404 || r.body.trim_space() == '404' {
errors << 'Skipping module `${name}`, since `${server_url}` reported that `${name}` does not exist.'
errors << 'Skipping module `${name}`, since `${url}` reported that `${name}` does not exist.'
continue
}
if r.status_code != 200 {
errors << 'Skipping module `${name}`, since `${server_url}` responded with ${r.status_code} http status code. Please try again later.'
errors << 'Skipping module `${name}`, since `${url}` responded with ${r.status_code} http status code. Please try again later.'
continue
}
s := r.body
Expand Down Expand Up @@ -198,10 +198,10 @@ fn get_name_from_url(raw_url string) !string {
}

fn get_outdated() ![]string {
module_names := get_installed_modules()
installed := get_installed_modules()
mut outdated := []string{}
mut pp := pool.new_pool_processor(callback: get_mod_date_info)
pp.work_on_items(module_names)
pp.work_on_items(installed)
for res in pp.get_results[ModuleDateInfo]() {
if res.exec_err {
return error('failed to check the latest commits for `${res.name}`.')
Expand All @@ -216,9 +216,7 @@ fn get_outdated() ![]string {
fn get_all_modules() []string {
url := get_working_server_url()
r := http.get(url) or {
vpm_error(err.msg(),
verbose: true
)
vpm_error(err.msg(), verbose: true)
exit(1)
}
if r.status_code != 200 {
Expand Down Expand Up @@ -282,6 +280,24 @@ fn get_installed_modules() []string {
return modules
}

fn get_path_of_existing_module(mod_name string) ?string {
name := get_name_from_url(mod_name) or { mod_name.replace('-', '_').to_lower() }
path := os.real_path(os.join_path(settings.vmodules_path, name.replace('.', os.path_separator)))
if !os.exists(path) {
vpm_error('failed to find `${name}` at `${path}`.')
return none
}
if !os.is_dir(path) {
vpm_error('skipping `${path}`, since it is not a directory.')
return none
}
vcs_used_in_dir(path) or {
vpm_error('skipping `${path}`, since it uses an unsupported version control system.')
return none
}
return path
}

fn get_working_server_url() string {
server_urls := if settings.server_urls.len > 0 {
settings.server_urls
Expand All @@ -291,27 +307,26 @@ fn get_working_server_url() string {
for url in server_urls {
verbose_println('Trying server url: ${url}')
http.head(url) or {
verbose_println(' ${url} failed.')
vpm_error('failed to connect to server url `${url}`.', details: err.msg())
continue
}
return url
}
panic('No responding vpm server found. Please check your network connectivity and try again later.')
vpm_error('No responding vpm server found. Please check your network connectivity and try again later.')
exit(1)
}

fn ensure_vmodules_dir_exist() {
if !os.is_dir(settings.vmodules_path) {
println('Creating `${settings.vmodules_path}` ...')
println('Creating `${settings.vmodules_path}`...')
os.mkdir(settings.vmodules_path) or {
vpm_error(err.msg(),
verbose: true
)
vpm_error(err.msg(), verbose: true)
exit(1)
}
}
}

fn ensure_vcs_is_installed(vcs &VCS) ! {
fn (vcs &VCS) is_executable() ! {
os.find_abs_path_of_executable(vcs.cmd) or {
return error('VPM needs `${vcs.cmd}` to be installed.')
}
Expand All @@ -323,39 +338,37 @@ fn increment_module_download_count(name string) ! {
return
}
mut errors := []string{}

for server_url in vpm_server_urls {
modurl := server_url + '/api/packages/${name}/incr_downloads'
for url in vpm_server_urls {
modurl := url + '/api/packages/${name}/incr_downloads'
r := http.post(modurl, '') or {
errors << 'Http server did not respond to our request for `${modurl}`.'
errors << 'Error details: ${err}'
continue
}
if r.status_code != 200 {
errors << 'Failed to increment the download count for module `${name}`, since `${server_url}` responded with ${r.status_code} http status code. Please try again later.'
errors << 'Failed to increment the download count for module `${name}`, since `${url}` responded with ${r.status_code} http status code. Please try again later.'
continue
}
return
}
return error(errors.join_lines())
}

fn resolve_dependencies(name string, module_path string, module_names []string) {
vmod_path := os.join_path(module_path, 'v.mod')
if !os.exists(vmod_path) {
return
}
manifest := vmod.from_file(vmod_path) or {
vpm_error(err.msg(),
verbose: true
)
return
fn get_manifest(path string) ?vmod.Manifest {
return vmod.from_file(os.join_path(path, 'v.mod')) or {
eprintln(term.ecolorize(term.yellow, 'warning: ') +
'failed to find v.mod file for `${path.all_after_last(os.path_separator)}`.')
return none
}
}

fn resolve_dependencies(manifest ?vmod.Manifest, modules []string) {
mod := manifest or { return }
// Filter out modules that are both contained in the input query and listed as
// dependencies in the mod file of the module that is supposed to be installed.
deps := manifest.dependencies.filter(it !in module_names)
deps := mod.dependencies.filter(it !in modules)
if deps.len > 0 {
println('Resolving ${deps.len} dependencies for module `${name}` ...')
println('Resolving ${deps.len} dependencies for module `${mod.name}`...')
verbose_println('Found dependencies: ${deps}')
vpm_install(deps)
}
Expand All @@ -370,27 +383,9 @@ fn vcs_used_in_dir(dir string) ?VCS {
return none
}

fn get_path_of_existing_module(mod_name string) ?string {
name := get_name_from_url(mod_name) or { mod_name.replace('-', '_').to_lower() }
path := os.real_path(os.join_path(settings.vmodules_path, name.replace('.', os.path_separator)))
if !os.exists(path) {
vpm_error('failed to find `${name}` at `${path}`.')
return none
}
if !os.is_dir(path) {
vpm_error('skipping `${path}`, since it is not a directory.')
return none
}
vcs_used_in_dir(path) or {
vpm_error('skipping `${path}`, since it uses an unsupported version control system.')
return none
}
return path
}

fn verbose_println(s string) {
fn verbose_println(msg string) {
if settings.is_verbose {
println(s)
println(msg)
}
}

Expand Down
Loading

0 comments on commit 11bc808

Please sign in to comment.