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(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) }