From c619faee966d7bc675aeee1f3ee5dd8f66adf616 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Tue, 1 Sep 2026 14:11:38 -0400 Subject: [PATCH 1/2] tui: Sort patches in a series based on patch number. When pressing space to expand a series, the patches are listed in order based on their patch ID. This does not always align with the ordering of the patches in the series. This can make it difficult to view patches in order or notice on large series that patches are missing (usually due to patchwork errors). This commit sorts the patches based on patch number. This solves the issues stated above. Signed-off-by: Mark Michelson Signed-off-by: Ilya Maximets --- tui/data.go | 4 +++ tui/data_test.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/tui/data.go b/tui/data.go index 985dd41..546e607 100644 --- a/tui/data.go +++ b/tui/data.go @@ -427,6 +427,10 @@ func seriesToRow( }, } + sort.SliceStable(patches, func(i, j int) bool { + return patchNumber(patches[i].Name) < patchNumber(patches[j].Name) + }) + row.SubRows = make([][]string, len(patches)) row.SubRowStyles = make([]RowStyle, len(patches)) row.SubRowFetched = make([]bool, len(patches)) diff --git a/tui/data_test.go b/tui/data_test.go index 6bcc5fd..9ed2da7 100644 --- a/tui/data_test.go +++ b/tui/data_test.go @@ -1222,4 +1222,79 @@ func TestSeriesToRow_FetchedStatus(t *testing.T) { } } +func TestSeriesToRow_SubRowsSortedByPatchNumber(t *testing.T) { + d := time.Now().UTC().Format("2006-01-02T15:04:05") + tests := []struct { + name string + listPrefix string + patches []db.PatchRow + want []string + }{ + { + "out of order", + "", + []db.PatchRow{ + {ID: 103, Name: "[PATCH 3/4] third", Date: d, State: "new"}, + {ID: 101, Name: "[PATCH 1/4] first", Date: d, State: "new"}, + {ID: 104, Name: "[PATCH 4/4] fourth", Date: d, State: "new"}, + {ID: 102, Name: "[PATCH 2/4] second", Date: d, State: "new"}, + }, + []string{"101", "102", "103", "104"}, + }, + { + "already sorted", + "", + []db.PatchRow{ + {ID: 201, Name: "[PATCH 1/3] alpha", Date: d, State: "new"}, + {ID: 202, Name: "[PATCH 2/3] beta", Date: d, State: "new"}, + {ID: 203, Name: "[PATCH 3/3] gamma", Date: d, State: "new"}, + }, + []string{"201", "202", "203"}, + }, + { + // IDs are assigned in the opposite order of the patch + // numbers, so sorting by ID would produce the wrong result. + "IDs don't match patch number order", + "", + []db.PatchRow{ + {ID: 303, Name: "[PATCH 1/3] a", Date: d, State: "new"}, + {ID: 302, Name: "[PATCH 2/3] b", Date: d, State: "new"}, + {ID: 301, Name: "[PATCH 3/3] c", Date: d, State: "new"}, + }, + []string{"303", "302", "301"}, + }, + { + "no position marker preserves original order", + "", + []db.PatchRow{ + {ID: 402, Name: "second patch", Date: d, State: "new"}, + {ID: 401, Name: "first patch", Date: d, State: "new"}, + }, + []string{"402", "401"}, + }, + { + "with list prefix", + "mylist", + []db.PatchRow{ + {ID: 502, Name: "[mylist,2/2] second", Date: d, State: "new"}, + {ID: 501, Name: "[mylist,1/2] first", Date: d, State: "new"}, + }, + []string{"501", "502"}, + }, + } + for _, tt := range tests { + s := db.SeriesRow{ + Name: tt.name, Date: d, TotalPatches: len(tt.patches), + } + row := seriesToRow(s, tt.patches, tt.listPrefix, + nil, nil, 0, nil, nil, nil, nil) + for i, want := range tt.want { + if i < len(row.SubRows) && row.SubRows[i][ColID] != want { + t.Errorf("%s: SubRow[%d] ID = %q, want %q", + tt.name, i, row.SubRows[i][ColID], want) + } + } + } +} + func boolPtr(v bool) *bool { return &v } From 516fb671495dc909501eb9e6cd8edc6cf3eb478c Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Fri, 25 Sep 2026 16:47:37 +0200 Subject: [PATCH 2/2] AUTHORS: Add Mark Michelson. Signed-off-by: Ilya Maximets --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index d2ca215..bc456c5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,3 +6,4 @@ # Please keep the list sorted. Ilya Maximets +Mark Michelson