mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
tools: add a v where fn join_path command, for platform independent searching the location of a symbol in the local project, vlib, ~/.vmodules (#15014)
This commit is contained in:
committed by
GitHub
parent
d12a8aef68
commit
28fd17654e
205
cmd/tools/vwhere/finder_utils.v
Executable file
205
cmd/tools/vwhere/finder_utils.v
Executable file
@@ -0,0 +1,205 @@
|
||||
module main
|
||||
|
||||
import os
|
||||
import term
|
||||
import regex
|
||||
import v.pref
|
||||
import os.cmdline
|
||||
|
||||
// Symbol type to search
|
||||
enum Symbol {
|
||||
@fn
|
||||
@struct
|
||||
@interface
|
||||
@enum
|
||||
@const
|
||||
var
|
||||
regexp
|
||||
}
|
||||
|
||||
// Visibility of the symbols to search
|
||||
enum Visibility {
|
||||
all
|
||||
@pub
|
||||
pri
|
||||
}
|
||||
|
||||
// Mutability of the symbols to search
|
||||
enum Mutability {
|
||||
any
|
||||
yes
|
||||
not
|
||||
}
|
||||
|
||||
const (
|
||||
args = os.args[2..]
|
||||
verbose = '-v' in cmdline.only_options(args)
|
||||
header = '-h' in cmdline.only_options(args)
|
||||
format = '-f' in cmdline.only_options(args)
|
||||
symbols = {
|
||||
'fn': Symbol.@fn
|
||||
'struct': .@struct
|
||||
'interface': .@interface
|
||||
'enum': .@enum
|
||||
'const': .@const
|
||||
'var': .var
|
||||
'regexp': .regexp
|
||||
}
|
||||
visibilities = {
|
||||
'all': Visibility.all
|
||||
'pub': .@pub
|
||||
'pri': .pri
|
||||
}
|
||||
mutabilities = {
|
||||
'any': Mutability.any
|
||||
'yes': .yes
|
||||
'not': .not
|
||||
}
|
||||
vexe = pref.vexe_path()
|
||||
vroot = os.dir(vexe)
|
||||
vmod_dir = os.vmodules_dir()
|
||||
vmod_paths = os.vmodules_paths()[1..]
|
||||
current_dir = os.abs_path('.')
|
||||
color_out = term.can_show_color_on_stdout()
|
||||
)
|
||||
|
||||
fn (mut cfg Symbol) set_from_str(str_in string) {
|
||||
if str_in !in symbols {
|
||||
invalid_option(cfg, str_in)
|
||||
}
|
||||
cfg = symbols[str_in]
|
||||
}
|
||||
|
||||
fn (mut cfg Visibility) set_from_str(str_in string) {
|
||||
if str_in !in visibilities {
|
||||
invalid_option(cfg, str_in)
|
||||
}
|
||||
cfg = visibilities[str_in]
|
||||
}
|
||||
|
||||
fn (mut cfg Mutability) set_from_str(str_in string) {
|
||||
if str_in !in mutabilities {
|
||||
invalid_option(cfg, str_in)
|
||||
}
|
||||
cfg = mutabilities[str_in]
|
||||
}
|
||||
|
||||
type ParamOption = Mutability | Symbol | Visibility
|
||||
|
||||
// General helpers
|
||||
fn invalid_option(invalid ParamOption, arg string) {
|
||||
match invalid.type_name() {
|
||||
'Symbol' {
|
||||
msg := 'First arg (symbol type) must be one of the following:'
|
||||
make_and_print_error(msg, symbols.keys(), arg)
|
||||
}
|
||||
'Visibility' {
|
||||
msg := '"-vis" (visibility) must be one of the following:'
|
||||
make_and_print_error(msg, visibilities.keys(), arg)
|
||||
}
|
||||
'Mutability' {
|
||||
msg := '"-mut" (mutability) must be one of the following:'
|
||||
make_and_print_error(msg, mutabilities.keys(), arg)
|
||||
}
|
||||
else {
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn valid_args_quantity_or_show_help() {
|
||||
if true in [
|
||||
args.len < 1,
|
||||
'-help' in os.args,
|
||||
'--help' in os.args,
|
||||
os.args[1..] == ['where', 'help'],
|
||||
] {
|
||||
os.system('${os.quoted_path(vexe)} help where')
|
||||
exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn make_and_print_error(msg string, opts []string, arg string) {
|
||||
eprintln('\n' + maybe_color(term.bright_yellow, msg))
|
||||
if opts.len > 0 {
|
||||
eprint(opts.map(maybe_color(term.bright_green, it)).join(' | '))
|
||||
}
|
||||
eprintln(' ...can not be ${maybe_color(term.bright_red, arg)}')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
fn maybe_color(term_color fn (string) string, str string) string {
|
||||
if color_out {
|
||||
return term_color(str)
|
||||
} else {
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_v_files(path string, recursive bool) ?[]string {
|
||||
if path.len == 0 {
|
||||
return error('path cannot be empty')
|
||||
}
|
||||
if !os.is_dir(path) {
|
||||
return error('path does not exist or is not a directory')
|
||||
}
|
||||
mut all_files := []string{}
|
||||
mut entries := os.ls(path)?
|
||||
mut local_path_separator := os.path_separator
|
||||
if path.ends_with(os.path_separator) {
|
||||
local_path_separator = ''
|
||||
}
|
||||
for entry in entries {
|
||||
file := path + local_path_separator + entry
|
||||
if os.is_dir(file) && !os.is_link(file) && recursive {
|
||||
all_files << collect_v_files(file, recursive)?
|
||||
} else if os.exists(file) && (file.ends_with('.v') || file.ends_with('.vsh')) {
|
||||
all_files << file
|
||||
}
|
||||
}
|
||||
return all_files
|
||||
}
|
||||
|
||||
fn search_within_file(file string, query string, is_const bool, v Visibility, m Mutability) (int, string) {
|
||||
mut re := regex.regex_opt(query) or { panic(err) }
|
||||
lines := os.read_lines(file) or { panic(err) }
|
||||
mut const_found := if is_const { false } else { true }
|
||||
mut n_line := 1
|
||||
for line in lines {
|
||||
if line.starts_with('const') {
|
||||
const_found = true
|
||||
}
|
||||
if re.matches_string(line) && const_found {
|
||||
words := line.split(' ').map(it.trim('\t'))
|
||||
match v {
|
||||
.all {}
|
||||
.@pub {
|
||||
if 'pub' !in words {
|
||||
continue
|
||||
}
|
||||
}
|
||||
.pri {
|
||||
if 'pub' in words {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
match m {
|
||||
.any {}
|
||||
.yes {
|
||||
if 'mut' !in words {
|
||||
continue
|
||||
}
|
||||
}
|
||||
.not {
|
||||
if 'mut' in words {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return n_line, line.replace(' {', '')
|
||||
}
|
||||
n_line++
|
||||
}
|
||||
return 0, ''
|
||||
}
|
||||
Reference in New Issue
Block a user