| 1 | module main |
| 2 | |
| 3 | import flag |
| 4 | import json |
| 5 | import net.http |
| 6 | import os |
| 7 | import time |
| 8 | |
| 9 | struct CreateBugReportResponse { |
| 10 | pub: |
| 11 | id string |
| 12 | delete_url string |
| 13 | delete_token string |
| 14 | message string |
| 15 | } |
| 16 | |
| 17 | struct SendConfig { |
| 18 | report_url string |
| 19 | report_file string |
| 20 | } |
| 21 | |
| 22 | fn args_without_command() []string { |
| 23 | args := os.args#[1..] |
| 24 | if args.len > 0 && args[0] == 'bug-report-send' { |
| 25 | return args[1..] |
| 26 | } |
| 27 | return args |
| 28 | } |
| 29 | |
| 30 | fn config_from_args() !SendConfig { |
| 31 | mut fp := flag.new_flag_parser(args_without_command()) |
| 32 | fp.application('v bug-report-send') |
| 33 | fp.version('0.0.1') |
| 34 | fp.description('Send a V compiler bug report JSON payload.') |
| 35 | fp.arguments_description('') |
| 36 | show_help := fp.bool('help', `h`, false, 'Show this help screen.') |
| 37 | report_url := fp.string('url', 0, '', 'Bug report endpoint URL.') |
| 38 | report_file := fp.string('file', `f`, '', 'JSON report file to send.') |
| 39 | if show_help { |
| 40 | println(fp.usage()) |
| 41 | exit(0) |
| 42 | } |
| 43 | remaining := fp.finalize()! |
| 44 | if remaining.len > 0 { |
| 45 | return error('unexpected arguments: ${remaining.join(' ')}') |
| 46 | } |
| 47 | if report_url == '' { |
| 48 | return error('missing required -url') |
| 49 | } |
| 50 | if report_file == '' { |
| 51 | return error('missing required -file') |
| 52 | } |
| 53 | return SendConfig{ |
| 54 | report_url: report_url.trim_space().trim_right('/') |
| 55 | report_file: report_file |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | fn send_bug_report(config SendConfig) !CreateBugReportResponse { |
| 60 | report_json := os.read_file(config.report_file)! |
| 61 | mut header := http.new_header(key: .content_type, value: 'application/json') |
| 62 | header.set(.accept, 'application/json') |
| 63 | response := http.fetch( |
| 64 | method: .post |
| 65 | url: config.report_url |
| 66 | data: report_json |
| 67 | header: header |
| 68 | max_retries: 1 |
| 69 | read_timeout: 3 * time.second |
| 70 | write_timeout: 3 * time.second |
| 71 | )! |
| 72 | if response.status_code < 200 || response.status_code >= 300 { |
| 73 | return error('server responded with HTTP ${response.status_code}') |
| 74 | } |
| 75 | return json.decode(CreateBugReportResponse, response.body)! |
| 76 | } |
| 77 | |
| 78 | fn main() { |
| 79 | config := config_from_args() or { |
| 80 | eprintln('v bug-report-send: ${err}') |
| 81 | exit(1) |
| 82 | } |
| 83 | response := send_bug_report(config) or { |
| 84 | eprintln('v bug-report-send: ${err}') |
| 85 | exit(1) |
| 86 | } |
| 87 | println('Sent C compiler bug report to ${config.report_url}.') |
| 88 | if response.id != '' { |
| 89 | println('Report id: ${response.id}') |
| 90 | } |
| 91 | delete_url := if response.delete_url != '' { |
| 92 | response.delete_url |
| 93 | } else if response.id != '' && response.delete_token != '' { |
| 94 | '${config.report_url}/${response.id}?token=${response.delete_token}' |
| 95 | } else { |
| 96 | '' |
| 97 | } |
| 98 | if delete_url != '' { |
| 99 | println('Delete this report from the server with:') |
| 100 | println(' curl -X DELETE ${os.quoted_path(delete_url)}') |
| 101 | } |
| 102 | } |
| 103 | |