v.util: extract v.util.version, use it to speed up building `v repl`, `v up` and `v doctor`

pull/10978/head
Delyan Angelov 2021-07-27 12:35:54 +03:00
parent cb7be87d4e
commit 6134c4870b
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
12 changed files with 134 additions and 122 deletions

View File

@ -6,7 +6,6 @@ import time
import term
import math
import scripting
import v.util
struct CmdResult {
mut:
@ -127,8 +126,12 @@ fn new_aints(ovals []int, extreme_mins int, extreme_maxs int) Aints {
return res
}
fn bold(s string) string {
return term.colorize(term.bold, s)
}
fn (a Aints) str() string {
return util.bold('${a.average:6.2f}') +
return bold('${a.average:6.2f}') +
'ms ± σ: ${a.stddev:4.1f}ms, min: ${a.imin:4}ms, max: ${a.imax:4}ms, runs:${a.values.len:3}, nmins:${a.nmins:2}, nmaxs:${a.nmaxs:2}'
}
@ -346,7 +349,7 @@ fn (mut context Context) show_diff_summary() {
first_marker = ' '
cpercent := (r.atiming.average / base) * 100 - 100
if r.icmd == 0 {
first_marker = util.bold('>')
first_marker = bold('>')
first_cmd_percentage = cpercent
}
println(' $first_marker${(i + 1):3} | ${cpercent:5.1f}% slower | ${r.cmd:-57s} | $r.atiming')

View File

@ -1,6 +1,7 @@
import os
import time
import v.util
import term
import v.util.version
import runtime
struct App {
@ -109,7 +110,7 @@ fn (mut a App) collect_info() {
a.line('vexe mtime', time.unix(os.file_last_mod_unix(vexe)).str())
a.line('is vroot writable', is_writable_dir(vroot).str())
a.line('is vmodules writable', is_writable_dir(vmodules).str())
a.line('V full version', util.full_v_version(true))
a.line('V full version', version.full_v_version(true))
vtmp := os.getenv('VTMP')
if vtmp != '' {
a.line('env VTMP', '"$vtmp"')
@ -149,7 +150,7 @@ fn (mut a App) cmd(c CmdConfig) string {
}
fn (mut a App) line(label string, value string) {
a.println('$label: ${util.bold(value)}')
a.println('$label: ${term.colorize(term.bold, value)}')
}
fn (app &App) parse(config string, sep string) map[string]string {

View File

@ -8,7 +8,7 @@ import term
import rand
import readline
import os.cmdline
import v.util
import v.util.version
struct Repl {
mut:
@ -102,7 +102,7 @@ fn (r &Repl) current_source_code(should_add_temp_lines bool, not_add_print bool)
}
fn repl_help() {
println(util.full_v_version(false))
println(version.full_v_version(false))
println('
|help Displays this information.
|list Show the program so far.
@ -114,8 +114,8 @@ fn repl_help() {
fn run_repl(workdir string, vrepl_prefix string) {
if !is_stdin_a_pipe {
println(util.full_v_version(false))
println('Use Ctrl-C or ${util.pretty_print('exit')} to exit, or ${util.pretty_print('help')} to see other available commands')
println(version.full_v_version(false))
println('Use Ctrl-C or ${term.highlight_command('exit')} to exit, or ${term.highlight_command('help')} to see other available commands')
}
if vstartup != '' {

View File

@ -2,7 +2,7 @@ module main
import os
import v.pref
import v.util
import v.util.version
import v.util.recompilation
struct App {
@ -29,8 +29,8 @@ fn main() {
os.chdir(app.vroot)
println('Updating V...')
app.update_from_master()
v_hash := util.githash(false)
current_hash := util.githash(true)
v_hash := version.githash(false)
current_hash := version.githash(true)
// println(v_hash)
// println(current_hash)
if v_hash == current_hash {

View File

@ -5,8 +5,10 @@ module main
import help
import os
import term
import v.pref
import v.util
import v.util.version
import v.builder
const (
@ -60,10 +62,10 @@ fn main() {
// Running `./v` without args launches repl
if args.len == 0 {
if os.is_atty(0) != 0 {
cmd_exit := util.pretty_print('exit')
cmd_help := util.pretty_print('v help')
file_main := util.pretty_print('main.v')
cmd_run := util.pretty_print('v run main.v')
cmd_exit := term.highlight_command('exit')
cmd_help := term.highlight_command('v help')
file_main := term.highlight_command('main.v')
cmd_run := term.highlight_command('v run main.v')
println('Welcome to the V REPL (for help with V itself, type $cmd_exit, then run $cmd_help).')
eprintln(' NB: the REPL is highly experimental. For best V experience, use a text editor,')
eprintln(' save your code in a $file_main file and execute: $cmd_run')
@ -114,7 +116,7 @@ fn main() {
exit(1)
}
'version' {
println(util.full_v_version(prefs.is_verbose))
println(version.full_v_version(prefs.is_verbose))
return
}
else {}
@ -128,7 +130,7 @@ fn main() {
if prefs.is_help {
invoke_help_and_exit(args)
}
eprintln('v $command: unknown command\nRun ${util.pretty_print('v help')} for usage.')
eprintln('v $command: unknown command\nRun ${term.highlight_command('v help')} for usage.')
exit(1)
}
@ -138,7 +140,7 @@ fn invoke_help_and_exit(remaining []string) {
2 { help.print_and_exit(remaining[1]) }
else {}
}
println('${util.pretty_print('v help')}: provide only one help topic.')
println('For usage information, use ${util.pretty_print('v help')}.')
println('${term.highlight_command('v help')}: provide only one help topic.')
println('For usage information, use ${term.highlight_command('v help')}.')
exit(1)
}

View File

@ -191,3 +191,9 @@ pub fn yellow(msg string) string {
pub fn bright_yellow(msg string) string {
return format(msg, '93', '39')
}
// highlight_command highlights the command with an on-brand background
// to make CLI commands immediately recognizable.
pub fn highlight_command(command string) string {
return bright_white(bg_cyan(' $command '))
}

View File

@ -10,6 +10,7 @@ import v.vmod
import v.token
import v.pref
import v.util
import v.util.version
import v.errors
import v.pkgconfig
import v.gen.native
@ -5683,7 +5684,7 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type {
node.val = (node.pos.col + 1).str()
}
.vhash {
node.val = util.vhash()
node.val = version.vhash()
}
.vmod_file {
// cache the vmod content, do not read it many times

View File

@ -9,6 +9,7 @@ import v.ast
import v.pref
import v.token
import v.util
import v.util.version
import v.depgraph
const (
@ -389,8 +390,8 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
}
pub fn (g &Gen) hashes() string {
mut res := c_commit_hash_default.replace('@@@', util.vhash())
res += c_current_commit_hash_default.replace('@@@', util.githash(g.pref.building_v))
mut res := c_commit_hash_default.replace('@@@', version.vhash())
res += c_current_commit_hash_default.replace('@@@', version.githash(g.pref.building_v))
return res
}

View File

@ -5,6 +5,7 @@ import v.ast
import v.token
import v.pref
import v.util
import v.util.version
import v.depgraph
import encoding.base64
import v.gen.js.sourcemap
@ -329,8 +330,8 @@ pub fn (mut g JsGen) init() {
}
pub fn (g JsGen) hashes() string {
mut res := '// V_COMMIT_HASH $util.vhash()\n'
res += '// V_CURRENT_COMMIT_HASH ${util.githash(g.pref.building_v)}\n'
mut res := '// V_COMMIT_HASH $version.vhash()\n'
res += '// V_CURRENT_COMMIT_HASH ${version.githash(g.pref.building_v)}\n'
return res
}

View File

@ -1,11 +1,14 @@
import os
import term
import benchmark
import v.util
import v.util.vtest
const turn_off_vcolors = os.setenv('VCOLORS', 'never', true)
fn bold(s string) string {
return term.colorize(term.bold, s)
}
//
// NB: skip_compile_files can be used for totally skipping .v files temporarily.
// .v files in skip_valgrind_files will be compiled, but will not be run under
@ -72,7 +75,7 @@ fn test_all() {
exe_filename := '$wrkdir/x'
full_path_to_source_file := os.join_path(vroot, test)
compile_cmd := '$vexe -o $exe_filename -cg -cflags "-w" -autofree "$full_path_to_source_file"'
vprintln('compile cmd: ${util.bold(compile_cmd)}')
vprintln('compile cmd: ${bold(compile_cmd)}')
res := os.execute(compile_cmd)
if res.exit_code != 0 {
bench.fail()
@ -89,11 +92,11 @@ fn test_all() {
}
}
valgrind_cmd := 'valgrind --error-exitcode=1 --leak-check=full $exe_filename'
vprintln('valgrind cmd: ${util.bold(valgrind_cmd)}')
vprintln('valgrind cmd: ${bold(valgrind_cmd)}')
valgrind_res := os.execute(valgrind_cmd)
if valgrind_res.exit_code != 0 {
bench.fail()
eprintln(bench.step_message_fail('failed valgrind check for ${util.bold(test)}'))
eprintln(bench.step_message_fail('failed valgrind check for ${bold(test)}'))
eprintln(valgrind_res.output)
eprintln('You can reproduce the failure with:\n$compile_cmd && $valgrind_cmd')
continue

View File

@ -5,15 +5,10 @@ module util
import os
import time
import term
import v.pref
import v.vmod
import v.util.recompilation
pub const (
v_version = '0.2.2'
)
// math.bits is needed by strconv.ftoa
pub const (
builtin_module_parts = ['math.bits', 'strconv', 'strconv.ftoa', 'strings', 'builtin']
@ -45,86 +40,6 @@ pub fn tabs(n int) string {
return if n < util.const_tabs.len { util.const_tabs[n] } else { '\t'.repeat(n) }
}
// vhash() returns the build string C.V_COMMIT_HASH . See cmd/tools/gen_vc.v .
pub fn vhash() string {
mut buf := [50]byte{}
buf[0] = 0
unsafe {
bp := &buf[0]
C.snprintf(&char(bp), 50, c'%s', C.V_COMMIT_HASH)
return tos_clone(bp)
}
}
pub fn full_hash() string {
build_hash := vhash()
current_hash := githash(false)
if build_hash == current_hash {
return build_hash
}
return '${build_hash}.$current_hash'
}
// full_v_version() returns the full version of the V compiler
pub fn full_v_version(is_verbose bool) string {
if is_verbose {
return 'V $util.v_version $full_hash()'
}
hash := githash(false)
return 'V $util.v_version $hash'
}
// githash(x) returns the current git commit hash.
// When x is false, it is very fast - it just returns a predefined C constant.
// When x is true, it tries to get the current commit hash, by parsing the
// relevant files in the .git/ folder, or if that is not possible
// for example when using a V from a V binary release, that does not have .git/
// defaults to getting the predefined C constant again.
// NB: githash(true) must be called only when v detects that it builds itself.
// For all other programs, githash(false) should be used.
pub fn githash(should_get_from_filesystem bool) string {
for {
// The `for` construct here is used as a goto substitute.
// The code in this function will break out of the `for`
// if it detects an error and can not continue.
if should_get_from_filesystem {
vexe := os.getenv('VEXE')
vroot := os.dir(vexe)
// .git/HEAD
git_head_file := os.join_path(vroot, '.git', 'HEAD')
if !os.exists(git_head_file) {
break
}
// 'ref: refs/heads/master' ... the current branch name
head_content := os.read_file(git_head_file) or { break }
mut current_branch_hash := head_content
if head_content.starts_with('ref: ') {
gcbranch_rel_path := head_content.replace('ref: ', '').trim_space()
gcbranch_file := os.join_path(vroot, '.git', gcbranch_rel_path)
// .git/refs/heads/master
if !os.exists(gcbranch_file) {
break
}
// get the full commit hash contained in the ref heads file
branch_hash := os.read_file(gcbranch_file) or { break }
current_branch_hash = branch_hash
}
desired_hash_length := 7
if current_branch_hash.len > desired_hash_length {
return current_branch_hash[0..desired_hash_length]
}
}
break
}
mut buf := [50]byte{}
buf[0] = 0
unsafe {
bp := &buf[0]
C.snprintf(&char(bp), 50, c'%s', C.V_CURRENT_COMMIT_HASH)
return tos_clone(bp)
}
}
//
pub fn set_vroot_folder(vroot_path string) {
// Preparation for the compiler module:
@ -235,7 +150,7 @@ pub fn launch_tool(is_verbose bool, tool_name string, args []string) {
for emodule in emodules {
check_module_is_installed(emodule, is_verbose) or { panic(err) }
}
mut compilation_command := '"$vexe" '
mut compilation_command := '"$vexe" -skip-unused '
if tool_name in ['vself', 'vup', 'vdoctor', 'vsymlink'] {
// These tools will be called by users in cases where there
// is high chance of there being a problem somewhere. Thus
@ -570,9 +485,3 @@ pub fn find_all_v_files(roots []string) ?[]string {
}
return files
}
// Highlight a command with an on-brand background to make CLI
// commands immediately recognizable.
pub fn pretty_print(command string) string {
return term.bright_white(term.bg_cyan(' $command '))
}

View File

@ -0,0 +1,85 @@
module version
import os
pub const v_version = '0.2.2'
// vhash() returns the build string C.V_COMMIT_HASH . See cmd/tools/gen_vc.v .
pub fn vhash() string {
mut buf := [50]byte{}
buf[0] = 0
unsafe {
bp := &buf[0]
C.snprintf(&char(bp), 50, c'%s', C.V_COMMIT_HASH)
return tos_clone(bp)
}
}
pub fn full_hash() string {
build_hash := vhash()
current_hash := githash(false)
if build_hash == current_hash {
return build_hash
}
return '${build_hash}.$current_hash'
}
// full_v_version() returns the full version of the V compiler
pub fn full_v_version(is_verbose bool) string {
if is_verbose {
return 'V $version.v_version $full_hash()'
}
hash := githash(false)
return 'V $version.v_version $hash'
}
// githash(x) returns the current git commit hash.
// When x is false, it is very fast - it just returns a predefined C constant.
// When x is true, it tries to get the current commit hash, by parsing the
// relevant files in the .git/ folder, or if that is not possible
// for example when using a V from a V binary release, that does not have .git/
// defaults to getting the predefined C constant again.
// NB: githash(true) must be called only when v detects that it builds itself.
// For all other programs, githash(false) should be used.
pub fn githash(should_get_from_filesystem bool) string {
for {
// The `for` construct here is used as a goto substitute.
// The code in this function will break out of the `for`
// if it detects an error and can not continue.
if should_get_from_filesystem {
vexe := os.getenv('VEXE')
vroot := os.dir(vexe)
// .git/HEAD
git_head_file := os.join_path(vroot, '.git', 'HEAD')
if !os.exists(git_head_file) {
break
}
// 'ref: refs/heads/master' ... the current branch name
head_content := os.read_file(git_head_file) or { break }
mut current_branch_hash := head_content
if head_content.starts_with('ref: ') {
gcbranch_rel_path := head_content.replace('ref: ', '').trim_space()
gcbranch_file := os.join_path(vroot, '.git', gcbranch_rel_path)
// .git/refs/heads/master
if !os.exists(gcbranch_file) {
break
}
// get the full commit hash contained in the ref heads file
branch_hash := os.read_file(gcbranch_file) or { break }
current_branch_hash = branch_hash
}
desired_hash_length := 7
if current_branch_hash.len > desired_hash_length {
return current_branch_hash[0..desired_hash_length]
}
}
break
}
mut buf := [50]byte{}
buf[0] = 0
unsafe {
bp := &buf[0]
C.snprintf(&char(bp), 50, c'%s', C.V_CURRENT_COMMIT_HASH)
return tos_clone(bp)
}
}