Alexandre Julliard : patches: Display replies under the main patch.
Module: tools Branch: master Commit: 0d60762f674e42035b8ad788b2a26f49a8b97fe5 URL: http://source.winehq.org/git/tools.git/?a=commit;h=0d60762f674e42035b8ad788b... Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Nov 8 10:17:12 2017 +0100 patches: Display replies under the main patch. Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- patches/patches.css | 5 +++- patches/update | 84 ++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/patches/patches.css b/patches/patches.css index c1ef34f..f7bb560 100644 --- a/patches/patches.css +++ b/patches/patches.css @@ -132,15 +132,18 @@ div.buglist { border: 1px solid #601919; } table.main, table.legend { width: 100%; } +table.main { border-collapse: collapse; } table.legend ul { margin: 2px 0; } tr.even { background-color: #fff8f8; } tr.odd { background-color: #f8e8e8; } +.indent { padding: 0 2em; } .id, .status, .testbot { text-align: center; } -.id, .status, .author { white-space: nowrap; padding: 0 3px; } +.id, .status, .author { white-space: nowrap; padding: 2px 3px; } .checkmark { text-align: center; color:green; } +.arrow { text-align: center; padding: 0 0; } .failmark { text-align: center; color: red; } .signoffextra { color: #A50D0D; border: 1px solid #601919; } .sha1 { white-space: nowrap; font-family: monospace; padding: 2px 12px; } diff --git a/patches/update b/patches/update index cdc172d..9e12c4b 100755 --- a/patches/update +++ b/patches/update @@ -90,6 +90,7 @@ my @legend = my $dir = $ARGV[0] || "$ENV{HOME}/patches"; my $dest = "/home/winehq/opt/source/patches"; my %patches; +my %messages; sub format_author($) { @@ -126,7 +127,7 @@ print INDEX "<div id=\"logo_blurb\">Wine source repository – Patch status< print INDEX "<div id=\"main_content\"><div id=\"content\"><div class=\"main\">\n"; print INDEX "<table id=\"main_table\" class=\"main\"><thead><tr><th class=\"id\">ID</th>", "<th class=\"status\">Status</th>", - "<th class=\"author\">Author</th>", + "<th colspan=\"2\" class=\"author\">Author</th>", "<th class=\"subject\">Subject</th>", "<th class=\"author\">Reviewer</th>", "<th class=\"status\">Sign</th>", @@ -144,6 +145,8 @@ foreach my $file (readdir DIR) utf8::decode($_); if (/^Subject: (.*)$/) { $patch{"subject"} = $1; } elsif (/^From: (.*)$/) { $patch{"author"} = format_author($1); } + elsif (/^Message-Id: (.*)$/) { $patch{"msgid"} = $1; } + elsif (/^In-Reply-To: (.*)$/) { $patch{"reply"} = $1; } last if (/^$/); } while (<PATCH>) @@ -152,8 +155,14 @@ foreach my $file (readdir DIR) if (/^\s*Signed-off-by: (.*)$/) { push @{$patch{"signoff"}}, format_author($1); } last if (/^---$/); } + while (<PATCH>) + { + utf8::decode($_); + if (/^diff --git a\//) { $patch{"has_patch"} = 1; last; } + } close PATCH; + $patch{"id"} = $file; $patch{"status"} = "nil"; if (open STATUS, "<$dir/$file.status") { @@ -208,19 +217,52 @@ foreach my $file (readdir DIR) { $patch{"testbot"} = "Failed"; } + if (defined $patch{"msgid"}) + { + $messages{$patch{"msgid"}} = \%patch; + } $patches{$file} = \%patch; } closedir DIR; +# build mail threads + +foreach my $file (sort keys %patches) +{ + my $patch = $patches{$file}; + next if defined $patch->{"has_patch"}; + next unless defined $patch->{"reply"}; + next unless defined $messages{$patch->{"reply"}}; + my $parent = $messages{$patch->{"reply"}}; + # find top parent + while (!defined($parent->{"has_patch"}) && defined($parent->{"reply"})) + { + $parent = $messages{$parent->{"reply"}}; + } + next unless defined $parent; + # add it to the parent's children and remove it from the list + $patch->{"parent"} = $parent; + push @{$parent->{"children"}}, $patch; + delete $patches{$file}; +} + my $row = 0; foreach my $file (sort { $patches{$b}->{"order"} <=> $patches{$a}->{"order"} } keys %patches) { my $patch = $patches{$file}; - printf INDEX "<tr class=\"%s %s\"><td class=\"id\">%s</td><td class=\"status\"><a href=\"#legend\">%s</a></td><td class=\"author\">%s</td>", - $row & 1 ? "odd" : "even", $patch->{"status"}, $file, $status_descr{$patch->{"status"}} || $patch->{"status"}, - escapeHTML($patch->{"author"}); - printf INDEX "<td class=\"subject\"><a href=\"data/$file\">%s</a></td>", - escapeHTML($patch->{"subject"}); + + printf INDEX "<tr class=\"%s %s\"><td class=\"id\">%s</td><td class=\"status\"><a href=\"#legend\">%s</a></td>", + $row & 1 ? "odd" : "even", $patch->{"status"}, $file, $status_descr{$patch->{"status"}} || $patch->{"status"}; + if (defined $patch->{"children"}) + { + printf INDEX "<td class=\"author\">%s</td>", escapeHTML($patch->{"author"}); + printf INDEX "<td class=\"arrow\" onclick=\"toggle_display('$file.reply')\">▼</td>"; + } + else + { + printf INDEX "<td colspan=\"2\" class=\"author\">%s</td>", escapeHTML($patch->{"author"}); + } + printf INDEX "<td class=\"subject\"><a href=\"data/$file\">%s</a></td>", escapeHTML($patch->{"subject"}); if ($patch->{"review"}) { printf INDEX "<td class=\"author\">%s</td>", escapeHTML($patch->{"review"}); @@ -259,9 +301,17 @@ foreach my $file (sort { $patches{$b}->{"order"} <=> $patches{$a}->{"order"} } k if (defined($patch->{"signoff"})) { printf INDEX "<tr class=\"%s\" id=\"$file.signoff\" style=\"display: none;\" onclick=\"toggle_display('$file.signoff')\">" . - "<td colspan=\"4\" /><td colspan=\"4\" class=\"signoffextra author\">%s</td></tr>\n", + "<td colspan=\"5\" /><td colspan=\"4\" class=\"signoffextra author\">%s</td></tr>\n", $row & 1 ? "odd" : "even", join("", map { "Signed-off-by: " . escapeHTML($_) . "<br/>"; } @{$patch->{"signoff"}}); } + foreach my $child (@{$patch->{"children"}}) + { + printf INDEX "<tr class=\"%s\" id=\"$file.reply\" style=\"display: none;\" onclick=\"toggle_display('$file.reply')\">" . + "<td colspan=\"2\" /><td colspan=\"2\" class=\"reply author\"><span class=\"indent\" />%s</td> " . + "<td class=\"reply author\"><span class=\"indent\" /><a href=\"data/%s\">%s</a></td> " . + "<td colspan=\"4\" /></tr>\n", + $row & 1 ? "odd" : "even", escapeHTML($child->{"author"}), $child->{"id"}, escapeHTML($child->{"subject"}); + } $row++; } print INDEX "</tbody></table></div>\n"; @@ -284,7 +334,7 @@ my $sorter = <<END; tbody = table.children[1], ths = thead.getElementsByTagName('th'), trs = tbody.getElementsByTagName('tr'), - i, do_reverse, th, sort_func; + i, j, k, id, do_reverse, th, sort_func; for (i = 0; i < ths.length; i++) ths[i].onclick = sort_table; @@ -307,13 +357,20 @@ my $sorter = <<END; do_reverse = 1; th.setAttribute('data-order', do_reverse) - for (j = 0, i = trs.length - 1; i != -1; i--) + for (j = 0, k = 0, i = trs.length - 1; i != -1; i--) { - tr = tbody.removeChild(trs[i]) + tr = tbody.removeChild(trs[0]) if (!tr.getAttribute('id')) + { clone_trs[j++] = tr; - else - sign_trs[text_content(trs[i - 1].children[0])] = tr; /* based on the patch ID */ + id = text_content(tr.children[0]); + k = 0; + } + else if (id) /* based on the patch ID */ + { + if (!k) sign_trs[id] = []; + sign_trs[id][k++] = tr; + } } clone_trs.sort(sorter); @@ -323,7 +380,8 @@ my $sorter = <<END; tbody.appendChild(clone_trs[i]); j = text_content(clone_trs[i].children[0]); if (sign_trs[j]) - tbody.appendChild(sign_trs[j]); + for (k = 0; k < sign_trs[j].length; k++) + tbody.appendChild(sign_trs[j][k]); } }
participants (1)
-
Alexandre Julliard