Skip to content

Commit 87881e9

Browse files
committed
fix: Keep patch series together
1 parent c651d22 commit 87881e9

4 files changed

Lines changed: 82 additions & 28 deletions

File tree

resources/bark-index.js

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -384,23 +384,6 @@ function sortReports(key, dir) {
384384

385385
/* ── Series folding ─────────────────────────────────────────── */
386386

387-
function seriesStatusSummary(members) {
388-
var acked = 0, closed = 0, open = 0;
389-
for (var i = 0; i < members.length; i++) {
390-
var seq = members[i].raw['patch-seq'] || '';
391-
if (seq.indexOf('0/') === 0) continue; // skip cover letter
392-
var flags = members[i].raw.flags || '---';
393-
if (flags.length >= 3 && flags[2] !== '-') closed++;
394-
else if (flags[0] !== '-') acked++;
395-
else open++;
396-
}
397-
var parts = [];
398-
if (acked) parts.push(acked + ' acked');
399-
if (closed) parts.push(closed + ' closed');
400-
if (open) parts.push(open + ' open');
401-
return parts.join(', ');
402-
}
403-
404387
function isSeriesHomogeneous(members) {
405388
var refCat = null;
406389
for (var i = 0; i < members.length; i++) {
@@ -465,7 +448,6 @@ function buildDisplayList() {
465448
repEntry._seriesFolded = folded;
466449
repEntry._seriesId = sid;
467450
repEntry._seriesMembers = members;
468-
repEntry._seriesSummary = seriesStatusSummary(members);
469451

470452
// Replace placeholder with representative + optionally expanded members
471453
var insert = [repEntry];
@@ -557,19 +539,11 @@ function buildRowElement(rpt) {
557539
if (rpt._isSeries && rpt._seriesMembers && rpt._seriesMembers.length > 1) {
558540
var arrow = rpt._seriesFolded ? '\u25B6' : '\u25BC';
559541
var stitle = rpt._seriesFolded ? 'Unfold series' : 'Fold series';
560-
var patchCount = 0;
561-
if (rpt._seriesMembers) {
562-
for (var si = 0; si < rpt._seriesMembers.length; si++) {
563-
var ps = rpt._seriesMembers[si].raw['patch-seq'] || '';
564-
if (ps.indexOf('0/') !== 0) patchCount++;
565-
}
566-
}
567-
var slabel = '[' + patchCount + ' patch' + (patchCount !== 1 ? 'es' : '') + ': ' + (rpt._seriesSummary || '') + ']';
568542
var safeSid = rpt._seriesId.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
569543
seriesHtml = '<a href="javascript:void(0)" onclick="toggleSeriesFold(\'' +
570544
escAttr(safeSid) + '\'); return false;" title="' + escAttr(stitle) +
571545
'" style="font-size:0.75rem;margin-right:0.3em;text-decoration:none">' +
572-
arrow + ' <small>' + escHtml(slabel) + '</small></a>';
546+
arrow + '</a>';
573547
}
574548

575549
var patchHtml = '';

resources/emails.edn

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,4 +1686,42 @@
16861686
:email/in-reply-to "<122@test.org>"
16871687
:email/references "<122@test.org>"
16881688
:email/body-text "Yes, my bug is a special case of the broader issue.\nSuperseded-by: <123@test.org>\n"}
1689+
1690+
;; =========================================================================
1691+
;; 125 — Cover letter for a series with no inner-bracket topic.
1692+
;; Each patch has a different `subdir:` colon-prefix in its
1693+
;; subject, so the per-message :topic parsed from the subject
1694+
;; diverges across patches. Threading via In-Reply-To must keep
1695+
;; all patches in the same series anyway.
1696+
;; =========================================================================
1697+
{:email/id "125"
1698+
:email/source "direct"
1699+
:email/message-id "<125@test.org>"
1700+
:email/subject "[PATCH 0/2] orgweb: several minor style fixes"
1701+
:email/from-address "kana@test.org"
1702+
:email/date-sent #inst "2026-03-04T10:00:00"
1703+
:email/ingested-at #inst "2026-03-04T10:00:00"
1704+
:email/body-text "Cover letter for a small style cleanup.\n"}
1705+
1706+
{:email/id "126"
1707+
:email/source "direct"
1708+
:email/message-id "<126@test.org>"
1709+
:email/subject "[PATCH 1/2] org-demo.html: use canonical aside"
1710+
:email/from-address "kana@test.org"
1711+
:email/date-sent #inst "2026-03-04T10:01:00"
1712+
:email/ingested-at #inst "2026-03-04T10:01:00"
1713+
:email/in-reply-to "<125@test.org>"
1714+
:email/references "<125@test.org>"
1715+
:email/body-text "Patch 1.\n\ndiff --git a/org-demo.html b/org-demo.html\n--- a/org-demo.html\n+++ b/org-demo.html\n@@ -1,3 +1,3 @@\n-old\n+new\n"}
1716+
1717+
{:email/id "127"
1718+
:email/source "direct"
1719+
:email/message-id "<127@test.org>"
1720+
:email/subject "[PATCH 2/2] css: fix horizontal scroll on mobile"
1721+
:email/from-address "kana@test.org"
1722+
:email/date-sent #inst "2026-03-04T10:02:00"
1723+
:email/ingested-at #inst "2026-03-04T10:02:00"
1724+
:email/in-reply-to "<125@test.org>"
1725+
:email/references "<125@test.org>"
1726+
:email/body-text "Patch 2.\n\ndiff --git a/style.css b/style.css\n--- a/style.css\n+++ b/style.css\n@@ -1,3 +1,3 @@\n-old\n+new\n"}
16891727
]

src/bark/series.clj

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,25 @@
4747
(not [?s :series/closed _])]
4848
db topic sender)))
4949

