v / cmd / tools
Raw file | 169 loc (156 sloc) | 4.94 KB | Latest commit hash 017ace6ea
1import net.urllib
2import os
3import readline
4
5const vroot = @VMODROOT
6
7// get output from `v doctor`
8fn get_vdoctor_output(is_verbose bool) string {
9 vexe := os.getenv('VEXE')
10 verbose_flag := if is_verbose { '-v' } else { '' }
11 result := os.execute('${os.quoted_path(vexe)} ${verbose_flag} doctor')
12 if result.exit_code != 0 {
13 eprintln('unable to get `v doctor` output: ${result.output}')
14 return ''
15 }
16 return result.output
17}
18
19// get ouput from `v -g -o vdbg cmd/v && vdbg file.v`
20fn get_v_build_output(is_verbose bool, is_yes bool, file_path string) string {
21 mut vexe := os.getenv('VEXE')
22 // prepare a V compiler with -g to have better backtraces if possible
23 wd := os.getwd()
24 os.chdir(vroot) or {}
25 verbose_flag := if is_verbose { '-v' } else { '' }
26 vdbg_path := $if windows { '${vroot}/vdbg.exe' } $else { '${vroot}/vdbg' }
27 vdbg_compilation_cmd := '${os.quoted_path(vexe)} ${verbose_flag} -g -o ${os.quoted_path(vdbg_path)} cmd/v'
28 vdbg_result := os.execute(vdbg_compilation_cmd)
29 os.chdir(wd) or {}
30 if vdbg_result.exit_code == 0 {
31 vexe = vdbg_path
32 } else {
33 eprintln('unable to compile V in debug mode: ${vdbg_result.output}\ncommand: ${vdbg_compilation_cmd}\n')
34 }
35 //
36 mut result := os.execute('${os.quoted_path(vexe)} ${verbose_flag} ${os.quoted_path(file_path)}')
37 defer {
38 os.rm(vdbg_path) or {
39 if is_verbose {
40 eprintln('unable to delete `vdbg`: ${err}')
41 }
42 }
43 }
44 if result.exit_code == 0 {
45 defer {
46 mut generated_file := file_path.all_before_last('.')
47 $if windows {
48 generated_file += '.exe'
49 }
50 os.rm(generated_file) or {
51 if is_verbose {
52 eprintln('unable to delete generated file: ${err}')
53 }
54 }
55 }
56 run := is_yes
57 || ask('It looks like the compilation went well, do you want to run the file?')
58 if run {
59 result = os.execute('${os.quoted_path(vexe)} ${verbose_flag} run ${os.quoted_path(file_path)}')
60 if result.exit_code == 0 && !is_yes {
61 confirm_or_exit('It looks like the file ran correctly as well, are you sure you want to continue?')
62 }
63 }
64 }
65 return result.output
66}
67
68fn ask(msg string) bool {
69 prompt := os.input_opt('${msg} [Y/n] ') or { 'y' }
70 return prompt == '' || prompt[0].ascii_str().to_lower() != 'n'
71}
72
73fn confirm_or_exit(msg string) {
74 if !ask(msg) {
75 exit(1)
76 }
77}
78
79fn main() {
80 mut file_path := ''
81 mut is_verbose := false
82 mut is_yes := false
83 for arg in os.args[2..] {
84 match arg {
85 '-v' {
86 is_verbose = true
87 }
88 '-y' {
89 is_yes = true
90 }
91 else {
92 if !arg.ends_with('.v') && !arg.ends_with('.vsh') && !arg.ends_with('.vv') {
93 eprintln('unknown argument: `${arg}`')
94 exit(1)
95 }
96 if file_path != '' {
97 eprintln('only one V file can be submitted')
98 exit(1)
99 }
100 file_path = arg
101 }
102 }
103 }
104 if file_path == '' {
105 eprintln('v bug: no v file listed to report')
106 exit(1)
107 }
108 os.unsetenv('VCOLORS')
109 // collect error information
110 // output from `v doctor`
111 vdoctor_output := get_vdoctor_output(is_verbose)
112 // file content
113 file_content := os.read_file(file_path) or {
114 eprintln('unable to get file "${file_path}" content: ${err}')
115 ''
116 }
117 // output from `v -g -o vdbg cmd/v && vdbg file.v`
118 build_output := get_v_build_output(is_verbose, is_yes, file_path)
119 // ask the user if he wants to submit even after an error
120 if !is_yes && (vdoctor_output == '' || file_content == '' || build_output == '') {
121 confirm_or_exit('An error occurred retrieving the information, do you want to continue?')
122 }
123
124 expected_result := readline.read_line('What did you expect to see? ') or {
125 // Ctrl-C was pressed
126 eprintln('\nCanceled')
127 exit(1)
128 }
129 // open prefilled issue creation page, or print link as a fallback
130
131 if !is_yes && vdoctor_output.contains('behind V master') {
132 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?')
133 }
134
135 // When updating this template, make sure to update `.github/ISSUE_TEMPLATE/bug_report.md` too
136 raw_body := '<!-- It is advisable to update all relevant modules using `v outdated` and `v install` -->
137**V doctor:**
138```
139${vdoctor_output}
140```
141
142**What did you do?**
143`v -g -o vdbg cmd/v && vdbg ${file_path}`
144{file_content}
145
146**What did you expect to see?**
147
148${expected_result}
149
150**What did you see instead?**
151```
152${build_output}```'
153 mut encoded_body := urllib.query_escape(raw_body.replace_once('{file_content}', '```v\n${file_content}\n```'))
154 mut generated_uri := 'https://github.com/vlang/v/issues/new?labels=Bug&body=${encoded_body}'
155 if generated_uri.len > 8192 {
156 // GitHub doesn't support URLs longer than 8192 characters
157 encoded_body = urllib.query_escape(raw_body.replace_once('{file_content}', 'See attached file `${file_path}`'))
158 generated_uri = 'https://github.com/vlang/v/issues/new?labels=Bug&body=${encoded_body}'
159 println('Your file is too big to be submitted. Head over to the following URL and attach your file.')
160 println(generated_uri)
161 } else {
162 os.open_uri(generated_uri) or {
163 if is_verbose {
164 eprintln(err)
165 }
166 println(generated_uri)
167 }
168 }
169}