tools: add periodic progress report for `v test-parser`

pull/7342/head
Delyan Angelov 2020-12-15 12:32:02 +02:00
parent d061a52829
commit 3c874891cd
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
1 changed files with 43 additions and 1 deletions

View File

@ -31,10 +31,13 @@ mut:
all_paths []string // all files given to the supervisor process all_paths []string // all files given to the supervisor process
path string // the current path, given to a worker process path string // the current path, given to a worker process
cut_index int // the cut position in the source from context.path cut_index int // the cut position in the source from context.path
max_index int // the maximum index (equivalent to the file content length)
// parser context in the worker processes: // parser context in the worker processes:
table table.Table table table.Table
scope ast.Scope scope ast.Scope
pref pref.Preferences pref pref.Preferences
period_ms int // print periodic progress
stop_print bool // stop printing the periodic progress
} }
fn main() { fn main() {
@ -70,13 +73,18 @@ fn main() {
context.expand_all_paths() context.expand_all_paths()
mut fails := 0 mut fails := 0
mut panics := 0 mut panics := 0
sw := time.new_stopwatch({})
for path in context.all_paths { for path in context.all_paths {
filesw := time.new_stopwatch({})
context.start_printing()
new_fails, new_panics := context.process_whole_file_in_worker(path) new_fails, new_panics := context.process_whole_file_in_worker(path)
fails += new_fails fails += new_fails
panics += new_panics panics += new_panics
context.stop_printing()
context.info('File: ${path:-30} | new_fails: ${new_fails:5} | new_panics: ${new_panics:5} | Elapsed time: ${filesw.elapsed().milliseconds()}ms')
} }
non_panics := fails - panics non_panics := fails - panics
println('Files processed: ${context.all_paths.len:5} | Errors found: ${fails:5} | Panics: ${panics:5} | Non panics: ${non_panics:5}') context.info('Total files processed: ${context.all_paths.len:5} | Errors found: ${fails:5} | Panics: ${panics:5} | Non panics: ${non_panics:5} | Elapsed time: ${sw.elapsed().milliseconds()}ms')
if fails > 0 { if fails > 0 {
exit(1) exit(1)
} }
@ -98,6 +106,7 @@ fn process_cli_args() &Context {
fp.skip_executable() fp.skip_executable()
context.is_help = fp.bool('help', `h`, false, 'Show help/usage screen.') context.is_help = fp.bool('help', `h`, false, 'Show help/usage screen.')
context.is_verbose = fp.bool('verbose', `v`, false, 'Be more verbose.') context.is_verbose = fp.bool('verbose', `v`, false, 'Be more verbose.')
context.period_ms = fp.int('progress_ms', `s`, 500, 'print a status report periodically, the period is given in milliseconds.')
context.is_worker = fp.bool('worker', `w`, false, 'worker specific flag - is this a worker process, that can crash/panic.') context.is_worker = fp.bool('worker', `w`, false, 'worker specific flag - is this a worker process, that can crash/panic.')
context.cut_index = fp.int('cut_index', `c`, 1, 'worker specific flag - cut index in the source file, everything before that will be parsed, the rest - ignored.') context.cut_index = fp.int('cut_index', `c`, 1, 'worker specific flag - cut index in the source file, everything before that will be parsed, the rest - ignored.')
context.timeout_ms = fp.int('timeout_ms', `t`, 250, 'worker specific flag - timeout in ms; a worker taking longer, will self terminate.') context.timeout_ms = fp.int('timeout_ms', `t`, 250, 'worker specific flag - timeout in ms; a worker taking longer, will self terminate.')
@ -140,6 +149,10 @@ fn yellow(msg string) string {
return term.yellow(msg) return term.yellow(msg)
} }
fn (mut context Context) info(msg string) {
println(msg)
}
fn (mut context Context) log(msg string) { fn (mut context Context) log(msg string) {
if context.is_verbose { if context.is_verbose {
label := yellow('info') label := yellow('info')
@ -177,6 +190,7 @@ fn (mut context Context) expand_all_paths() {
} }
fn (mut context Context) process_whole_file_in_worker(path string) (int, int) { fn (mut context Context) process_whole_file_in_worker(path string) (int, int) {
context.path = path // needed for the progress bar
context.log('> context.process_whole_file_in_worker path: $path') context.log('> context.process_whole_file_in_worker path: $path')
if !(os.is_file(path) && os.is_readable(path)) { if !(os.is_file(path) && os.is_readable(path)) {
context.error('$path is not readable') context.error('$path is not readable')
@ -190,8 +204,10 @@ fn (mut context Context) process_whole_file_in_worker(path string) (int, int) {
len := source.len - 1 len := source.len - 1
mut fails := 0 mut fails := 0
mut panics := 0 mut panics := 0
context.max_index = len
for i in 0 .. len { for i in 0 .. len {
verbosity := if context.is_verbose { '-v' } else { '' } verbosity := if context.is_verbose { '-v' } else { '' }
context.cut_index = i // needed for the progress bar
cmd := '"$context.myself" $verbosity --worker --timeout_ms ${context.timeout_ms:5} --cut_index ${i:5} --path "$path" ' cmd := '"$context.myself" $verbosity --worker --timeout_ms ${context.timeout_ms:5} --cut_index ${i:5} --path "$path" '
context.log(cmd) context.log(cmd)
res := os.exec(cmd) or { os.Result{ res := os.exec(cmd) or { os.Result{
@ -221,3 +237,29 @@ fn (mut context Context) process_whole_file_in_worker(path string) (int, int) {
} }
return fails, panics return fails, panics
} }
fn (mut context Context) start_printing() {
context.stop_print = false
println('\n')
go context.print_periodic_status()
}
fn (mut context Context) stop_printing() {
context.stop_print = true
time.sleep_ms(context.period_ms / 5)
}
fn (mut context Context) print_status() {
term.cursor_up(1)
eprint('\r > ${context.path:-30} | index: ${context.cut_index:5}/${context.max_index - 1:5}\n')
}
fn (mut context Context) print_periodic_status() {
for !context.stop_print {
context.print_status()
for i := 0; i < 10 && !context.stop_print; i++ {
time.sleep_ms(context.period_ms / 10)
}
}
context.print_status()
}