80 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			V
		
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			V
		
	
	
| 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)
 | |
| }
 |