diff --git a/modules/openstack_project/files/gerrit/hideci.js b/modules/openstack_project/files/gerrit/hideci.js index 78c61d1e99..7275c57127 100644 --- a/modules/openstack_project/files/gerrit/hideci.js +++ b/modules/openstack_project/files/gerrit/hideci.js @@ -1,4 +1,5 @@ // Copyright (c) 2014 VMware, Inc. +// Copyright (c) 2014 Hewlett-Packard Development Company, L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain @@ -13,189 +14,181 @@ // under the License. // this regex matches the hash part of review pages -var hashRegex = /^\#\/c\/[\/\d]+$/ +var hashRegex = /^\#\/c\/[\/\d]+$/; // this regex matches CI comments -var ciRegex = /^(.* CI|Jenkins)$/ +var ciRegex = /^(.* CI|Jenkins)$/; // this regex matches "Patch set #" -var psRegex = /^Patch Set (\d+):/ +var psRegex = /^

(Uploaded patch set|Patch Set) (\d+)(:|\.)/; // this regex matches merge failure messages -var mergeFailedRegex = /^Merge Failed\./ +var mergeFailedRegex = /Merge Failed\./; // this regex matches the name of CI systems we trust to report merge failures -var trustedCIRegex = /^(OpenStack CI|Jenkins)$/ +var trustedCIRegex = /^(OpenStack CI|Jenkins)$/; -ci_find_comments = function() { - var comments = []; - var last_merge_failure = null; - $("p").each(function() { - var match = psRegex.exec(this.innerHTML); - if (match !== null) { - var psnum = parseInt(match[1]); - var top = $(this).parent().parent().parent(); - var name = top.attr("name"); - if (!name) { - top = $(this).parent().parent().parent(); - name = $(this).parent().prev().children()[0].innerHTML; - } - // Search this comment for results - var comment_object = $(this).parent(); - var result_list = []; - comment_object.find("li.comment_test").each(function(i, li) { - var result = {}; - result["name"] = $(li).find("span.comment_test_name").find("a")[0].innerHTML; - result["link"] = $(li).find("span.comment_test_name").find("a")[0]; - result["result"] = $(li).find("span.comment_test_result")[0]; - result_list.push(result); - }); - - var comment = {"name":name, "psnum":psnum, "top":top, - "merge_failure":null, - "results":result_list, - "comment":comment_object}; - comments.push(comment); - - // Keep a pointer to the most recent merge failure message from - // the trusted CI system. If there is a message from the system - // after it, drop the reference. This way we end up with a pointer - // iff the last comment from the trusted system is a merge failure. - if (trustedCIRegex.exec(name) !== null) { - if ($(this).next().length>0 && - mergeFailedRegex.exec($(this).next()[0].innerHTML) !== null) { - last_merge_failure = comment; - } else if (result_list.length>0) { - last_merge_failure = null; - } - } - - } - }); - // If the last comment from the trusted system is a merge failure, - // mark that comment as a merge failure so it is displayed. (We - // want to ignore it if there was a merge failure that was - // superceded.) - if (last_merge_failure !== null) { - last_merge_failure["merge_failure"] = true; +var ci_parse_psnum = function($panel) { + var match = psRegex.exec($panel.html()); + if (match !== null) { + return parseInt(match[2]); } + return 0; +}; + +var ci_parse_is_merge_conflict = function($panel) { + return (mergeFailedRegex.exec($panel.html()) !== null); +}; + +var ci_parse_results = function($panel) { + var result_list = []; + var test_results = $panel.find("li.comment_test"); + if (test_results !== null) { + test_results.each(function(i, li) { + var result = {}; + result["name"] = $(li).find("span.comment_test_name").find("a")[0].innerHTML; + result["link"] = $(li).find("span.comment_test_name").find("a")[0]; + result["result"] = $(li).find("span.comment_test_result")[0]; + result_list.push(result); + }); + } + return result_list; +}; + +var ci_parse_comments = function() { + var comments = []; + $(".commentPanel").each(function() { + var comment = {}; + comment.name = $(this).attr("name"); + comment.email = $(this).attr("email"); + comment.date = $(this).find(".commentPanelDateCell").attr("title"); + var comment_panel = $(this).find(".commentPanelMessage"); + comment.psnum = ci_parse_psnum(comment_panel); + comment.merge_conflict = ci_parse_is_merge_conflict(comment_panel); + comment.results = ci_parse_results(comment_panel); + comment.is_ci = (ciRegex.exec(comment.name) !== null); + comment.is_trusted_ci = (trustedCIRegex.exec(comment.name) !== null); + comment.ref = this; + comments.push(comment); + }); return comments; }; -ci_update_table = function() { - var patchsets = []; +var ci_latest_patchset = function(comments) { + var psnum = 0; + for (var i = 0; i < comments.length; i++) { + psnum = Math.max(psnum, comments[i].psnum); + } + return psnum; +}; - var comments = ci_find_comments(); - $.each(comments, function(comment_index, comment) { - while (patchsets.length < comment["psnum"]) { - // Whether there is a current merge failure in this - // patchset. - patchsets.push({"_merge_failure": false}); - } - - // If this comment has results - if (comment["results"].length > 0) { - // Get the name of the system - var name = comment["name"]; - // an item in patchsets is a hash of systems - var systems = patchsets[comment["psnum"]-1]; - var system; - // Get or create the system object for this system - if (name in systems) { - system = systems[name]; - } else { - // A system object has an ordered list of jobs (so - // we preserve what was in the comments), and a - // hash of results (so later runs of the same job - // on the same patchset override previous results). - system = {"jobs": [], "results": {}}; - systems[name] = system; +var ci_is_merge_conflict = function(comments) { + var latest = ci_latest_patchset(comments); + var conflict = false; + for (var i = 0; i < comments.length; i++) { + var comment = comments[i]; + // only if we are actually talking about the latest patch set + if (comment.psnum == latest) { + if (comment.is_trusted_ci) { + conflict = comment.merge_conflict; } - $.each(comment["results"], function(i, result) { - // For each result, add the name of the job to the - // ordered list if it isn't there already - if (system["jobs"].indexOf(result["name"]) < 0) { - system["jobs"].push(result["name"]); - } - // Then set or override the result - system["results"][result["name"]] = result; - }); } - // The merge failure flag will only be set on a comment if it - // is the most recent comment and is a merge failure. - if (comment["merge_failure"] === true) { - patchsets[comment["psnum"]-1]["_merge_failure"] = true; - } - }); + } + return conflict; +}; - if (patchsets.length > 0) { - // Create a table and insert it after the approval table - var table = $("table.test_result_table")[0]; - if (!table) { - table = document.createElement("table"); - $(table).addClass("test_result_table"); - $(table).addClass("infoTable").css({"margin-top":"1em", "margin-bottom":"1em"}); - var approval_table = $("div.approvalTable"); - if (approval_table.length) { - var outer_table = document.createElement("table"); - $(outer_table).insertBefore(approval_table); - var outer_table_row = document.createElement("tr"); - $(outer_table).append(outer_table_row); - var td = document.createElement("td"); - $(outer_table_row).append(td); - $(td).css({"vertical-align":"top"}); - $(td).append(approval_table); - td = document.createElement("td"); - $(outer_table_row).append(td); - $(td).css({"vertical-align":"top"}); - $(td).append(table); - } else { - var big_table_row = $("div.screen>div>div>table>tbody>tr"); - var td = $(big_table_row).children()[1]; - $(td).append(table); - } - // Hide existing comments - ci_toggle_visibility(comments); +var ci_prepare_results_table = function() { + // Create a table and insert it after the approval table + var table = $("table.test_result_table")[0]; + if (!table) { + table = document.createElement("table"); + $(table).addClass("test_result_table"); + $(table).addClass("infoTable").css({"margin-top":"1em", "margin-bottom":"1em"}); + var approval_table = $("div.approvalTable"); + if (approval_table.length) { + var outer_table = document.createElement("table"); + $(outer_table).insertBefore(approval_table); + var outer_table_row = document.createElement("tr"); + $(outer_table).append(outer_table_row); + var td = document.createElement("td"); + $(outer_table_row).append(td); + $(td).css({"vertical-align":"top"}); + $(td).append(approval_table); + td = document.createElement("td"); + $(outer_table_row).append(td); + $(td).css({"vertical-align":"top"}); + $(td).append(table); } else { - $(table).empty(); + var big_table_row = $("div.screen>div>div>table>tbody>tr"); + var td = $(big_table_row).children()[1]; + $(td).append(table); } - var patchset = patchsets[patchsets.length-1]; - if (!patchset["_merge_failure"]) { - $.each(patchset, function(name, system) { - if (name != "_merge_failure") { - // Add a header for each system - var header = $("").append($(''+name+'')); - $(table).append(header); - // Add the results - $.each(system["jobs"], function(i, name) { - var result = system["results"][name]; - var tr = $(""); - tr.append($("").append($(result["link"]).clone())); - tr.append($("").append($(result["result"]).clone())); - $(table).append(tr); - }); - } - }); + } else { + $(table).empty(); + } + return table; +}; + +var ci_display_results = function(comments) { + var table = ci_prepare_results_table(); + if (ci_is_merge_conflict(comments)) { + var mc_header = $("").append($('Patch in Merge Conflict')); + mc_header.css('width', '400'); + mc_header.css('font-weight', 'bold'); + mc_header.css('color', 'red'); + mc_header.css('padding-left', '2em'); + $(table).append(mc_header); + + return; + } + var current = ci_latest_patchset(comments); + for (var i = 0; i < comments.length; i++) { + var comment = comments[i]; + if ((comment.psnum == current) && comment.is_ci && (comment.results.length > 0)) { + var header = $("").append($('' + comment.name + '')); + header.append('' + comment.date + ''); + $(table).append(header); + + for (var j = 0; j < comment.results.length; j++) { + var result = comment.results[j]; + var tr = $(""); + tr.append($("").append($(result["link"]).clone())); + tr.append($("").append($(result["result"]).clone())); + $(table).append(tr); + } } } }; -ci_page_loaded = function() { +var ci_toggle_visibility = function(comments) { + if (!comments) { + comments = ci_parse_comments(); + } + $.each(comments, function(i, comment) { + if (comment.is_ci) { + $(comment.ref).toggle(); + } + }); +}; + +var ci_hide_ci_comments = function(comments) { + if (!comments) { + comments = ci_parse_comments(); + } + $.each(comments, function(i, comment) { + if (comment.is_ci) { + $(comment.ref).hide(); + } + }); +}; + +var ci_page_loaded = function() { if (hashRegex.test(window.location.hash)) { $("#toggleci").show(); - ci_update_table(); + var comments = ci_parse_comments(); + ci_display_results(comments); + ci_hide_ci_comments(comments); } else { $("#toggleci").hide(); } }; -ci_toggle_visibility = function(comments) { - if (!comments) { - comments = ci_find_comments(); - } - $.each(comments, function(i, comment) { - if (ciRegex.exec(comment["name"]) && - !comment["merge_failure"]) { - comment["top"].toggle(); - } - }); -}; window.onload = function() { var input = document.createElement("input");