detached 60b8e93

fix lint in browser launch feature

commit
60b8e9394522f033fa739465a340287b169ba8e0
author
brice · · 2026-04-14 16:33 UTC
parent
85687b3
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
6 files · +42 -54
M internal/infrastructure/desktop/browser_launch_relay.go +15 -13
@@ -20,6 +20,8 @@ const browserLaunchSocketName = "browser-launch.sock"
2020
2121 const browserLaunchIOTimeout = 50 * time.Millisecond
2222
23+const browserLaunchDirPerm = 0o700
24+
2325 type browserLaunchRelay struct {
2426 xdg port.XDGPaths
2527 }
@@ -64,7 +66,7 @@ func (r *browserLaunchRelay) DeliverOpenFreshWindow(ctx context.Context, url str
6466 }
6567 return false, err
6668 }
67- defer conn.Close()
69+ defer func() { _ = conn.Close() }()
6870
6971 if err := setBrowserLaunchConnDeadline(ctx, conn); err != nil {
7072 return false, err
@@ -80,17 +82,17 @@ func (r *browserLaunchRelay) DeliverOpenFreshWindow(ctx context.Context, url str
8082 var response browserLaunchResponse
8183 decoder := json.NewDecoder(conn)
8284 for {
83- if err := decoder.Decode(&response); err != nil {
84- if isBrowserLaunchReadTimeout(err) {
85+ if decodeErr := decoder.Decode(&response); decodeErr != nil {
86+ if isBrowserLaunchReadTimeout(decodeErr) {
8587 if ctxErr := ctx.Err(); ctxErr != nil {
8688 return false, ctxErr
8789 }
88- if err := setBrowserLaunchConnDeadline(ctx, conn); err != nil {
89- return false, err
90+ if deadlineErr := setBrowserLaunchConnDeadline(ctx, conn); deadlineErr != nil {
91+ return false, deadlineErr
9092 }
9193 continue
9294 }
93- return false, err
95+ return false, decodeErr
9496 }
9597 break
9698 }
@@ -125,11 +127,11 @@ func (r *browserLaunchRelay) Listen(ctx context.Context, opener port.BrowserWind
125127 return nil, err
126128 }
127129
128- if err := os.MkdirAll(filepath.Dir(socketPath), 0o700); err != nil {
129- return nil, fmt.Errorf("create browser launch dir: %w", err)
130+ if mkdirErr := os.MkdirAll(filepath.Dir(socketPath), browserLaunchDirPerm); mkdirErr != nil {
131+ return nil, fmt.Errorf("create browser launch dir: %w", mkdirErr)
130132 }
131- if err := os.Remove(socketPath); err != nil && !os.IsNotExist(err) {
132- return nil, fmt.Errorf("remove stale browser launch socket: %w", err)
133+ if removeErr := os.Remove(socketPath); removeErr != nil && !os.IsNotExist(removeErr) {
134+ return nil, fmt.Errorf("remove stale browser launch socket: %w", removeErr)
133135 }
134136
135137 listener, err := net.ListenUnix("unix", &net.UnixAddr{Name: socketPath, Net: "unix"})
@@ -179,7 +181,7 @@ func (l *browserLaunchRelayListener) Close() error {
179181 }
180182
181183 func (l *browserLaunchRelayListener) serve(ctx context.Context, opener port.BrowserWindowOpener) {
182- defer l.Close()
184+ defer func() { _ = l.Close() }()
183185
184186 for {
185187 if err := l.listener.SetDeadline(time.Now().Add(browserLaunchIOTimeout)); err != nil {
@@ -204,8 +206,8 @@ func (l *browserLaunchRelayListener) serve(ctx context.Context, opener port.Brow
204206 }
205207 }
206208
207-func (l *browserLaunchRelayListener) handleConnection(ctx context.Context, conn *net.UnixConn, opener port.BrowserWindowOpener) {
208- defer conn.Close()
209+func (*browserLaunchRelayListener) handleConnection(ctx context.Context, conn *net.UnixConn, opener port.BrowserWindowOpener) {
210+ defer func() { _ = conn.Close() }()
209211
210212 var request browserLaunchRequest
211213 if err := json.NewDecoder(conn).Decode(&request); err != nil {
@@ -20,6 +20,8 @@ const browserLaunchSocketName = "browser-launch.sock"
20 20
21 const browserLaunchIOTimeout = 50 * time.Millisecond21 const browserLaunchIOTimeout = 50 * time.Millisecond
22 22
23+const browserLaunchDirPerm = 0o700
24+
23 type browserLaunchRelay struct {25 type browserLaunchRelay struct {
24 xdg port.XDGPaths26 xdg port.XDGPaths
25 }27 }
@@ -64,7 +66,7 @@ func (r *browserLaunchRelay) DeliverOpenFreshWindow(ctx context.Context, url str
64 }66 }
65 return false, err67 return false, err
66 }68 }
67- defer conn.Close()69+ defer func() { _ = conn.Close() }()
68 70
69 if err := setBrowserLaunchConnDeadline(ctx, conn); err != nil {71 if err := setBrowserLaunchConnDeadline(ctx, conn); err != nil {
70 return false, err72 return false, err
@@ -80,17 +82,17 @@ func (r *browserLaunchRelay) DeliverOpenFreshWindow(ctx context.Context, url str
80 var response browserLaunchResponse82 var response browserLaunchResponse
81 decoder := json.NewDecoder(conn)83 decoder := json.NewDecoder(conn)
82 for {84 for {
83- if err := decoder.Decode(&response); err != nil {85+ if decodeErr := decoder.Decode(&response); decodeErr != nil {
84- if isBrowserLaunchReadTimeout(err) {86+ if isBrowserLaunchReadTimeout(decodeErr) {
85 if ctxErr := ctx.Err(); ctxErr != nil {87 if ctxErr := ctx.Err(); ctxErr != nil {
86 return false, ctxErr88 return false, ctxErr
87 }89 }
88- if err := setBrowserLaunchConnDeadline(ctx, conn); err != nil {90+ if deadlineErr := setBrowserLaunchConnDeadline(ctx, conn); deadlineErr != nil {
89- return false, err91+ return false, deadlineErr
90 }92 }
91 continue93 continue
92 }94 }
93- return false, err95+ return false, decodeErr
94 }96 }
95 break97 break
96 }98 }
@@ -125,11 +127,11 @@ func (r *browserLaunchRelay) Listen(ctx context.Context, opener port.BrowserWind
125 return nil, err127 return nil, err
126 }128 }
127 129
128- if err := os.MkdirAll(filepath.Dir(socketPath), 0o700); err != nil {130+ if mkdirErr := os.MkdirAll(filepath.Dir(socketPath), browserLaunchDirPerm); mkdirErr != nil {
129- return nil, fmt.Errorf("create browser launch dir: %w", err)131+ return nil, fmt.Errorf("create browser launch dir: %w", mkdirErr)
130 }132 }
131- if err := os.Remove(socketPath); err != nil && !os.IsNotExist(err) {133+ if removeErr := os.Remove(socketPath); removeErr != nil && !os.IsNotExist(removeErr) {
132- return nil, fmt.Errorf("remove stale browser launch socket: %w", err)134+ return nil, fmt.Errorf("remove stale browser launch socket: %w", removeErr)
133 }135 }
134 136
135 listener, err := net.ListenUnix("unix", &net.UnixAddr{Name: socketPath, Net: "unix"})137 listener, err := net.ListenUnix("unix", &net.UnixAddr{Name: socketPath, Net: "unix"})
@@ -179,7 +181,7 @@ func (l *browserLaunchRelayListener) Close() error {
179 }181 }
180 182
181 func (l *browserLaunchRelayListener) serve(ctx context.Context, opener port.BrowserWindowOpener) {183 func (l *browserLaunchRelayListener) serve(ctx context.Context, opener port.BrowserWindowOpener) {
182- defer l.Close()184+ defer func() { _ = l.Close() }()
183 185
184 for {186 for {
185 if err := l.listener.SetDeadline(time.Now().Add(browserLaunchIOTimeout)); err != nil {187 if err := l.listener.SetDeadline(time.Now().Add(browserLaunchIOTimeout)); err != nil {
@@ -204,8 +206,8 @@ func (l *browserLaunchRelayListener) serve(ctx context.Context, opener port.Brow
204 }206 }
205 }207 }
206 208
207-func (l *browserLaunchRelayListener) handleConnection(ctx context.Context, conn *net.UnixConn, opener port.BrowserWindowOpener) {209+func (*browserLaunchRelayListener) handleConnection(ctx context.Context, conn *net.UnixConn, opener port.BrowserWindowOpener) {
208- defer conn.Close()210+ defer func() { _ = conn.Close() }()
209 211
210 var request browserLaunchRequest212 var request browserLaunchRequest
211 if err := json.NewDecoder(conn).Decode(&request); err != nil {213 if err := json.NewDecoder(conn).Decode(&request); err != nil {
M internal/infrastructure/desktop/browser_launch_relay_test.go +16 -16
@@ -20,16 +20,16 @@ type testXDGPaths struct {
2020
2121 var _ port.XDGPaths = testXDGPaths{}
2222
23-func (x testXDGPaths) ConfigDir() (string, error) { return "", nil }
24-func (x testXDGPaths) DataDir() (string, error) { return "", nil }
25-func (x testXDGPaths) StateDir() (string, error) { return x.stateDir, nil }
26-func (x testXDGPaths) RuntimeDir() (string, error) { return x.runtimeDir, nil }
27-func (x testXDGPaths) CacheDir() (string, error) { return "", nil }
28-func (x testXDGPaths) FilterJSONDir() (string, error) { return "", nil }
29-func (x testXDGPaths) FilterStoreDir() (string, error) { return "", nil }
30-func (x testXDGPaths) FilterCacheDir() (string, error) { return "", nil }
31-func (x testXDGPaths) ManDir() (string, error) { return "", nil }
32-func (x testXDGPaths) DownloadDir() (string, error) { return "", nil }
23+func (testXDGPaths) ConfigDir() (string, error) { return "", nil }
24+func (testXDGPaths) DataDir() (string, error) { return "", nil }
25+func (x testXDGPaths) StateDir() (string, error) { return x.stateDir, nil }
26+func (x testXDGPaths) RuntimeDir() (string, error) { return x.runtimeDir, nil }
27+func (testXDGPaths) CacheDir() (string, error) { return "", nil }
28+func (testXDGPaths) FilterJSONDir() (string, error) { return "", nil }
29+func (testXDGPaths) FilterStoreDir() (string, error) { return "", nil }
30+func (testXDGPaths) FilterCacheDir() (string, error) { return "", nil }
31+func (testXDGPaths) ManDir() (string, error) { return "", nil }
32+func (testXDGPaths) DownloadDir() (string, error) { return "", nil }
3333
3434 type browserWindowOpenerFunc func(context.Context, string) error
3535
@@ -84,7 +84,7 @@ func TestBrowserLaunchRelay_DeliverOpenFreshWindow_RoundTrip(t *testing.T) {
8484 ctx, cancel := context.WithCancel(context.Background())
8585 defer cancel()
8686
87- closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(ctx context.Context, url string) error {
87+ closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(_ context.Context, url string) error {
8888 received <- url
8989 return nil
9090 }))
@@ -114,7 +114,7 @@ func TestBrowserLaunchRelay_UsesStateFallbackWhenRuntimeDirMissing(t *testing.T)
114114 ctx, cancel := context.WithCancel(context.Background())
115115 defer cancel()
116116
117- closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(ctx context.Context, url string) error {
117+ closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(_ context.Context, url string) error {
118118 received <- url
119119 return nil
120120 }))
@@ -145,7 +145,7 @@ func TestBrowserLaunchRelay_RejectsMalformedPayloads(t *testing.T) {
145145 ctx, cancel := context.WithCancel(context.Background())
146146 defer cancel()
147147
148- closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(ctx context.Context, url string) error {
148+ closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(_ context.Context, url string) error {
149149 received <- url
150150 return nil
151151 }))
@@ -227,8 +227,8 @@ func TestBrowserLaunchRelay_DeliverOpenFreshWindow_RespectsResponseReadTimeout(t
227227 ready := make(chan struct{})
228228 go func() {
229229 close(ready)
230- conn, err := listener.AcceptUnix()
231- if err != nil {
230+ conn, acceptErr := listener.AcceptUnix()
231+ if acceptErr != nil {
232232 return
233233 }
234234 defer conn.Close()
@@ -242,6 +242,6 @@ func TestBrowserLaunchRelay_DeliverOpenFreshWindow_RespectsResponseReadTimeout(t
242242
243243 delivered, err := relay.DeliverOpenFreshWindow(ctx, "https://example.com/slow")
244244 require.Error(t, err)
245- assert.ErrorIs(t, err, context.DeadlineExceeded)
245+ require.ErrorIs(t, err, context.DeadlineExceeded)
246246 assert.False(t, delivered)
247247 }
@@ -20,16 +20,16 @@ type testXDGPaths struct {
20 20
21 var _ port.XDGPaths = testXDGPaths{}21 var _ port.XDGPaths = testXDGPaths{}
22 22
23-func (x testXDGPaths) ConfigDir() (string, error) { return "", nil }23+func (testXDGPaths) ConfigDir() (string, error) { return "", nil }
24-func (x testXDGPaths) DataDir() (string, error) { return "", nil }24+func (testXDGPaths) DataDir() (string, error) { return "", nil }
25-func (x testXDGPaths) StateDir() (string, error) { return x.stateDir, nil }25+func (x testXDGPaths) StateDir() (string, error) { return x.stateDir, nil }
26-func (x testXDGPaths) RuntimeDir() (string, error) { return x.runtimeDir, nil }26+func (x testXDGPaths) RuntimeDir() (string, error) { return x.runtimeDir, nil }
27-func (x testXDGPaths) CacheDir() (string, error) { return "", nil }27+func (testXDGPaths) CacheDir() (string, error) { return "", nil }
28-func (x testXDGPaths) FilterJSONDir() (string, error) { return "", nil }28+func (testXDGPaths) FilterJSONDir() (string, error) { return "", nil }
29-func (x testXDGPaths) FilterStoreDir() (string, error) { return "", nil }29+func (testXDGPaths) FilterStoreDir() (string, error) { return "", nil }
30-func (x testXDGPaths) FilterCacheDir() (string, error) { return "", nil }30+func (testXDGPaths) FilterCacheDir() (string, error) { return "", nil }
31-func (x testXDGPaths) ManDir() (string, error) { return "", nil }31+func (testXDGPaths) ManDir() (string, error) { return "", nil }
32-func (x testXDGPaths) DownloadDir() (string, error) { return "", nil }32+func (testXDGPaths) DownloadDir() (string, error) { return "", nil }
33 33
34 type browserWindowOpenerFunc func(context.Context, string) error34 type browserWindowOpenerFunc func(context.Context, string) error
35 35
@@ -84,7 +84,7 @@ func TestBrowserLaunchRelay_DeliverOpenFreshWindow_RoundTrip(t *testing.T) {
84 ctx, cancel := context.WithCancel(context.Background())84 ctx, cancel := context.WithCancel(context.Background())
85 defer cancel()85 defer cancel()
86 86
87- closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(ctx context.Context, url string) error {87+ closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(_ context.Context, url string) error {
88 received <- url88 received <- url
89 return nil89 return nil
90 }))90 }))
@@ -114,7 +114,7 @@ func TestBrowserLaunchRelay_UsesStateFallbackWhenRuntimeDirMissing(t *testing.T)
114 ctx, cancel := context.WithCancel(context.Background())114 ctx, cancel := context.WithCancel(context.Background())
115 defer cancel()115 defer cancel()
116 116
117- closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(ctx context.Context, url string) error {117+ closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(_ context.Context, url string) error {
118 received <- url118 received <- url
119 return nil119 return nil
120 }))120 }))
@@ -145,7 +145,7 @@ func TestBrowserLaunchRelay_RejectsMalformedPayloads(t *testing.T) {
145 ctx, cancel := context.WithCancel(context.Background())145 ctx, cancel := context.WithCancel(context.Background())
146 defer cancel()146 defer cancel()
147 147
148- closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(ctx context.Context, url string) error {148+ closer, err := relay.Listen(ctx, browserWindowOpenerFunc(func(_ context.Context, url string) error {
149 received <- url149 received <- url
150 return nil150 return nil
151 }))151 }))
@@ -227,8 +227,8 @@ func TestBrowserLaunchRelay_DeliverOpenFreshWindow_RespectsResponseReadTimeout(t
227 ready := make(chan struct{})227 ready := make(chan struct{})
228 go func() {228 go func() {
229 close(ready)229 close(ready)
230- conn, err := listener.AcceptUnix()230+ conn, acceptErr := listener.AcceptUnix()
231- if err != nil {231+ if acceptErr != nil {
232 return232 return
233 }233 }
234 defer conn.Close()234 defer conn.Close()
@@ -242,6 +242,6 @@ func TestBrowserLaunchRelay_DeliverOpenFreshWindow_RespectsResponseReadTimeout(t
242 242
243 delivered, err := relay.DeliverOpenFreshWindow(ctx, "https://example.com/slow")243 delivered, err := relay.DeliverOpenFreshWindow(ctx, "https://example.com/slow")
244 require.Error(t, err)244 require.Error(t, err)
245- assert.ErrorIs(t, err, context.DeadlineExceeded)245+ require.ErrorIs(t, err, context.DeadlineExceeded)
246 assert.False(t, delivered)246 assert.False(t, delivered)
247 }247 }
M internal/infrastructure/desktop/browser_launcher_test.go +2 -2
@@ -23,7 +23,7 @@ func TestBrowserLauncher_LaunchURL_ReturnsWithoutSpawningWhenRelayDelivers(t *te
2323 t.Fatal("expected executable path resolution to be skipped")
2424 return "", nil
2525 }
26- launcher.startDetachedProcess = func(cmd *exec.Cmd) error {
26+ launcher.startDetachedProcess = func(_ *exec.Cmd) error {
2727 spawned = true
2828 return nil
2929 }
@@ -65,7 +65,7 @@ func TestBrowserLauncher_LaunchURL_ReportsRelayErrorWhenDelivered(t *testing.T)
6565 t.Fatal("expected executable path resolution to be skipped")
6666 return "", nil
6767 }
68- launcher.startDetachedProcess = func(cmd *exec.Cmd) error {
68+ launcher.startDetachedProcess = func(_ *exec.Cmd) error {
6969 t.Fatal("expected launch to stop after relay delivery")
7070 return nil
7171 }
@@ -23,7 +23,7 @@ func TestBrowserLauncher_LaunchURL_ReturnsWithoutSpawningWhenRelayDelivers(t *te
23 t.Fatal("expected executable path resolution to be skipped")23 t.Fatal("expected executable path resolution to be skipped")
24 return "", nil24 return "", nil
25 }25 }
26- launcher.startDetachedProcess = func(cmd *exec.Cmd) error {26+ launcher.startDetachedProcess = func(_ *exec.Cmd) error {
27 spawned = true27 spawned = true
28 return nil28 return nil
29 }29 }
@@ -65,7 +65,7 @@ func TestBrowserLauncher_LaunchURL_ReportsRelayErrorWhenDelivered(t *testing.T)
65 t.Fatal("expected executable path resolution to be skipped")65 t.Fatal("expected executable path resolution to be skipped")
66 return "", nil66 return "", nil
67 }67 }
68- launcher.startDetachedProcess = func(cmd *exec.Cmd) error {68+ launcher.startDetachedProcess = func(_ *exec.Cmd) error {
69 t.Fatal("expected launch to stop after relay delivery")69 t.Fatal("expected launch to stop after relay delivery")
70 return nil70 return nil
71 }71 }
M internal/infrastructure/xdg/adapter_test.go +1 -1
@@ -55,7 +55,7 @@ func TestAdapter_RuntimeDir(t *testing.T) {
5555 dir, err := adapter.RuntimeDir()
5656
5757 require.NoError(t, err)
58- assert.Equal(t, filepath.Join("/tmp/dumber-state", "dumber", "runtime"), dir)
58+ assert.Equal(t, "/tmp/dumber-state/dumber/runtime", dir)
5959 })
6060 }
6161
@@ -55,7 +55,7 @@ func TestAdapter_RuntimeDir(t *testing.T) {
55 dir, err := adapter.RuntimeDir()55 dir, err := adapter.RuntimeDir()
56 56
57 require.NoError(t, err)57 require.NoError(t, err)
58- assert.Equal(t, filepath.Join("/tmp/dumber-state", "dumber", "runtime"), dir)58+ assert.Equal(t, "/tmp/dumber-state/dumber/runtime", dir)
59 })59 })
60 }60 }
61 61
M internal/ui/app.go +8 -8
@@ -534,29 +534,29 @@ func (a *App) openFreshWindow(ctx context.Context, url string) error {
534534 a.tabCreationWindow = nil
535535 }()
536536
537- tab, err := a.tabCoord.Create(ctx, url)
538- if err != nil {
537+ createdTab, createErr := a.tabCoord.Create(ctx, url)
538+ if createErr != nil {
539539 a.removeBrowserWindow(created.id)
540540 if created.mainWindow != nil {
541541 created.mainWindow.Destroy()
542542 }
543- return err
543+ return createErr
544544 }
545- if a.workspaceViews[tab.ID] == nil {
545+ if a.workspaceViews[createdTab.ID] == nil {
546546 if a.tabs != nil {
547- a.tabs.Remove(tab.ID)
547+ a.tabs.Remove(createdTab.ID)
548548 }
549549 if a.mainWindow != nil && a.mainWindow.TabBar() != nil {
550- a.mainWindow.TabBar().RemoveTab(tab.ID)
550+ a.mainWindow.TabBar().RemoveTab(createdTab.ID)
551551 a.mainWindow.TabBar().SetActive(a.tabs.ActiveTabID)
552552 }
553553 a.removeBrowserWindow(created.id)
554554 if created.mainWindow != nil {
555555 created.mainWindow.Destroy()
556556 }
557- return fmt.Errorf("workspace view not created for tab %s", tab.ID)
557+ return fmt.Errorf("workspace view not created for tab %s", createdTab.ID)
558558 }
559- a.setBrowserWindowForTab(tab.ID, created)
559+ a.setBrowserWindowForTab(createdTab.ID, created)
560560 if created.mainWindow != nil {
561561 created.mainWindow.Show()
562562 }
@@ -534,29 +534,29 @@ func (a *App) openFreshWindow(ctx context.Context, url string) error {
534 a.tabCreationWindow = nil534 a.tabCreationWindow = nil
535 }()535 }()
536 536
537- tab, err := a.tabCoord.Create(ctx, url)537+ createdTab, createErr := a.tabCoord.Create(ctx, url)
538- if err != nil {538+ if createErr != nil {
539 a.removeBrowserWindow(created.id)539 a.removeBrowserWindow(created.id)
540 if created.mainWindow != nil {540 if created.mainWindow != nil {
541 created.mainWindow.Destroy()541 created.mainWindow.Destroy()
542 }542 }
543- return err543+ return createErr
544 }544 }
545- if a.workspaceViews[tab.ID] == nil {545+ if a.workspaceViews[createdTab.ID] == nil {
546 if a.tabs != nil {546 if a.tabs != nil {
547- a.tabs.Remove(tab.ID)547+ a.tabs.Remove(createdTab.ID)
548 }548 }
549 if a.mainWindow != nil && a.mainWindow.TabBar() != nil {549 if a.mainWindow != nil && a.mainWindow.TabBar() != nil {
550- a.mainWindow.TabBar().RemoveTab(tab.ID)550+ a.mainWindow.TabBar().RemoveTab(createdTab.ID)
551 a.mainWindow.TabBar().SetActive(a.tabs.ActiveTabID)551 a.mainWindow.TabBar().SetActive(a.tabs.ActiveTabID)
552 }552 }
553 a.removeBrowserWindow(created.id)553 a.removeBrowserWindow(created.id)
554 if created.mainWindow != nil {554 if created.mainWindow != nil {
555 created.mainWindow.Destroy()555 created.mainWindow.Destroy()
556 }556 }
557- return fmt.Errorf("workspace view not created for tab %s", tab.ID)557+ return fmt.Errorf("workspace view not created for tab %s", createdTab.ID)
558 }558 }
559- a.setBrowserWindowForTab(tab.ID, created)559+ a.setBrowserWindowForTab(createdTab.ID, created)
560 if created.mainWindow != nil {560 if created.mainWindow != nil {
561 created.mainWindow.Show()561 created.mainWindow.Show()
562 }562 }
M internal/ui/app_browser_launch_test.go +0 -14
@@ -12,9 +12,7 @@ import (
1212 "github.com/bnema/dumber/internal/domain/entity"
1313 "github.com/bnema/dumber/internal/ui/component"
1414 "github.com/bnema/dumber/internal/ui/coordinator"
15- "github.com/bnema/dumber/internal/ui/layout"
1615 "github.com/bnema/dumber/internal/ui/window"
17- "github.com/bnema/puregotk/v4/gtk"
1816 )
1917
2018 type testBrowserLaunchRelay struct {
@@ -93,18 +91,6 @@ func windowTabBarActiveID(t *testing.T, mw *window.MainWindow) entity.TabID {
9391 return mw.TabBar().ActiveTabID()
9492 }
9593
96-type fakeWidgetFactory struct{}
97-
98-func (fakeWidgetFactory) NewPaned(layout.Orientation) layout.PanedWidget { return nil }
99-func (fakeWidgetFactory) NewBox(layout.Orientation, int) layout.BoxWidget { return nil }
100-func (fakeWidgetFactory) NewOverlay() layout.OverlayWidget { return nil }
101-func (fakeWidgetFactory) NewLabel(string) layout.LabelWidget { return nil }
102-func (fakeWidgetFactory) NewButton() layout.ButtonWidget { return nil }
103-func (fakeWidgetFactory) NewImage() layout.ImageWidget { return nil }
104-func (fakeWidgetFactory) NewProgressBar() layout.ProgressBarWidget { return nil }
105-func (fakeWidgetFactory) NewSpinner() layout.SpinnerWidget { return nil }
106-func (fakeWidgetFactory) WrapWidget(*gtk.Widget) layout.Widget { return nil }
107-
10894 func TestApp_FinalizeActivationStartsBrowserLaunchRelayOnceAndClosesOnShutdown(t *testing.T) {
10995 relay := &testBrowserLaunchRelay{closer: &testCloser{}}
11096 deps := &Dependencies{}
@@ -12,9 +12,7 @@ import (
12 "github.com/bnema/dumber/internal/domain/entity"12 "github.com/bnema/dumber/internal/domain/entity"
13 "github.com/bnema/dumber/internal/ui/component"13 "github.com/bnema/dumber/internal/ui/component"
14 "github.com/bnema/dumber/internal/ui/coordinator"14 "github.com/bnema/dumber/internal/ui/coordinator"
15- "github.com/bnema/dumber/internal/ui/layout"
16 "github.com/bnema/dumber/internal/ui/window"15 "github.com/bnema/dumber/internal/ui/window"
17- "github.com/bnema/puregotk/v4/gtk"
18 )16 )
19 17
20 type testBrowserLaunchRelay struct {18 type testBrowserLaunchRelay struct {
@@ -93,18 +91,6 @@ func windowTabBarActiveID(t *testing.T, mw *window.MainWindow) entity.TabID {
93 return mw.TabBar().ActiveTabID()91 return mw.TabBar().ActiveTabID()
94 }92 }
95 93
96-type fakeWidgetFactory struct{}
97-
98-func (fakeWidgetFactory) NewPaned(layout.Orientation) layout.PanedWidget { return nil }
99-func (fakeWidgetFactory) NewBox(layout.Orientation, int) layout.BoxWidget { return nil }
100-func (fakeWidgetFactory) NewOverlay() layout.OverlayWidget { return nil }
101-func (fakeWidgetFactory) NewLabel(string) layout.LabelWidget { return nil }
102-func (fakeWidgetFactory) NewButton() layout.ButtonWidget { return nil }
103-func (fakeWidgetFactory) NewImage() layout.ImageWidget { return nil }
104-func (fakeWidgetFactory) NewProgressBar() layout.ProgressBarWidget { return nil }
105-func (fakeWidgetFactory) NewSpinner() layout.SpinnerWidget { return nil }
106-func (fakeWidgetFactory) WrapWidget(*gtk.Widget) layout.Widget { return nil }
107-
108 func TestApp_FinalizeActivationStartsBrowserLaunchRelayOnceAndClosesOnShutdown(t *testing.T) {94 func TestApp_FinalizeActivationStartsBrowserLaunchRelayOnceAndClosesOnShutdown(t *testing.T) {
109 relay := &testBrowserLaunchRelay{closer: &testCloser{}}95 relay := &testBrowserLaunchRelay{closer: &testCloser{}}
110 deps := &Dependencies{}96 deps := &Dependencies{}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close