mirror of
https://github.com/vlang/v.git
synced 2025-09-11 08:25:42 -04:00
tools: allow for passing arbitrary compiler flags to v bug
, for example: v bug -cg -autofree file.v
(#23335)
This commit is contained in:
parent
a366582010
commit
7cf77fbda0
132
cmd/tools/vbug.v
132
cmd/tools/vbug.v
@ -1,8 +1,15 @@
|
|||||||
import net.urllib
|
|
||||||
import os
|
import os
|
||||||
|
import term
|
||||||
import readline
|
import readline
|
||||||
|
import net.urllib
|
||||||
|
|
||||||
const vroot = @VMODROOT
|
fn elog(msg string) {
|
||||||
|
eprintln(term.ecolorize(term.gray, msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn olog(msg string) {
|
||||||
|
println(term.colorize(term.green, msg))
|
||||||
|
}
|
||||||
|
|
||||||
// get output from `v doctor`
|
// get output from `v doctor`
|
||||||
fn get_vdoctor_output(is_verbose bool) string {
|
fn get_vdoctor_output(is_verbose bool) string {
|
||||||
@ -10,55 +17,64 @@ fn get_vdoctor_output(is_verbose bool) string {
|
|||||||
verbose_flag := if is_verbose { '-v' } else { '' }
|
verbose_flag := if is_verbose { '-v' } else { '' }
|
||||||
result := os.execute('${os.quoted_path(vexe)} ${verbose_flag} doctor')
|
result := os.execute('${os.quoted_path(vexe)} ${verbose_flag} doctor')
|
||||||
if result.exit_code != 0 {
|
if result.exit_code != 0 {
|
||||||
eprintln('unable to get `v doctor` output: ${result.output}')
|
elog('> unable to get `v doctor` output: ${result.output}')
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
return result.output
|
return result.output
|
||||||
}
|
}
|
||||||
|
|
||||||
// get output from `./v -g -o vdbg cmd/v && ./vdbg file.v`
|
fn runv(label string, user_cmd string) os.Result {
|
||||||
fn get_v_build_output(is_verbose bool, is_yes bool, file_path string) string {
|
mut result := os.Result{}
|
||||||
|
elog('> ${label} using: ${term.ecolorize(term.magenta, user_cmd)}')
|
||||||
|
result = os.execute(user_cmd)
|
||||||
|
print(result.output)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// get output from `./v -g -o vdbg cmd/v && ./vdbg -user_args run file.v`
|
||||||
|
fn get_v_build_output(is_verbose bool, is_yes bool, file_path string, user_args string, generated_file string) string {
|
||||||
|
mut result := os.Result{}
|
||||||
mut vexe := os.getenv('VEXE')
|
mut vexe := os.getenv('VEXE')
|
||||||
|
|
||||||
// prepare a V compiler with -g to have better backtraces if possible
|
// prepare a V compiler with -g to have better backtraces if possible
|
||||||
wd := os.getwd()
|
wd := os.getwd()
|
||||||
|
vroot := @VMODROOT
|
||||||
os.chdir(vroot) or {}
|
os.chdir(vroot) or {}
|
||||||
verbose_flag := if is_verbose { '-v' } else { '' }
|
verbose_flag := if is_verbose { '-v' } else { '' }
|
||||||
vdbg_path := $if windows { '${vroot}/vdbg.exe' } $else { '${vroot}/vdbg' }
|
vdbg_path := $if windows { '${vroot}/vdbg.exe' } $else { '${vroot}/vdbg' }
|
||||||
vdbg_compilation_cmd := '${os.quoted_path(vexe)} ${verbose_flag} -g -o ${os.quoted_path(vdbg_path)} cmd/v'
|
vdbg_compilation_cmd := '${os.quoted_path(vexe)} ${verbose_flag} -g -o ${os.quoted_path(vdbg_path)} cmd/v'
|
||||||
vdbg_result := os.execute(vdbg_compilation_cmd)
|
result = runv('Prepare vdbg', vdbg_compilation_cmd)
|
||||||
os.chdir(wd) or {}
|
os.chdir(wd) or {}
|
||||||
if vdbg_result.exit_code == 0 {
|
|
||||||
|
if result.exit_code == 0 {
|
||||||
vexe = vdbg_path
|
vexe = vdbg_path
|
||||||
} else {
|
} else {
|
||||||
eprintln('unable to compile V in debug mode: ${vdbg_result.output}\ncommand: ${vdbg_compilation_cmd}\n')
|
elog('> unable to compile V in debug mode: ${result.output}\ncommand: ${vdbg_compilation_cmd}\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
mut result := os.execute('${os.quoted_path(vexe)} ${verbose_flag} ${os.quoted_path(file_path)}')
|
result = runv('Compile', '${os.quoted_path(vexe)} ${verbose_flag} ${user_args} ${os.quoted_path(file_path)}')
|
||||||
defer {
|
defer {
|
||||||
os.rm(vdbg_path) or {
|
os.rm(vdbg_path) or {
|
||||||
if is_verbose {
|
if is_verbose {
|
||||||
eprintln('unable to delete `vdbg`: ${err}')
|
elog('> unable to delete `vdbg`: ${err}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if result.exit_code == 0 {
|
if result.exit_code == 0 {
|
||||||
defer {
|
defer {
|
||||||
mut generated_file := file_path.all_before_last('.')
|
|
||||||
$if windows {
|
|
||||||
generated_file += '.exe'
|
|
||||||
}
|
|
||||||
os.rm(generated_file) or {
|
os.rm(generated_file) or {
|
||||||
if is_verbose {
|
if is_verbose {
|
||||||
eprintln('unable to delete generated file: ${err}')
|
elog('> unable to delete generated file: ${err}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run := is_yes
|
run := is_yes
|
||||||
|| ask('It looks like the compilation went well, do you want to run the file?')
|
|| ask('It looks like the compilation went well, do you want to run the file?')
|
||||||
if run {
|
if run {
|
||||||
result = os.execute('${os.quoted_path(vexe)} ${verbose_flag} run ${os.quoted_path(file_path)}')
|
result = runv('Run', generated_file)
|
||||||
if result.exit_code == 0 && !is_yes {
|
if result.exit_code == 0 && !is_yes {
|
||||||
confirm_or_exit('It looks like the file ran correctly as well, are you sure you want to continue?')
|
elog('> The file ran correctly as well.')
|
||||||
|
confirm_or_exit('Are you sure you want to continue?')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,7 +82,7 @@ fn get_v_build_output(is_verbose bool, is_yes bool, file_path string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ask(msg string) bool {
|
fn ask(msg string) bool {
|
||||||
prompt := os.input_opt('${msg} [Y/n] ') or { 'y' }
|
prompt := os.input_opt(term.colorize(term.bright_white, '${msg} [Y/n] ')) or { 'y' }
|
||||||
return prompt == '' || prompt[0].ascii_str().to_lower() != 'n'
|
return prompt == '' || prompt[0].ascii_str().to_lower() != 'n'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,59 +93,68 @@ fn confirm_or_exit(msg string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
unbuffer_stdout()
|
||||||
|
mut compiler_args := []string{}
|
||||||
mut file_path := ''
|
mut file_path := ''
|
||||||
mut is_verbose := false
|
is_verbose := '-v' in os.args
|
||||||
mut is_yes := false
|
is_yes := '-y' in os.args
|
||||||
for arg in os.args[2..] {
|
|
||||||
match arg {
|
for arg in os.args[1..] {
|
||||||
'-v' {
|
if arg == 'bug' {
|
||||||
is_verbose = true
|
continue
|
||||||
|
}
|
||||||
|
if arg.ends_with('.v') || arg.ends_with('.vsh') || arg.ends_with('.vv') {
|
||||||
|
if file_path != '' {
|
||||||
|
elog('> v bug: only one V file can be submitted')
|
||||||
|
exit(1)
|
||||||
}
|
}
|
||||||
'-y' {
|
file_path = arg
|
||||||
is_yes = true
|
} else {
|
||||||
}
|
if arg !in ['-y', '-v'] {
|
||||||
else {
|
compiler_args << arg
|
||||||
if !arg.ends_with('.v') && !arg.ends_with('.vsh') && !arg.ends_with('.vv') {
|
|
||||||
eprintln('unknown argument: `${arg}`')
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
if file_path != '' {
|
|
||||||
eprintln('only one V file can be submitted')
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
file_path = arg
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if file_path == '' {
|
if file_path == '' {
|
||||||
eprintln('v bug: no v file listed to report')
|
elog('> v bug: no v file listed to report')
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
os.unsetenv('VCOLORS')
|
os.unsetenv('VCOLORS')
|
||||||
// collect error information
|
// collect error information
|
||||||
// output from `v doctor`
|
// output from `v doctor`
|
||||||
vdoctor_output := get_vdoctor_output(is_verbose)
|
vdoctor_output := get_vdoctor_output(is_verbose)
|
||||||
// file content
|
// file content
|
||||||
file_content := os.read_file(file_path) or {
|
file_content := os.read_file(file_path) or {
|
||||||
eprintln('unable to get file "${file_path}" content: ${err}')
|
elog('> unable to get file "${file_path}" content: ${err}')
|
||||||
''
|
''
|
||||||
}
|
}
|
||||||
// output from `./v -g -o vdbg cmd/v && ./vdbg file.v`
|
|
||||||
build_output := get_v_build_output(is_verbose, is_yes, file_path)
|
user_args := compiler_args.join(' ')
|
||||||
|
mut generated_file := file_path.all_before_last('.')
|
||||||
|
if os.user_os() == 'windows' {
|
||||||
|
generated_file += '.exe'
|
||||||
|
}
|
||||||
|
build_output := get_v_build_output(is_verbose, is_yes, file_path, user_args, generated_file)
|
||||||
|
|
||||||
// ask the user if he wants to submit even after an error
|
// ask the user if he wants to submit even after an error
|
||||||
if !is_yes && (vdoctor_output == '' || file_content == '' || build_output == '') {
|
if !is_yes && (vdoctor_output == '' || file_content == '' || build_output == '') {
|
||||||
confirm_or_exit('An error occurred retrieving the information, do you want to continue?')
|
elog('> Error while retrieving the information.')
|
||||||
|
confirm_or_exit('Do you want to continue?')
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_result := readline.read_line('What did you expect to see? ') or {
|
expected_result := readline.read_line('What did you expect to see? ') or {
|
||||||
// Ctrl-C was pressed
|
// Ctrl-C was pressed
|
||||||
eprintln('\nCanceled')
|
elog('\nCanceled')
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
// open prefilled issue creation page, or print link as a fallback
|
// open prefilled issue creation page, or print link as a fallback
|
||||||
|
|
||||||
if !is_yes && vdoctor_output.contains('behind V master') {
|
if !is_yes && vdoctor_output.contains('behind V master') {
|
||||||
confirm_or_exit('It looks like your installation of V is outdated, we advise you to run `v up` before submitting an issue. Are you sure you want to continue?')
|
olog('> It looks like your installation of V is outdated.')
|
||||||
|
olog('> We advise you to run `v up` before submitting an issue.')
|
||||||
|
confirm_or_exit('Are you sure you want to continue?')
|
||||||
}
|
}
|
||||||
|
|
||||||
// When updating this template, make sure to update `.github/ISSUE_TEMPLATE/bug_report.md` too
|
// When updating this template, make sure to update `.github/ISSUE_TEMPLATE/bug_report.md` too
|
||||||
@ -140,30 +165,33 @@ ${vdoctor_output}
|
|||||||
```
|
```
|
||||||
|
|
||||||
**What did you do?**
|
**What did you do?**
|
||||||
`./v -g -o vdbg cmd/v && ./vdbg ${file_path}`
|
`./v -g -o vdbg cmd/v && ./vdbg ${user_args} ${file_path} && ${generated_file}`
|
||||||
{file_content}
|
{file_content}
|
||||||
|
|
||||||
|
**What did you see instead?**
|
||||||
|
```
|
||||||
|
${build_output}```
|
||||||
|
|
||||||
**What did you expect to see?**
|
**What did you expect to see?**
|
||||||
|
|
||||||
${expected_result}
|
${expected_result}
|
||||||
|
|
||||||
**What did you see instead?**
|
'
|
||||||
```
|
|
||||||
${build_output}```'
|
|
||||||
mut encoded_body := urllib.query_escape(raw_body.replace_once('{file_content}', '```v\n${file_content}\n```'))
|
mut encoded_body := urllib.query_escape(raw_body.replace_once('{file_content}', '```v\n${file_content}\n```'))
|
||||||
mut generated_uri := 'https://github.com/vlang/v/issues/new?labels=Bug&body=${encoded_body}'
|
mut generated_uri := 'https://github.com/vlang/v/issues/new?labels=Bug&body=${encoded_body}'
|
||||||
if generated_uri.len > 8192 {
|
if generated_uri.len > 8192 {
|
||||||
// GitHub doesn't support URLs longer than 8192 characters
|
// GitHub doesn't support URLs longer than 8192 characters
|
||||||
encoded_body = urllib.query_escape(raw_body.replace_once('{file_content}', 'See attached file `${file_path}`'))
|
encoded_body = urllib.query_escape(raw_body.replace_once('{file_content}', 'See attached file `${file_path}`'))
|
||||||
generated_uri = 'https://github.com/vlang/v/issues/new?labels=Bug&body=${encoded_body}'
|
generated_uri = 'https://github.com/vlang/v/issues/new?labels=Bug&body=${encoded_body}'
|
||||||
println('Your file is too big to be submitted. Head over to the following URL and attach your file.')
|
elog('> Your file is too big to be submitted.')
|
||||||
println(generated_uri)
|
elog('> Go to the following URL, and attach your file:')
|
||||||
|
olog(generated_uri)
|
||||||
} else {
|
} else {
|
||||||
os.open_uri(generated_uri) or {
|
os.open_uri(generated_uri) or {
|
||||||
if is_verbose {
|
if is_verbose {
|
||||||
eprintln(err)
|
elog(err.str())
|
||||||
}
|
}
|
||||||
println(generated_uri)
|
olog(generated_uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user