113 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			V
		
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			V
		
	
	
| import os
 | |
| import flag
 | |
| import scripting
 | |
| import vgit
 | |
| 
 | |
| const (
 | |
| 	tool_version = '0.0.3'
 | |
| 	tool_description = '  Checkout an old V and compile it as it was on specific commit.
 | |
|      This tool is useful, when you want to discover when something broke.
 | |
|      It is also useful, when you just want to experiment with an older historic V.
 | |
| 
 | |
|      The VCOMMIT argument can be a git commitish like HEAD or master and so on.
 | |
|      When oldv is used with git bisect, you probably want to give HEAD. For example:
 | |
|           git bisect start
 | |
|           git bisect bad
 | |
|           git checkout known_good_commit
 | |
|           git bisect 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"
 | |
|               ## See what the result is, and either do: ...
 | |
|           git bisect good
 | |
|               ## ... or do:
 | |
|           git bisect bad
 | |
|               ## Now you just repeat the above steps, each time running oldv with the same command, then mark the result as good or bad,
 | |
|               ## until you find the commit, where the problem first occurred.
 | |
|               ## When you finish, do not forget to do:
 | |
|           git bisect reset'
 | |
| )
 | |
| 
 | |
| struct Context {
 | |
| mut:
 | |
| 	vgo           vgit.VGitOptions
 | |
| 	commit_v      string='master' // the commit from which you want to produce a working v compiler (this may be a commit-ish too)
 | |
| 	commit_vc     string='master' // this will be derived from commit_v
 | |
| 	commit_v_hash string // this will be filled from the commit-ish commit_v using rev-list. It IS a commit hash.
 | |
| 	path_v        string // the full path to the v folder inside workdir.
 | |
| 	path_vc       string // the full path to the vc folder inside workdir.
 | |
| 	cmd_to_run    string // the command that you want to run *in* the oldv repo
 | |
| 	cc            string='cc' // the C compiler to use for bootstrapping.
 | |
| 	cleanup       bool // should the tool run a cleanup first
 | |
| }
 | |
| 
 | |
| fn (mut c Context) compile_oldv_if_needed() {
 | |
| 	mut vgit_context := vgit.VGitContext{
 | |
| 		workdir:     c.vgo.workdir
 | |
| 		v_repo_url:  c.vgo.v_repo_url
 | |
| 		vc_repo_url: c.vgo.vc_repo_url
 | |
| 		cc:          c.cc
 | |
| 		commit_v:    c.commit_v
 | |
| 		path_v:      c.path_v
 | |
| 		path_vc:     c.path_vc
 | |
| 	}
 | |
| 	vgit_context.compile_oldv_if_needed()
 | |
| 	c.commit_v_hash = vgit_context.commit_v__hash
 | |
| 	if !os.exists(vgit_context.vexepath) && c.cmd_to_run.len > 0 {
 | |
| 		// NB: 125 is a special code, that git bisect understands as 'skip this commit'.
 | |
| 		// it is used to inform git bisect that the current commit leads to a build failure.
 | |
| 		exit(125)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| fn main() {
 | |
| 	scripting.used_tools_must_exist(['git', 'cc'])
 | |
| 	mut context := Context{}
 | |
| 	mut fp := flag.new_flag_parser(os.args)
 | |
| 	fp.application(os.file_name(os.executable()))
 | |
| 	fp.version(tool_version)
 | |
| 	fp.description(tool_description)
 | |
| 	fp.arguments_description('VCOMMIT')
 | |
| 	fp.skip_executable()
 | |
| 	fp.limit_free_args(1, 1)
 | |
| 
 | |
| 	context.cleanup = fp.bool('clean', 0, true, 'Clean before running (slower).')
 | |
| 	context.cmd_to_run = fp.string('command', `c`, '', 'Command to run in the old V repo.\n')
 | |
| 
 | |
| 	commits := vgit.add_common_tool_options(mut context.vgo, mut fp)
 | |
| 	if commits.len > 0 {
 | |
| 		context.commit_v = commits[0]
 | |
| 	} else {
 | |
| 		context.commit_v = scripting.run('git rev-list -n1 HEAD')
 | |
| 	}
 | |
| 	println('#################  context.commit_v: $context.commit_v #####################')
 | |
| 	context.path_v = vgit.normalized_workpath_for_commit(context.vgo.workdir, context.commit_v)
 | |
| 	context.path_vc = vgit.normalized_workpath_for_commit(context.vgo.workdir, 'vc')
 | |
| 	if !os.is_dir(context.vgo.workdir) {
 | |
| 		eprintln('Work folder: ${context.vgo.workdir} , does not exist.')
 | |
| 		exit(2)
 | |
| 	}
 | |
| 	ecc := os.getenv('CC')
 | |
| 	if ecc != '' {
 | |
| 		context.cc = ecc
 | |
| 	}
 | |
| 	if context.cleanup {
 | |
| 		scripting.rmrf(context.path_v)
 | |
| 		scripting.rmrf(context.path_vc)
 | |
| 	}
 | |
| 
 | |
| 	context.compile_oldv_if_needed()
 | |
| 
 | |
| 	scripting.chdir(context.path_v)
 | |
| 	println('#     v commit hash: $context.commit_v_hash')
 | |
| 	println('#   checkout folder: $context.path_v')
 | |
| 	if context.cmd_to_run.len > 0 {
 | |
| 		cmdres := os.exec(context.cmd_to_run) or {
 | |
| 			panic(err)
 | |
| 		}
 | |
| 		println('#           command: ${context.cmd_to_run:-34s} exit code: ${cmdres.exit_code:-4d}  result:')
 | |
| 		println(cmdres.output)
 | |
| 		exit(cmdres.exit_code)
 | |
| 	}
 | |
| 
 | |
| }
 |