tools: add cmd/tools/regress.v to simplify bisecting for regression bugs/features:
Support finding which commit introduced a regression: ./v run cmd/tools/regress.v --old COMMIT --command './v run /abs/path/to/regression_bug.v' Support also finding which commit introduced a feature (or made code compile/run): ./v run cmd/tools/regress.v --old COMMIT --command '! ./v run /abs/path/to/feature.v' NB: the '! ' is a POSIX shell feature. It may not work on Windows outside of WSL. Its meaning is to invert the exit code for the next command, i.e. 0 -> 1, non 0 -> 0 If it does not work for you, you need to write a more explicit script that will exit with 0 code for all commits, where the feature does NOT work, and with non 0 code for all commits, where the feature does work.pull/13498/head
parent
d739abbb3f
commit
eb45a321a5
|
@ -16,7 +16,7 @@ const (
|
||||||
| git checkout known_good_commit
|
| git checkout known_good_commit
|
||||||
| git bisect good
|
| git bisect good
|
||||||
| ## Now git will automatically checkout a middle commit between the bad and the good
|
| ## Now git will automatically checkout a middle commit between the bad and the good
|
||||||
| cmd/tools/oldv HEAD --command="run commands in oldv folder, to verify if the commit is good or bad"
|
| cmd/tools/oldv --bisect --command="run commands in oldv folder, to verify if the commit is good or bad"
|
||||||
| ## See what the result is, and either do: ...
|
| ## See what the result is, and either do: ...
|
||||||
| git bisect good
|
| git bisect good
|
||||||
| ## ... or do:
|
| ## ... or do:
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
import os
|
||||||
|
import term
|
||||||
|
import flag
|
||||||
|
|
||||||
|
const tools_folder = os.real_path(os.dir(os.executable()))
|
||||||
|
|
||||||
|
const oldvexe = fullpath(tools_folder, 'oldv')
|
||||||
|
|
||||||
|
const oldv_source = fullpath(tools_folder, 'oldv.v')
|
||||||
|
|
||||||
|
const vroot = os.real_path(os.dir(tools_folder))
|
||||||
|
|
||||||
|
const vexe = fullpath(vroot, 'v')
|
||||||
|
|
||||||
|
fn fullpath(folder string, fname string) string {
|
||||||
|
return os.real_path(os.join_path_single(folder, exename(fname)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exename(n string) string {
|
||||||
|
if n.ends_with('.v') || os.user_os() != 'windows' {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
return '${n}.exe'
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
mut:
|
||||||
|
old_commit string
|
||||||
|
new_commit string
|
||||||
|
command string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
mut fp := flag.new_flag_parser(os.args)
|
||||||
|
mut context := Context{}
|
||||||
|
fp.application(os.file_name(os.executable()))
|
||||||
|
fp.version('0.0.2')
|
||||||
|
fp.description('\n Find at what commit a regression occurred.
|
||||||
|
To find when a regression happened (regression_bug.v should fail on master):
|
||||||
|
./v run cmd/tools/regress.v --old a7019ac --command " ./v run /abs/path/to/regression_bug.v"
|
||||||
|
To find when a feature was implemented (feature.v should succeed on master):
|
||||||
|
./v run cmd/tools/regress.v --old a7019ac --command "! ./v run /abs/path/to/feature.v"')
|
||||||
|
fp.skip_executable()
|
||||||
|
//
|
||||||
|
context.new_commit = fp.string('new', `n`, 'master', 'The new commit, by default: master.')
|
||||||
|
context.old_commit = fp.string('old', `o`, '', 'A known old commit, required (for it, COMMAND should exit with 0).')
|
||||||
|
context.command = fp.string('command', `c`, '', 'A command to execute. Should exit with 0 for the *old* commits.')
|
||||||
|
fp.finalize() or {}
|
||||||
|
if context.old_commit == '' {
|
||||||
|
eprintln('--old COMMIT is required')
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
if context.command == '' {
|
||||||
|
eprintln('--command "COMMAND" is required')
|
||||||
|
exit(2)
|
||||||
|
}
|
||||||
|
if !os.exists(oldvexe) {
|
||||||
|
if 0 != execute('${os.quoted_path(vexe)} -o ${os.quoted_path(oldvexe)} ${os.quoted_path(oldv_source)}') {
|
||||||
|
panic('can not compile $oldvexe')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os.execute('git checkout master')
|
||||||
|
os.execute('git bisect reset')
|
||||||
|
os.execute('git checkout $context.new_commit')
|
||||||
|
os.execute('git bisect start')
|
||||||
|
os.execute('git bisect new')
|
||||||
|
os.execute('git checkout $context.old_commit')
|
||||||
|
os.execute('git bisect old')
|
||||||
|
println(term.colorize(term.bright_yellow, term.header('', '-')))
|
||||||
|
execute('git bisect run ${os.quoted_path(oldvexe)} --bisect -c "$context.command"')
|
||||||
|
println(term.colorize(term.bright_yellow, term.header('', '-')))
|
||||||
|
os.execute('git bisect reset')
|
||||||
|
os.execute('git checkout master')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute(cmd string) int {
|
||||||
|
eprintln('### $cmd')
|
||||||
|
return os.system(cmd)
|
||||||
|
}
|
Loading…
Reference in New Issue