50+
(defn find-open-series-via-parents
51+
"Find an open series among parent reports' :report/series, restricted
52+
to series with the given sender and expected total. Threading is the
53+
reliable signal for series membership: the per-message :topic parsed
54+
from the subject can vary across patches when each patch carries its
55+
own `subdir:` colon-prefix, but threading via In-Reply-To/References
56+
consistently links every patch back to the cover letter (or to a
57+
sibling already in the series)."
58+
[db parent-report-eids sender total]
59+
(when (seq parent-report-eids)
60+
(d/q '[:find ?s .
61+
:in $ [?r ...] ?sender ?total
62+
:where
63+
[?r :report/series ?s]
64+
[?s :series/sender ?sender]
65+
[?s :series/expected ?total]
66+
(not [?s :series/closed _])]
67+
db parent-report-eids sender total)))
68+
5069
(defn create-series! [conn topic sender total]
5170
(let [sid (next-series-id (d/db conn) topic sender total)]
5271
(d/transact! conn [{:series/id sid
@@ -140,7 +159,10 @@
140159
(log/info "Auto-closed series"
141160
(pr-str (:series/id (d/pull (d/db conn) [:series/id] sid)))
142161
"(superseded)")))
143-
(let [series-eid (or (find-open-series (d/db conn) topic from-addr m)
162+
(let [series-eid (or (when (pos? n)
163+
(find-open-series-via-parents
164+
(d/db conn) parent-report-eids from-addr m))
165+
(find-open-series (d/db conn) topic from-addr m)
144166
(let [sid (create-series! conn topic from-addr m)]
145167
(log/info "New series:"
146168
(pr-str (series-id topic from-addr m))

test/bark/digest_test.clj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,26 @@
451451
(is (some? (:report/series r39)))
452452
(is (= "1/3" (:report/patch-seq r39)))))
453453

454+
;; --- Series with diverging per-patch :topic (emails 125-127) ---
455+
(testing "Series held together by threading despite divergent topics"
456+
;; Cover letter and patches each have a different `subdir:`
457+
;; colon-prefix, so the per-message :topic differs across
458+
;; reports. Threading via In-Reply-To must keep all patches
459+
;; in the cover letter's series.
460+
(let [s (get-series-by-id db "orgweb|kana@test.org|2")]
461+
(is (some? (:series/id s)))
462+
(is (= 2 (:series/expected s)))
463+
(is (= "<125@test.org>" (get-in s [:series/cover-letter :email/message-id])))
464+
(is (= 2 (series-patch-count db "orgweb|kana@test.org|2"))))
465+
(let [r126 (get-report db "<126@test.org>")
466+
r127 (get-report db "<127@test.org>")]
467+
(is (some? (:report/series r126)))
468+
(is (some? (:report/series r127)))
469+
(is (= "orgweb|kana@test.org|2"
470+
(:series/id (:report/series r126))))
471+
(is (= "orgweb|kana@test.org|2"
472+
(:series/id (:report/series r127))))))
473+
454474
;; --- Email 40 patch related to bug ---
455475
(testing "Email 40 patch related to bug"
456476
(let [patch (get-report db "<40@test.org>")

0 commit comments

Comments
 (0)