mirror of
https://github.com/vlang/v.git
synced 2025-09-16 07:52:32 +03:00
207 lines
5.1 KiB
V
207 lines
5.1 KiB
V
// Copyright (c) 2019-2023 Alexander Medvednikov. All rights reserved.
|
||
// Use of this source code is governed by an MIT license
|
||
// that can be found in the LICENSE file.
|
||
module main
|
||
|
||
import os
|
||
import os.cmdline
|
||
import rand
|
||
import v.help
|
||
import v.vmod
|
||
|
||
struct VpmSettings {
|
||
mut:
|
||
is_help bool
|
||
is_verbose bool
|
||
server_urls []string
|
||
vmodules_path string
|
||
}
|
||
|
||
enum Source {
|
||
git
|
||
hg
|
||
vpm
|
||
}
|
||
|
||
const (
|
||
settings = &VpmSettings{}
|
||
default_vpm_server_urls = ['https://vpm.vlang.io', 'https://vpm.url4e.com']
|
||
vpm_server_urls = rand.shuffle_clone(default_vpm_server_urls) or { [] } // ensure that all queries are distributed fairly
|
||
valid_vpm_commands = ['help', 'search', 'install', 'update', 'upgrade', 'outdated',
|
||
'list', 'remove', 'show']
|
||
excluded_dirs = ['cache', 'vlib']
|
||
supported_vcs_systems = ['git', 'hg']
|
||
supported_vcs_folders = ['.git', '.hg']
|
||
supported_vcs_update_cmds = {
|
||
'git': 'pull --recurse-submodules' // pulling with `--depth=1` leads to conflicts, when the upstream is more than 1 commit newer
|
||
'hg': 'pull --update'
|
||
}
|
||
supported_vcs_install_cmds = {
|
||
'git': 'clone --depth=1 --recursive --shallow-submodules'
|
||
'hg': 'clone'
|
||
}
|
||
supported_vcs_outdated_steps = {
|
||
'git': ['fetch', 'rev-parse @', 'rev-parse @{u}']
|
||
'hg': ['incoming']
|
||
}
|
||
supported_vcs_version_cmds = {
|
||
'git': 'version'
|
||
'hg': 'version'
|
||
}
|
||
)
|
||
|
||
fn main() {
|
||
init_settings()
|
||
// This tool is intended to be launched by the v frontend,
|
||
// which provides the path to V inside os.getenv('VEXE')
|
||
// args are: vpm [options] SUBCOMMAND module names
|
||
params := cmdline.only_non_options(os.args[1..])
|
||
options := cmdline.only_options(os.args[1..])
|
||
verbose_println('cli params: ${params}')
|
||
if params.len < 1 {
|
||
help.print_and_exit('vpm', exit_code: 5)
|
||
}
|
||
vpm_command := params[0]
|
||
mut requested_modules := params[1..].clone()
|
||
ensure_vmodules_dir_exist()
|
||
// println('module names: ') println(requested_modules)
|
||
match vpm_command {
|
||
'help' {
|
||
help.print_and_exit('vpm')
|
||
}
|
||
'search' {
|
||
vpm_search(requested_modules)
|
||
}
|
||
'install' {
|
||
vpm_install(requested_modules, options)
|
||
}
|
||
'update' {
|
||
vpm_update(requested_modules)
|
||
}
|
||
'upgrade' {
|
||
vpm_upgrade()
|
||
}
|
||
'outdated' {
|
||
vpm_outdated()
|
||
}
|
||
'list' {
|
||
vpm_list()
|
||
}
|
||
'remove' {
|
||
vpm_remove(requested_modules)
|
||
}
|
||
'show' {
|
||
vpm_show(requested_modules)
|
||
}
|
||
else {
|
||
eprintln('Error: you tried to run "v ${vpm_command}"')
|
||
eprintln('... but the v package management tool vpm only knows about these commands:')
|
||
for validcmd in valid_vpm_commands {
|
||
eprintln(' v ${validcmd}')
|
||
}
|
||
exit(3)
|
||
}
|
||
}
|
||
}
|
||
|
||
fn init_settings() {
|
||
mut s := &VpmSettings(unsafe { nil })
|
||
unsafe {
|
||
s = settings
|
||
}
|
||
s.is_help = '-h' in os.args || '--help' in os.args || 'help' in os.args
|
||
s.is_verbose = '-v' in os.args
|
||
s.server_urls = cmdline.options(os.args, '-server-url')
|
||
s.vmodules_path = os.vmodules_dir()
|
||
}
|
||
|
||
fn vpm_upgrade() {
|
||
outdated := get_outdated() or { exit(1) }
|
||
if outdated.len > 0 {
|
||
vpm_update(outdated)
|
||
} else {
|
||
println('Modules are up to date.')
|
||
}
|
||
}
|
||
|
||
fn vpm_outdated() {
|
||
outdated := get_outdated() or { exit(1) }
|
||
if outdated.len > 0 {
|
||
eprintln('Outdated modules:')
|
||
for m in outdated {
|
||
eprintln(' ${m}')
|
||
}
|
||
} else {
|
||
println('Modules are up to date.')
|
||
}
|
||
}
|
||
|
||
fn vpm_list() {
|
||
module_names := get_installed_modules()
|
||
if module_names.len == 0 {
|
||
eprintln('You have no modules installed.')
|
||
exit(0)
|
||
}
|
||
for mod in module_names {
|
||
println(mod)
|
||
}
|
||
}
|
||
|
||
fn vpm_remove(module_names []string) {
|
||
if settings.is_help {
|
||
help.print_and_exit('remove')
|
||
}
|
||
if module_names.len == 0 {
|
||
eprintln('´v remove´ requires *at least one* module name.')
|
||
exit(2)
|
||
}
|
||
for name in module_names {
|
||
final_module_path := valid_final_path_of_existing_module(name) or { continue }
|
||
eprintln('Removing module "${name}" ...')
|
||
verbose_println('removing folder ${final_module_path}')
|
||
os.rmdir_all(final_module_path) or {
|
||
verbose_println('error while removing "${final_module_path}": ${err.msg()}')
|
||
}
|
||
// delete author directory if it is empty
|
||
author := name.split('.')[0]
|
||
author_dir := os.real_path(os.join_path(settings.vmodules_path, author))
|
||
if !os.exists(author_dir) {
|
||
continue
|
||
}
|
||
if os.is_dir_empty(author_dir) {
|
||
verbose_println('removing author folder ${author_dir}')
|
||
os.rmdir(author_dir) or {
|
||
verbose_println('error while removing "${author_dir}": ${err.msg()}')
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
fn vpm_show(module_names []string) {
|
||
installed_modules := get_installed_modules()
|
||
for module_name in module_names {
|
||
if module_name !in installed_modules {
|
||
module_meta_info := get_module_meta_info(module_name) or { continue }
|
||
print('
|
||
Name: ${module_meta_info.name}
|
||
Homepage: ${module_meta_info.url}
|
||
Downloads: ${module_meta_info.nr_downloads}
|
||
Installed: False
|
||
--------
|
||
')
|
||
continue
|
||
}
|
||
path := os.join_path(os.vmodules_dir(), module_name.replace('.', os.path_separator))
|
||
mod := vmod.from_file(os.join_path(path, 'v.mod')) or { continue }
|
||
print('Name: ${mod.name}
|
||
Version: ${mod.version}
|
||
Description: ${mod.description}
|
||
Homepage: ${mod.repo_url}
|
||
Author: ${mod.author}
|
||
License: ${mod.license}
|
||
Location: ${path}
|
||
Requires: ${mod.dependencies.join(', ')}
|
||
--------
|
||
')
|
||
}
|
||
}
|