]>
Commit | Line | Data |
---|---|---|
238b439d ES |
1 | #include "builtin.h" |
2 | #include "parse-options.h" | |
3 | #include "stdio.h" | |
4 | #include "strbuf.h" | |
5 | #include "time.h" | |
6 | ||
7 | static const char * const bugreport_usage[] = { | |
8 | N_("git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"), | |
9 | NULL | |
10 | }; | |
11 | ||
12 | static int get_bug_template(struct strbuf *template) | |
13 | { | |
14 | const char template_text[] = N_( | |
15 | "Thank you for filling out a Git bug report!\n" | |
16 | "Please answer the following questions to help us understand your issue.\n" | |
17 | "\n" | |
18 | "What did you do before the bug happened? (Steps to reproduce your issue)\n" | |
19 | "\n" | |
20 | "What did you expect to happen? (Expected behavior)\n" | |
21 | "\n" | |
22 | "What happened instead? (Actual behavior)\n" | |
23 | "\n" | |
24 | "What's different between what you expected and what actually happened?\n" | |
25 | "\n" | |
26 | "Anything else you want to add:\n" | |
27 | "\n" | |
28 | "Please review the rest of the bug report below.\n" | |
29 | "You can delete any lines you don't wish to share.\n"); | |
30 | ||
31 | strbuf_addstr(template, _(template_text)); | |
32 | return 0; | |
33 | } | |
34 | ||
35 | int cmd_main(int argc, const char **argv) | |
36 | { | |
37 | struct strbuf buffer = STRBUF_INIT; | |
38 | struct strbuf report_path = STRBUF_INIT; | |
39 | int report = -1; | |
40 | time_t now = time(NULL); | |
41 | char *option_output = NULL; | |
42 | char *option_suffix = "%Y-%m-%d-%H%M"; | |
43 | int nongit_ok = 0; | |
44 | const char *prefix = NULL; | |
45 | const char *user_relative_path = NULL; | |
46 | ||
47 | const struct option bugreport_options[] = { | |
48 | OPT_STRING('o', "output-directory", &option_output, N_("path"), | |
49 | N_("specify a destination for the bugreport file")), | |
50 | OPT_STRING('s', "suffix", &option_suffix, N_("format"), | |
51 | N_("specify a strftime format suffix for the filename")), | |
52 | OPT_END() | |
53 | }; | |
54 | ||
55 | prefix = setup_git_directory_gently(&nongit_ok); | |
56 | ||
57 | argc = parse_options(argc, argv, prefix, bugreport_options, | |
58 | bugreport_usage, 0); | |
59 | ||
60 | /* Prepare the path to put the result */ | |
61 | strbuf_addstr(&report_path, | |
62 | prefix_filename(prefix, | |
63 | option_output ? option_output : "")); | |
64 | strbuf_complete(&report_path, '/'); | |
65 | ||
66 | strbuf_addstr(&report_path, "git-bugreport-"); | |
67 | strbuf_addftime(&report_path, option_suffix, localtime(&now), 0, 0); | |
68 | strbuf_addstr(&report_path, ".txt"); | |
69 | ||
70 | switch (safe_create_leading_directories(report_path.buf)) { | |
71 | case SCLD_OK: | |
72 | case SCLD_EXISTS: | |
73 | break; | |
74 | default: | |
75 | die(_("could not create leading directories for '%s'"), | |
76 | report_path.buf); | |
77 | } | |
78 | ||
79 | /* Prepare the report contents */ | |
80 | get_bug_template(&buffer); | |
81 | ||
82 | /* fopen doesn't offer us an O_EXCL alternative, except with glibc. */ | |
83 | report = open(report_path.buf, O_CREAT | O_EXCL | O_WRONLY, 0666); | |
84 | ||
85 | if (report < 0) { | |
86 | UNLEAK(report_path); | |
87 | die(_("couldn't create a new file at '%s'"), report_path.buf); | |
88 | } | |
89 | ||
90 | strbuf_write_fd(&buffer, report); | |
91 | close(report); | |
92 | ||
93 | /* | |
94 | * We want to print the path relative to the user, but we still need the | |
95 | * path relative to us to give to the editor. | |
96 | */ | |
97 | if (!(prefix && skip_prefix(report_path.buf, prefix, &user_relative_path))) | |
98 | user_relative_path = report_path.buf; | |
99 | fprintf(stderr, _("Created new report at '%s'.\n"), | |
100 | user_relative_path); | |
101 | ||
102 | UNLEAK(buffer); | |
103 | UNLEAK(report_path); | |
104 | return !!launch_editor(report_path.buf, NULL, NULL); | |
105 | } |