You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
781 lines
24 KiB
781 lines
24 KiB
From 914bdfee5da272a99d8dc3f68652534eb132e007 Mon Sep 17 00:00:00 2001 |
|
From: Jakub Filak <jfilak@redhat.com> |
|
Date: Thu, 4 Dec 2014 08:45:07 +0100 |
|
Subject: [PATCH] bugzilla: port to Problem Format API |
|
|
|
Related to #303 |
|
|
|
Signed-off-by: Jakub Filak <jfilak@redhat.com> |
|
--- |
|
src/plugins/reporter-bugzilla.c | 691 ++++------------------------------------ |
|
1 file changed, 59 insertions(+), 632 deletions(-) |
|
|
|
diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c |
|
index 097924e..38f48ef 100644 |
|
--- a/src/plugins/reporter-bugzilla.c |
|
+++ b/src/plugins/reporter-bugzilla.c |
|
@@ -17,515 +17,11 @@ |
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|
*/ |
|
#include "internal_libreport.h" |
|
+#include "problem_report.h" |
|
#include "client.h" |
|
#include "abrt_xmlrpc.h" |
|
#include "rhbz.h" |
|
|
|
-#include <satyr/stacktrace.h> |
|
-#include <satyr/abrt.h> |
|
- |
|
-struct section_t { |
|
- char *name; |
|
- GList *items; |
|
-}; |
|
-typedef struct section_t section_t; |
|
- |
|
- |
|
-/* Utility functions */ |
|
- |
|
-static |
|
-GList* split_string_on_char(const char *str, char ch) |
|
-{ |
|
- GList *list = NULL; |
|
- for (;;) |
|
- { |
|
- const char *delim = strchrnul(str, ch); |
|
- list = g_list_prepend(list, xstrndup(str, delim - str)); |
|
- if (*delim == '\0') |
|
- break; |
|
- str = delim + 1; |
|
- } |
|
- return g_list_reverse(list); |
|
-} |
|
- |
|
-static |
|
-int compare_item_name(const char *lookup, const char *name) |
|
-{ |
|
- if (lookup[0] == '-') |
|
- lookup++; |
|
- else if (strncmp(lookup, "%bare_", 6) == 0) |
|
- lookup += 6; |
|
- return strcmp(lookup, name); |
|
-} |
|
- |
|
-static |
|
-int is_item_name_in_section(const section_t *lookup, const char *name) |
|
-{ |
|
- if (g_list_find_custom(lookup->items, name, (GCompareFunc)compare_item_name)) |
|
- return 0; /* "found it!" */ |
|
- return 1; |
|
-} |
|
- |
|
-static |
|
-bool is_explicit_or_forbidden(const char *name, GList *comment_fmt_spec) |
|
-{ |
|
- return g_list_find_custom(comment_fmt_spec, name, (GCompareFunc)is_item_name_in_section); |
|
-} |
|
- |
|
-static |
|
-GList* load_bzrep_conf_file(const char *path) |
|
-{ |
|
- FILE *fp = stdin; |
|
- if (strcmp(path, "-") != 0) |
|
- { |
|
- fp = fopen(path, "r"); |
|
- if (!fp) |
|
- return NULL; |
|
- } |
|
- |
|
- GList *sections = NULL; |
|
- |
|
- char *line; |
|
- while ((line = xmalloc_fgetline(fp)) != NULL) |
|
- { |
|
- /* Skip comments */ |
|
- char first = *skip_whitespace(line); |
|
- if (first == '#') |
|
- goto free_line; |
|
- |
|
- /* Handle trailing backslash continuation */ |
|
- check_continuation: ; |
|
- unsigned len = strlen(line); |
|
- if (len && line[len-1] == '\\') |
|
- { |
|
- line[len-1] = '\0'; |
|
- char *next_line = xmalloc_fgetline(fp); |
|
- if (next_line) |
|
- { |
|
- line = append_to_malloced_string(line, next_line); |
|
- free(next_line); |
|
- goto check_continuation; |
|
- } |
|
- } |
|
- |
|
- /* We are reusing line buffer to form temporary |
|
- * "key\0values\0..." in its beginning |
|
- */ |
|
- bool summary_line = false; |
|
- char *value = NULL; |
|
- char *src; |
|
- char *dst; |
|
- for (src = dst = line; *src; src++) |
|
- { |
|
- char c = *src; |
|
- /* did we reach the value list? */ |
|
- if (!value && c == ':' && src[1] == ':') |
|
- { |
|
- *dst++ = '\0'; /* terminate key */ |
|
- src += 2; |
|
- value = dst; /* remember where value starts */ |
|
- summary_line = (strcmp(line, "%summary") == 0); |
|
- if (summary_line) |
|
- { |
|
- value = src; |
|
- break; |
|
- } |
|
- continue; |
|
- } |
|
- /* skip whitespace in value list */ |
|
- if (value && isspace(c)) |
|
- continue; |
|
- *dst++ = c; /* store next key or value char */ |
|
- } |
|
- |
|
- GList *item_list = NULL; |
|
- if (summary_line) |
|
- { |
|
- /* %summary is special */ |
|
- item_list = g_list_append(NULL, xstrdup(skip_whitespace(value))); |
|
- } |
|
- else |
|
- { |
|
- *dst = '\0'; /* terminate value (or key) */ |
|
- if (value) |
|
- item_list = split_string_on_char(value, ','); |
|
- } |
|
- |
|
- section_t *sec = xzalloc(sizeof(*sec)); |
|
- sec->name = xstrdup(line); |
|
- sec->items = item_list; |
|
- sections = g_list_prepend(sections, sec); |
|
- |
|
- free_line: |
|
- free(line); |
|
- } |
|
- |
|
- if (fp != stdin) |
|
- fclose(fp); |
|
- |
|
- return g_list_reverse(sections); |
|
-} |
|
- |
|
- |
|
-/* Summary generation */ |
|
- |
|
-#define MAX_OPT_DEPTH 10 |
|
-static |
|
-char *format_percented_string(const char *str, problem_data_t *pd) |
|
-{ |
|
- size_t old_pos[MAX_OPT_DEPTH] = { 0 }; |
|
- int okay[MAX_OPT_DEPTH] = { 1 }; |
|
- int opt_depth = 1; |
|
- struct strbuf *result = strbuf_new(); |
|
- |
|
- while (*str) { |
|
- switch (*str) { |
|
- default: |
|
- strbuf_append_char(result, *str); |
|
- str++; |
|
- break; |
|
- case '\\': |
|
- if (str[1]) |
|
- str++; |
|
- strbuf_append_char(result, *str); |
|
- str++; |
|
- break; |
|
- case '[': |
|
- if (str[1] == '[' && opt_depth < MAX_OPT_DEPTH) |
|
- { |
|
- old_pos[opt_depth] = result->len; |
|
- okay[opt_depth] = 1; |
|
- opt_depth++; |
|
- str += 2; |
|
- } else { |
|
- strbuf_append_char(result, *str); |
|
- str++; |
|
- } |
|
- break; |
|
- case ']': |
|
- if (str[1] == ']' && opt_depth > 1) |
|
- { |
|
- opt_depth--; |
|
- if (!okay[opt_depth]) |
|
- { |
|
- result->len = old_pos[opt_depth]; |
|
- result->buf[result->len] = '\0'; |
|
- } |
|
- str += 2; |
|
- } else { |
|
- strbuf_append_char(result, *str); |
|
- str++; |
|
- } |
|
- break; |
|
- case '%': ; |
|
- char *nextpercent = strchr(++str, '%'); |
|
- if (!nextpercent) |
|
- { |
|
- error_msg_and_die("Unterminated %%element%%: '%s'", str - 1); |
|
- } |
|
- |
|
- *nextpercent = '\0'; |
|
- const problem_item *item = problem_data_get_item_or_NULL(pd, str); |
|
- *nextpercent = '%'; |
|
- |
|
- if (item && (item->flags & CD_FLAG_TXT)) |
|
- strbuf_append_str(result, item->content); |
|
- else |
|
- okay[opt_depth - 1] = 0; |
|
- str = nextpercent + 1; |
|
- break; |
|
- } |
|
- } |
|
- |
|
- if (opt_depth > 1) |
|
- { |
|
- error_msg_and_die("Unbalanced [[ ]] bracket"); |
|
- } |
|
- |
|
- if (!okay[0]) |
|
- { |
|
- error_msg("Undefined variable outside of [[ ]] bracket"); |
|
- } |
|
- |
|
- return strbuf_free_nobuf(result); |
|
-} |
|
- |
|
-static |
|
-char *create_summary_string(problem_data_t *pd, GList *comment_fmt_spec) |
|
-{ |
|
- GList *l = comment_fmt_spec; |
|
- while (l) |
|
- { |
|
- section_t *sec = l->data; |
|
- l = l->next; |
|
- |
|
- /* Find %summary" */ |
|
- if (strcmp(sec->name, "%summary") != 0) |
|
- continue; |
|
- |
|
- GList *item = sec->items; |
|
- if (!item) |
|
- /* not supposed to happen, there will be at least "" */ |
|
- error_msg_and_die("BUG in %%summary parser"); |
|
- |
|
- const char *str = item->data; |
|
- return format_percented_string(str, pd); |
|
- } |
|
- |
|
- return format_percented_string("%reason%", pd); |
|
-} |
|
- |
|
- |
|
-/* BZ comment generation */ |
|
- |
|
-static |
|
-int append_text(struct strbuf *result, const char *item_name, const char *content, bool print_item_name) |
|
-{ |
|
- char *eol = strchrnul(content, '\n'); |
|
- if (eol[0] == '\0' || eol[1] == '\0') |
|
- { |
|
- /* one-liner */ |
|
- int pad = 16 - (strlen(item_name) + 2); |
|
- if (pad < 0) |
|
- pad = 0; |
|
- if (print_item_name) |
|
- strbuf_append_strf(result, |
|
- eol[0] == '\0' ? "%s: %*s%s\n" : "%s: %*s%s", |
|
- item_name, pad, "", content |
|
- ); |
|
- else |
|
- strbuf_append_strf(result, |
|
- eol[0] == '\0' ? "%s\n" : "%s", |
|
- content |
|
- ); |
|
- } |
|
- else |
|
- { |
|
- /* multi-line item */ |
|
- if (print_item_name) |
|
- strbuf_append_strf(result, "%s:\n", item_name); |
|
- for (;;) |
|
- { |
|
- eol = strchrnul(content, '\n'); |
|
- strbuf_append_strf(result, |
|
- /* For %bare_multiline_item, we don't want to print colons */ |
|
- (print_item_name ? ":%.*s\n" : "%.*s\n"), |
|
- (int)(eol - content), content |
|
- ); |
|
- if (eol[0] == '\0' || eol[1] == '\0') |
|
- break; |
|
- content = eol + 1; |
|
- } |
|
- } |
|
- return 1; |
|
-} |
|
- |
|
-static |
|
-int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data, size_t max_text_size, bool print_item_name) |
|
-{ |
|
- const problem_item *item = problem_data_get_item_or_NULL(problem_data, |
|
- FILENAME_BACKTRACE); |
|
- if (!item) |
|
- return 0; /* "I did not print anything" */ |
|
- if (!(item->flags & CD_FLAG_TXT)) |
|
- return 0; /* "I did not print anything" */ |
|
- |
|
- char *truncated = NULL; |
|
- |
|
- if (strlen(item->content) >= max_text_size) |
|
- { |
|
- char *error_msg = NULL; |
|
- const char *analyzer = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER); |
|
- if (!analyzer) |
|
- return 0; |
|
- |
|
- /* For CCpp crashes, use the GDB-produced backtrace which should be |
|
- * available by now. sr_abrt_type_from_analyzer returns SR_REPORT_CORE |
|
- * by default for CCpp crashes. |
|
- */ |
|
- enum sr_report_type report_type = sr_abrt_type_from_analyzer(analyzer); |
|
- if (strcmp(analyzer, "CCpp") == 0) |
|
- report_type = SR_REPORT_GDB; |
|
- |
|
- struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type, |
|
- item->content, &error_msg); |
|
- |
|
- if (!backtrace) |
|
- { |
|
- log(_("Can't parse backtrace: %s"), error_msg); |
|
- free(error_msg); |
|
- return 0; |
|
- } |
|
- |
|
- /* Get optimized thread stack trace for 10 top most frames */ |
|
- truncated = sr_stacktrace_to_short_text(backtrace, 10); |
|
- sr_stacktrace_free(backtrace); |
|
- |
|
- if (!truncated) |
|
- { |
|
- log(_("Can't generate stacktrace description (no crash thread?)")); |
|
- return 0; |
|
- } |
|
- } |
|
- |
|
- append_text(result, |
|
- /*item_name:*/ truncated ? "truncated_backtrace" : FILENAME_BACKTRACE, |
|
- /*content:*/ truncated ? truncated : item->content, |
|
- print_item_name |
|
- ); |
|
- free(truncated); |
|
- return 1; |
|
-} |
|
- |
|
-static |
|
-int append_item(struct strbuf *result, const char *item_name, problem_data_t *pd, GList *comment_fmt_spec) |
|
-{ |
|
- bool print_item_name = (strncmp(item_name, "%bare_", strlen("%bare_")) != 0); |
|
- if (!print_item_name) |
|
- item_name += strlen("%bare_"); |
|
- |
|
- if (item_name[0] != '%') |
|
- { |
|
- struct problem_item *item = problem_data_get_item_or_NULL(pd, item_name); |
|
- if (!item) |
|
- return 0; /* "I did not print anything" */ |
|
- if (!(item->flags & CD_FLAG_TXT)) |
|
- return 0; /* "I did not print anything" */ |
|
- |
|
- char *formatted = problem_item_format(item); |
|
- char *content = formatted ? formatted : item->content; |
|
- append_text(result, item_name, content, print_item_name); |
|
- free(formatted); |
|
- return 1; /* "I printed something" */ |
|
- } |
|
- |
|
- /* Special item name */ |
|
- |
|
- /* Compat with previously-existed ad-hockery: %short_backtrace */ |
|
- if (strcmp(item_name, "%short_backtrace") == 0) |
|
- return append_short_backtrace(result, pd, CD_TEXT_ATT_SIZE_BZ, print_item_name); |
|
- |
|
- /* Compat with previously-existed ad-hockery: %reporter */ |
|
- if (strcmp(item_name, "%reporter") == 0) |
|
- return append_text(result, "reporter", PACKAGE"-"VERSION, print_item_name); |
|
- |
|
- /* %oneline,%multiline,%text */ |
|
- bool oneline = (strcmp(item_name+1, "oneline" ) == 0); |
|
- bool multiline = (strcmp(item_name+1, "multiline") == 0); |
|
- bool text = (strcmp(item_name+1, "text" ) == 0); |
|
- if (!oneline && !multiline && !text) |
|
- { |
|
- log("Unknown or unsupported element specifier '%s'", item_name); |
|
- return 0; /* "I did not print anything" */ |
|
- } |
|
- |
|
- int printed = 0; |
|
- |
|
- /* Iterate over _sorted_ items */ |
|
- GList *sorted_names = g_hash_table_get_keys(pd); |
|
- sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp); |
|
- |
|
- /* %text => do as if %oneline, then repeat as if %multiline */ |
|
- if (text) |
|
- oneline = 1; |
|
- |
|
- again: ; |
|
- GList *l = sorted_names; |
|
- while (l) |
|
- { |
|
- const char *name = l->data; |
|
- l = l->next; |
|
- struct problem_item *item = g_hash_table_lookup(pd, name); |
|
- if (!item) |
|
- continue; /* paranoia, won't happen */ |
|
- |
|
- if (!(item->flags & CD_FLAG_TXT)) |
|
- continue; |
|
- |
|
- if (is_explicit_or_forbidden(name, comment_fmt_spec)) |
|
- continue; |
|
- |
|
- char *formatted = problem_item_format(item); |
|
- char *content = formatted ? formatted : item->content; |
|
- char *eol = strchrnul(content, '\n'); |
|
- bool is_oneline = (eol[0] == '\0' || eol[1] == '\0'); |
|
- if (oneline == is_oneline) |
|
- printed |= append_text(result, name, content, print_item_name); |
|
- free(formatted); |
|
- } |
|
- if (text && oneline) |
|
- { |
|
- /* %text, and we just did %oneline. Repeat as if %multiline */ |
|
- oneline = 0; |
|
- /*multiline = 1; - not checked in fact, so why bother setting? */ |
|
- goto again; |
|
- } |
|
- |
|
- g_list_free(sorted_names); /* names themselves are not freed */ |
|
- |
|
- return printed; |
|
-} |
|
- |
|
-static |
|
-void generate_bz_comment(struct strbuf *result, problem_data_t *pd, GList *comment_fmt_spec) |
|
-{ |
|
- bool last_line_is_empty = true; |
|
- GList *l = comment_fmt_spec; |
|
- while (l) |
|
- { |
|
- section_t *sec = l->data; |
|
- l = l->next; |
|
- |
|
- /* Skip special sections such as "%attach" */ |
|
- if (sec->name[0] == '%') |
|
- continue; |
|
- |
|
- if (sec->items) |
|
- { |
|
- /* "Text: item[,item]..." */ |
|
- struct strbuf *output = strbuf_new(); |
|
- GList *item = sec->items; |
|
- while (item) |
|
- { |
|
- const char *str = item->data; |
|
- item = item->next; |
|
- if (str[0] == '-') /* "-name", ignore it */ |
|
- continue; |
|
- append_item(output, str, pd, comment_fmt_spec); |
|
- } |
|
- |
|
- if (output->len != 0) |
|
- { |
|
- strbuf_append_strf(result, |
|
- sec->name[0] ? "%s:\n%s" : "%s%s", |
|
- sec->name, |
|
- output->buf |
|
- ); |
|
- last_line_is_empty = false; |
|
- } |
|
- strbuf_free(output); |
|
- } |
|
- else |
|
- { |
|
- /* Just "Text" (can be "") */ |
|
- |
|
- /* Filter out consecutive empty lines */ |
|
- if (sec->name[0] != '\0' || !last_line_is_empty) |
|
- strbuf_append_strf(result, "%s\n", sec->name); |
|
- last_line_is_empty = (sec->name[0] == '\0'); |
|
- } |
|
- } |
|
- |
|
- /* Nuke any trailing empty lines */ |
|
- while (result->len >= 1 |
|
- && result->buf[result->len-1] == '\n' |
|
- && (result->len == 1 || result->buf[result->len-2] == '\n') |
|
- ) { |
|
- result->buf[--result->len] = '\0'; |
|
- } |
|
-} |
|
- |
|
- |
|
/* BZ attachments */ |
|
|
|
static |
|
@@ -573,104 +69,6 @@ int attach_file_item(struct abrt_xmlrpc *ax, const char *bug_id, |
|
return (r == 0); |
|
} |
|
|
|
-static |
|
-int attach_item(struct abrt_xmlrpc *ax, const char *bug_id, |
|
- const char *item_name, problem_data_t *pd, GList *comment_fmt_spec) |
|
-{ |
|
- if (item_name[0] != '%') |
|
- { |
|
- struct problem_item *item = problem_data_get_item_or_NULL(pd, item_name); |
|
- if (!item) |
|
- return 0; |
|
- if (item->flags & CD_FLAG_TXT) |
|
- return attach_text_item(ax, bug_id, item_name, item); |
|
- if (item->flags & CD_FLAG_BIN) |
|
- return attach_file_item(ax, bug_id, item_name, item); |
|
- return 0; |
|
- } |
|
- |
|
- /* Special item name */ |
|
- |
|
- /* %oneline,%multiline,%text,%binary */ |
|
- bool oneline = (strcmp(item_name+1, "oneline" ) == 0); |
|
- bool multiline = (strcmp(item_name+1, "multiline") == 0); |
|
- bool text = (strcmp(item_name+1, "text" ) == 0); |
|
- bool binary = (strcmp(item_name+1, "binary" ) == 0); |
|
- if (!oneline && !multiline && !text && !binary) |
|
- { |
|
- log("Unknown or unsupported element specifier '%s'", item_name); |
|
- return 0; |
|
- } |
|
- |
|
- log_debug("Special item_name '%s', iterating for attach...", item_name); |
|
- int done = 0; |
|
- |
|
- /* Iterate over _sorted_ items */ |
|
- GList *sorted_names = g_hash_table_get_keys(pd); |
|
- sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp); |
|
- |
|
- GList *l = sorted_names; |
|
- while (l) |
|
- { |
|
- const char *name = l->data; |
|
- l = l->next; |
|
- struct problem_item *item = g_hash_table_lookup(pd, name); |
|
- if (!item) |
|
- continue; /* paranoia, won't happen */ |
|
- |
|
- if (is_explicit_or_forbidden(name, comment_fmt_spec)) |
|
- continue; |
|
- |
|
- if ((item->flags & CD_FLAG_TXT) && !binary) |
|
- { |
|
- char *content = item->content; |
|
- char *eol = strchrnul(content, '\n'); |
|
- bool is_oneline = (eol[0] == '\0' || eol[1] == '\0'); |
|
- if (text || oneline == is_oneline) |
|
- done |= attach_text_item(ax, bug_id, name, item); |
|
- } |
|
- if ((item->flags & CD_FLAG_BIN) && binary) |
|
- done |= attach_file_item(ax, bug_id, name, item); |
|
- } |
|
- |
|
- g_list_free(sorted_names); /* names themselves are not freed */ |
|
- |
|
- |
|
- log_debug("...Done iterating over '%s' for attach", item_name); |
|
- |
|
- return done; |
|
-} |
|
- |
|
-static |
|
-int attach_files(struct abrt_xmlrpc *ax, const char *bug_id, |
|
- problem_data_t *pd, GList *comment_fmt_spec) |
|
-{ |
|
- int done = 0; |
|
- GList *l = comment_fmt_spec; |
|
- while (l) |
|
- { |
|
- section_t *sec = l->data; |
|
- l = l->next; |
|
- |
|
- /* Find %attach" */ |
|
- if (strcmp(sec->name, "%attach") != 0) |
|
- continue; |
|
- |
|
- GList *item = sec->items; |
|
- while (item) |
|
- { |
|
- const char *str = item->data; |
|
- item = item->next; |
|
- if (str[0] == '-') /* "-name", ignore it */ |
|
- continue; |
|
- done |= attach_item(ax, bug_id, str, pd, comment_fmt_spec); |
|
- } |
|
- } |
|
- |
|
- return done; |
|
-} |
|
- |
|
- |
|
/* Main */ |
|
|
|
struct bugzilla_struct { |
|
@@ -1102,18 +500,29 @@ int main(int argc, char **argv) |
|
|
|
if (opts & OPT_D) |
|
{ |
|
- GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file); |
|
- struct strbuf *bzcomment_buf = strbuf_new(); |
|
- generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec); |
|
- char *bzcomment = strbuf_free_nobuf(bzcomment_buf); |
|
- char *summary = create_summary_string(problem_data, comment_fmt_spec); |
|
+ problem_formatter_t *pf = problem_formatter_new(); |
|
+ |
|
+ if (problem_formatter_load_file(pf, fmt_file)) |
|
+ error_msg_and_die("Invalid format file: %s", fmt_file); |
|
+ |
|
+ problem_report_t *pr = NULL; |
|
+ if (problem_formatter_generate_report(pf, problem_data, &pr)) |
|
+ error_msg_and_die("Failed to format bug report from problem data"); |
|
+ |
|
printf("summary: %s\n" |
|
"\n" |
|
"%s" |
|
- , summary, bzcomment |
|
+ "\n" |
|
+ , problem_report_get_summary(pr) |
|
+ , problem_report_get_description(pr) |
|
); |
|
- free(bzcomment); |
|
- free(summary); |
|
+ |
|
+ puts("attachments:"); |
|
+ for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a)) |
|
+ printf(" %s\n", (const char *)a->data); |
|
+ |
|
+ problem_report_free(pr); |
|
+ problem_formatter_free(pf); |
|
exit(0); |
|
} |
|
|
|
@@ -1196,22 +605,29 @@ int main(int argc, char **argv) |
|
/* Create new bug */ |
|
log(_("Creating a new bug")); |
|
|
|
- GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file); |
|
+ problem_formatter_t *pf = problem_formatter_new(); |
|
+ |
|
+ if (problem_formatter_load_file(pf, fmt_file)) |
|
+ error_msg_and_die("Invalid format file: %s", fmt_file); |
|
+ |
|
+ problem_report_t *pr = NULL; |
|
+ if (problem_formatter_generate_report(pf, problem_data, &pr)) |
|
+ error_msg_and_die("Failed to format problem data"); |
|
|
|
- struct strbuf *bzcomment_buf = strbuf_new(); |
|
- generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec); |
|
if (crossver_id >= 0) |
|
- strbuf_append_strf(bzcomment_buf, "\nPotential duplicate: bug %u\n", crossver_id); |
|
- char *bzcomment = strbuf_free_nobuf(bzcomment_buf); |
|
- char *summary = create_summary_string(problem_data, comment_fmt_spec); |
|
+ problem_report_buffer_printf( |
|
+ problem_report_get_buffer(pr, PR_SEC_DESCRIPTION), |
|
+ "\nPotential duplicate: bug %u\n", crossver_id); |
|
+ |
|
+ problem_formatter_free(pf); |
|
+ |
|
int new_id = rhbz_new_bug(client, |
|
problem_data, rhbz.b_product, rhbz.b_product_version, |
|
- summary, bzcomment, |
|
+ problem_report_get_summary(pr), |
|
+ problem_report_get_description(pr), |
|
(rhbz.b_create_private | (opts & OPT_g)), // either we got Bugzilla_CreatePrivate from settings or -g was specified on cmdline |
|
rhbz.b_private_groups |
|
); |
|
- free(bzcomment); |
|
- free(summary); |
|
|
|
if (new_id == -1) |
|
{ |
|
@@ -1236,9 +652,17 @@ int main(int argc, char **argv) |
|
char new_id_str[sizeof(int)*3 + 2]; |
|
sprintf(new_id_str, "%i", new_id); |
|
|
|
- attach_files(client, new_id_str, problem_data, comment_fmt_spec); |
|
- |
|
-//TODO: free_comment_fmt_spec(comment_fmt_spec); |
|
+ for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a)) |
|
+ { |
|
+ const char *item_name = (const char *)a->data; |
|
+ struct problem_item *item = problem_data_get_item_or_NULL(problem_data, item_name); |
|
+ if (!item) |
|
+ continue; |
|
+ else if (item->flags & CD_FLAG_TXT) |
|
+ attach_text_item(client, new_id_str, item_name, item); |
|
+ else if (item->flags & CD_FLAG_BIN) |
|
+ attach_file_item(client, new_id_str, item_name, item); |
|
+ } |
|
|
|
bz = new_bug_info(); |
|
bz->bi_status = xstrdup("NEW"); |
|
@@ -1302,18 +726,21 @@ int main(int argc, char **argv) |
|
const char *comment = problem_data_get_content_or_NULL(problem_data, FILENAME_COMMENT); |
|
if (comment && comment[0]) |
|
{ |
|
- GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file2); |
|
- struct strbuf *bzcomment_buf = strbuf_new(); |
|
- generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec); |
|
- char *bzcomment = strbuf_free_nobuf(bzcomment_buf); |
|
-//TODO: free_comment_fmt_spec(comment_fmt_spec); |
|
+ problem_formatter_t *pf = problem_formatter_new(); |
|
+ if (problem_formatter_load_file(pf, fmt_file2)) |
|
+ error_msg_and_die("Invalid duplicate format file: '%s", fmt_file2); |
|
+ |
|
+ problem_report_t *pr; |
|
+ if (problem_formatter_generate_report(pf, problem_data, &pr)) |
|
+ error_msg_and_die("Failed to format duplicate comment from problem data"); |
|
+ |
|
+ const char *bzcomment = problem_report_get_description(pr); |
|
|
|
int dup_comment = is_comment_dup(bz->bi_comments, bzcomment); |
|
if (!dup_comment) |
|
{ |
|
log(_("Adding new comment to bug %d"), bz->bi_id); |
|
rhbz_add_comment(client, bz->bi_id, bzcomment, 0); |
|
- free(bzcomment); |
|
|
|
const char *bt = problem_data_get_content_or_NULL(problem_data, FILENAME_BACKTRACE); |
|
unsigned rating = 0; |
|
@@ -1331,10 +758,10 @@ int main(int argc, char **argv) |
|
} |
|
} |
|
else |
|
- { |
|
- free(bzcomment); |
|
log(_("Found the same comment in the bug history, not adding a new one")); |
|
- } |
|
+ |
|
+ problem_report_free(pr); |
|
+ problem_formatter_free(pf); |
|
} |
|
|
|
log_out: |
|
-- |
|
1.8.3.1 |
|
|
|
|