Skip to content

Commit

Permalink
tools.vpm: update vcs handling (#20090)
Browse files Browse the repository at this point in the history
  • Loading branch information
ttytm committed Dec 5, 2023
1 parent 700fbd7 commit 77e65ac
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 69 deletions.
30 changes: 5 additions & 25 deletions cmd/tools/vpm/common.v
Expand Up @@ -39,25 +39,24 @@ fn get_mod_date_info(mut pp pool.PoolProcessor, idx int, wid int) &ModuleDateInf
}
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'
args := vcs_info[vcs].args
mut outputs := []string{}
for step in vcs.args.outdated {
cmd := '${vcs.cmd} ${vcs.args.path} "${path}" ${step}'
for step in args.outdated {
cmd := [vcs.str(), args.path, os.quoted_path(path), step].join(' ')
res := os.execute(cmd)
if res.exit_code < 0 {
verbose_println('Error command: ${cmd}')
verbose_println('Error details:\n${res.output}')
result.exec_err = true
return result
}
if is_hg && res.exit_code == 1 {
if vcs == .hg && res.exit_code == 1 {
result.outdated = true
return result
}
outputs << res.output
}
// vcs.cmd == 'git'
if !is_hg && outputs[1] != outputs[2] {
if vcs == .git && outputs[1] != outputs[2] {
result.outdated = true
}
return result
Expand Down Expand Up @@ -217,10 +216,6 @@ fn get_path_of_existing_module(mod_name string) ?string {
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
}

Expand Down Expand Up @@ -252,12 +247,6 @@ fn ensure_vmodules_dir_exist() {
}
}

fn (vcs &VCS) is_executable() ! {
os.find_abs_path_of_executable(vcs.cmd) or {
return error('VPM needs `${vcs.cmd}` to be installed.')
}
}

fn increment_module_download_count(name string) ! {
if settings.no_dl_count_increment {
println('Skipping download count increment for `${name}`.')
Expand Down Expand Up @@ -296,15 +285,6 @@ fn resolve_dependencies(manifest ?vmod.Manifest, modules []string) {
}
}

fn vcs_used_in_dir(dir string) ?VCS {
for vcs in supported_vcs.values() {
if os.is_dir(os.real_path(os.join_path(dir, vcs.dir))) {
return vcs
}
}
return none
}

fn verbose_println(msg string) {
if settings.is_verbose {
println(msg)
Expand Down
5 changes: 3 additions & 2 deletions cmd/tools/vpm/install.v
Expand Up @@ -121,8 +121,9 @@ fn (m Module) install() InstallResult {
}
}
vcs := m.vcs or { settings.vcs }
version_opt := if m.version != '' { ' ${vcs.args.version} ${m.version}' } else { '' }
cmd := '${vcs.cmd} ${vcs.args.install}${version_opt} "${m.url}" "${m.install_path}"'
args := vcs_info[vcs].args
version_opt := if m.version != '' { '${args.version} ${m.version}' } else { '' }
cmd := [vcs.str(), args.install, version_opt, m.url, os.quoted_path(m.install_path)].join(' ')
vpm_log(@FILE_LINE, @FN, 'command: ${cmd}')
println('Installing `${m.name}`...')
verbose_println(' cloning from `${m.url}` to `${m.install_path_fmted}`')
Expand Down
8 changes: 4 additions & 4 deletions cmd/tools/vpm/parse.v
Expand Up @@ -28,7 +28,7 @@ mut:

fn parse_query(query []string) []Module {
mut p := Parser{
is_git_setting: settings.vcs.cmd == 'git'
is_git_setting: settings.vcs == .git
}
for m in query {
p.parse_module(m)
Expand Down Expand Up @@ -96,20 +96,20 @@ fn (mut p Parser) parse_module(m string) {
// Verify VCS.
mut is_git_module := true
vcs := if info.vcs != '' {
info_vcs := supported_vcs[info.vcs] or {
info_vcs := vcs_from_str(info.vcs) or {
vpm_error('skipping `${info.name}`, since it uses an unsupported version control system `${info.vcs}`.')
p.errors++
return
}
is_git_module = info.vcs == 'git'
is_git_module = info_vcs == .git
if !is_git_module && version != '' {
vpm_error('skipping `${info.name}`, version installs are currently only supported for projects using `git`.')
p.errors++
return
}
info_vcs
} else {
supported_vcs['git']
VCS.git
}
vcs.is_executable() or {
vpm_error(err.msg())
Expand Down
2 changes: 1 addition & 1 deletion cmd/tools/vpm/settings.v
Expand Up @@ -35,7 +35,7 @@ fn init_settings() VpmSettings {
is_verbose: '-v' in opts || '--verbose' in opts
is_force: '-f' in opts || '--force' in opts
server_urls: cmdline.options(args, '--server-urls')
vcs: supported_vcs[if '--hg' in opts { 'hg' } else { 'git' }]
vcs: if '--hg' in opts { .hg } else { .git }
vmodules_path: os.vmodules_dir()
no_dl_count_increment: os.getenv('CI') != '' || (no_inc_env != '' && no_inc_env != '0')
fail_on_prompt: os.getenv('VPM_FAIL_ON_PROMPT') != ''
Expand Down
3 changes: 2 additions & 1 deletion cmd/tools/vpm/update.v
Expand Up @@ -54,7 +54,8 @@ fn update_module(mut pp pool.PoolProcessor, idx int, wid int) &UpdateResult {
vpm_error(err.msg())
return &UpdateResult{}
}
cmd := '${vcs.cmd} ${vcs.args.path} "${install_path}" ${vcs.args.update}'
args := vcs_info[vcs].args
cmd := [vcs.str(), args.path, os.quoted_path(install_path), args.update].join(' ')
vpm_log(@FILE_LINE, @FN, 'cmd: ${cmd}')
println('Updating module `${name}` in `${fmt_mod_path(install_path)}`...')
res := os.execute_opt(cmd) or {
Expand Down
67 changes: 67 additions & 0 deletions cmd/tools/vpm/vcs.v
@@ -0,0 +1,67 @@
module main

import os

// Supported version control system commands.
enum VCS {
git
hg
}

struct VCSInfo {
dir string @[required]
args struct {
install string @[required]
version string @[required] // flag to specify a version, added to install.
path string @[required] // flag to specify a path. E.g., used to explicitly work on a path during multithreaded updating.
update string @[required]
outdated []string @[required]
}
}

const vcs_info = {
VCS.git: VCSInfo{
dir: '.git'
args: struct {
install: 'clone --depth=1 --recursive --shallow-submodules'
version: '--single-branch -b'
update: 'pull --recurse-submodules' // pulling with `--depth=1` leads to conflicts when the upstream has more than 1 new commits.
path: '-C'
outdated: ['fetch', 'rev-parse @', 'rev-parse @{u}']
}
}
VCS.hg: VCSInfo{
dir: '.hg'
args: struct {
install: 'clone'
version: '' // not supported yet.
update: 'pull --update'
path: '-R'
outdated: ['incoming']
}
}
}

fn (vcs &VCS) is_executable() ! {
cmd := vcs.str()
os.find_abs_path_of_executable(cmd) or {
return error('VPM requires that `${cmd}` is executable.')
}
}

fn vcs_used_in_dir(dir string) ?VCS {
for vcs, info in vcs_info {
if os.is_dir(os.real_path(os.join_path(dir, info.dir))) {
return vcs
}
}
return none
}

fn vcs_from_str(str string) ?VCS {
return match str {
'git' { .git }
'hg' { .hg }
else { none }
}
}
36 changes: 0 additions & 36 deletions cmd/tools/vpm/vpm.v
Expand Up @@ -9,48 +9,12 @@ import rand
import v.help
import v.vmod

struct VCS {
dir string @[required]
cmd string @[required]
args struct {
install string @[required]
version string @[required] // flag to specify a version, added to install.
path string @[required] // flag to specify a path. E.g., used to explicitly work on a path during multithreaded updating.
update string @[required]
outdated []string @[required]
}
}

const settings = init_settings()
const default_vpm_server_urls = ['https://vpm.vlang.io', 'https://vpm.url4e.com']
const vpm_server_urls = rand.shuffle_clone(default_vpm_server_urls) or { [] } // ensure that all queries are distributed fairly
const valid_vpm_commands = ['help', 'search', 'install', 'update', 'upgrade', 'outdated', 'list',
'remove', 'show']
const excluded_dirs = ['cache', 'vlib']
const supported_vcs = {
'git': VCS{
dir: '.git'
cmd: 'git'
args: struct {
install: 'clone --depth=1 --recursive --shallow-submodules'
version: '--single-branch -b'
update: 'pull --recurse-submodules' // pulling with `--depth=1` leads to conflicts when the upstream has more than 1 new commits.
path: '-C'
outdated: ['fetch', 'rev-parse @', 'rev-parse @{u}']
}
}
'hg': VCS{
dir: '.hg'
cmd: 'hg'
args: struct {
install: 'clone'
version: '' // not supported yet.
update: 'pull --update'
path: '-R'
outdated: ['incoming']
}
}
}

fn main() {
// This tool is intended to be launched by the v frontend,
Expand Down

0 comments on commit 77e65ac

Please sign in to comment.