feat: link each changelog entry to its PR and commit (#11)
Like Immich's and RomM's release notes: every changelog entry now links to its pull request and its commit, in `CHANGELOG.md` and in the release notes on Gitea: ``` - Search with fzf's scoring and query syntax ([#11](…/pulls/11)) ([65dc2d7](…/commit/65dc2d7…)) ``` - `cliff.toml`: the entry template adds the short commit hash as a link; a postprocessor turns the squash commit's `(#N)` into a link to the PR. - The app shows release notes as text (`U`, and the status pane's changelog to come), so `Release.Notes()` turns Markdown links back into their text: `Search (#11) (65dc2d7)`. Checked with `git cliff --unreleased` on main: every entry since v0.1.0 gets both links. Test for the link stripping. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com> Reviewed-on: #11
This commit was merged in pull request #11.
This commit is contained in:
1 parent
1c8d69d957
commit
56d3d25c9c
19 files changed
+396
-92
No files matched your search
@@ -19,6 +19,7 @@ import (
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/provider"
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/provider/fake"
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/ui/keys"
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/ui/panes"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
@@ -57,7 +58,7 @@ func newDriverOpts(t *testing.T, opts Options, providers ...provider.Provider) *
|
||||
m := New(providers, opts)
|
||||
m.detail.Now = func() time.Time { return time.Date(2026, 10, 1, 0, 0, 0, 0, time.UTC) }
|
||||
d := &driver{t: t, m: m}
|
||||
d.send(tea.WindowSizeMsg{Width: 100, Height: 30})
|
||||
d.send(tea.WindowSizeMsg{Width: 100, Height: 33}) // 30 for the main panes, 3 for status
|
||||
d.run(m.Init())
|
||||
return d
|
||||
}
|
||||
@@ -1189,3 +1190,49 @@ func TestDetailsFollowFocus(t *testing.T) {
|
||||
t.Errorf("value not shown:\n%s", d.screen())
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatusPane(t *testing.T) {
|
||||
t.Parallel()
|
||||
var opened []string
|
||||
d := newDriverOpts(t, Options{Version: "0.1.0", ConfigFiles: []string{"/cfg/config.yaml"}, StatePath: "/state/state.json",
|
||||
OpenURL: func(u string) error { opened = append(opened, u); return nil }},
|
||||
fake.Azure(0), signedOut{fake.Azure(0)})
|
||||
if !strings.Contains(d.screen(), "2 accounts · 1 need sign-in") {
|
||||
t.Errorf("status line:\n%s", d.screen())
|
||||
}
|
||||
d.keys("0")
|
||||
if d.m.focus != paneStatus {
|
||||
t.Fatalf("focus %v", d.m.focus)
|
||||
}
|
||||
scr := d.screen()
|
||||
for _, want := range []string{"version v0.1.0", "GPL-3.0-or-later", "Azure · 2 subscriptions", "Azure · admin · sign-in required",
|
||||
"/cfg/config.yaml", "/state/state.json", "lazysecrets/…/docs"} {
|
||||
if !strings.Contains(scr, want) {
|
||||
t.Errorf("missing %q:\n%s", want, scr)
|
||||
}
|
||||
}
|
||||
// Into its rows: L signs in to the failing account, y copies a path,
|
||||
// o opens a link.
|
||||
d.keys("enter")
|
||||
if d.m.focus != paneDetail {
|
||||
t.Fatalf("enter: focus %v", d.m.focus)
|
||||
}
|
||||
d.m.fields.SelectWhere(func(f panes.Field) bool { return f.Provider == "Azure:admin@contoso.com/t1" })
|
||||
if a := d.m.loginFor(); a == nil || a.Account != "Azure · admin" {
|
||||
t.Errorf("L signs in to %+v", a)
|
||||
}
|
||||
d.m.fields.SelectWhere(func(f panes.Field) bool { return f.Label == "config" })
|
||||
d.keys("y")
|
||||
if got := d.clip().content; got != "/cfg/config.yaml" {
|
||||
t.Errorf("y copied %q", got)
|
||||
}
|
||||
d.m.fields.SelectWhere(func(f panes.Field) bool { return f.Label == "docs" })
|
||||
d.keys("o")
|
||||
if len(opened) != 1 || !strings.HasSuffix(opened[0], "/src/branch/main/docs") {
|
||||
t.Errorf("o opened %q", opened)
|
||||
}
|
||||
d.keys("shift+tab")
|
||||
if d.m.focus != paneStatus {
|
||||
t.Errorf("back to %v", d.m.focus)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user