Alexandre Julliard : patches: Display replies under the main patch.
Alexandre Julliard
julliard at winehq.org
Wed Nov 8 03:39:48 CST 2017
Module: tools
Branch: master
Commit: 0d60762f674e42035b8ad788b2a26f49a8b97fe5
URL: http://source.winehq.org/git/tools.git/?a=commit;h=0d60762f674e42035b8ad788b2a26f49a8b97fe5
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Nov 8 10:17:12 2017 +0100
patches: Display replies under the main patch.
Signed-off-by: Alexandre Julliard <julliard at 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]);
}
}
More information about the wine-cvs
mailing list