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