detached fa63924

refactor(remote): centralize catalog cache path and unwrap load error

Add CatalogCachePath alongside HostStorePath so run.go and its test
share one canonical path instead of an inline filepath.Join literal.
Also drop the redundant "malformed cache file" wrapper in Load, since
normalizeCatalogCacheEntries already returns errors prefixed with
"remote catalog cache: ...".
commit
fa63924cb6a33edca22c725375360b74956f46b5
author
brice · · 2026-07-31 08:31 UTC
committer
brice · · 2026-07-31 08:54 UTC
parent
f0e21e9
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
3 files · +11 -4
M internal/adapters/remote/catalog_cache.go +9 -2
@@ -6,6 +6,7 @@ import (
66 "errors"
77 "fmt"
88 "os"
9+ "path/filepath"
910 "sort"
1011 "time"
1112 "unicode/utf8"
@@ -14,7 +15,13 @@ import (
1415 "github.com/bnema/vev/internal/ports"
1516 )
1617
17-const catalogCacheFileVersion = 1
18+const (
19+ catalogCacheFileName = "remote-catalog-cache.json"
20+ catalogCacheFileVersion = 1
21+)
22+
23+// CatalogCachePath returns the canonical location of the remote catalog cache in stateDir.
24+func CatalogCachePath(stateDir string) string { return filepath.Join(stateDir, catalogCacheFileName) }
1825
1926 type catalogCacheFile struct {
2027 Version *int `json:"version"`
@@ -114,7 +121,7 @@ func (c *fileCatalogCache) Load() ([]ports.RemoteCatalogCacheEntry, error) {
114121 }
115122 normalized, err := normalizeCatalogCacheEntries(entries)
116123 if err != nil {
117- return nil, fmt.Errorf("remote catalog cache: malformed cache file: %w", err)
124+ return nil, err
118125 }
119126 return normalized, nil
120127 }
@@ -6,6 +6,7 @@ import (
6 "errors"6 "errors"
7 "fmt"7 "fmt"
8 "os"8 "os"
9+ "path/filepath"
9 "sort"10 "sort"
10 "time"11 "time"
11 "unicode/utf8"12 "unicode/utf8"
@@ -14,7 +15,13 @@ import (
14 "github.com/bnema/vev/internal/ports"15 "github.com/bnema/vev/internal/ports"
15 )16 )
16 17
17-const catalogCacheFileVersion = 118+const (
19+ catalogCacheFileName = "remote-catalog-cache.json"
20+ catalogCacheFileVersion = 1
21+)
22+
23+// CatalogCachePath returns the canonical location of the remote catalog cache in stateDir.
24+func CatalogCachePath(stateDir string) string { return filepath.Join(stateDir, catalogCacheFileName) }
18 25
19 type catalogCacheFile struct {26 type catalogCacheFile struct {
20 Version *int `json:"version"`27 Version *int `json:"version"`
@@ -114,7 +121,7 @@ func (c *fileCatalogCache) Load() ([]ports.RemoteCatalogCacheEntry, error) {
114 }121 }
115 normalized, err := normalizeCatalogCacheEntries(entries)122 normalized, err := normalizeCatalogCacheEntries(entries)
116 if err != nil {123 if err != nil {
117- return nil, fmt.Errorf("remote catalog cache: malformed cache file: %w", err)124+ return nil, err
118 }125 }
119 return normalized, nil126 return normalized, nil
120 }127 }
M internal/app/run.go +1 -1
@@ -798,7 +798,7 @@ func remoteDiscoveryDaemonOption(stateDir string, observer ports.SerializedRunti
798798 return daemon.WithRemoteDiscovery(
799799 newRemoteHostStore(remoteadapter.HostStorePath(stateDir)),
800800 newRemoteCatalogClient(),
801- newRemoteCatalogCache(filepath.Join(stateDir, "remote-catalog-cache.json")),
801+ newRemoteCatalogCache(remoteadapter.CatalogCachePath(stateDir)),
802802 newRemoteDialerFactoryWithRuntimeObserver(observer),
803803 mode,
804804 ), nil
@@ -798,7 +798,7 @@ func remoteDiscoveryDaemonOption(stateDir string, observer ports.SerializedRunti
798 return daemon.WithRemoteDiscovery(798 return daemon.WithRemoteDiscovery(
799 newRemoteHostStore(remoteadapter.HostStorePath(stateDir)),799 newRemoteHostStore(remoteadapter.HostStorePath(stateDir)),
800 newRemoteCatalogClient(),800 newRemoteCatalogClient(),
801- newRemoteCatalogCache(filepath.Join(stateDir, "remote-catalog-cache.json")),801+ newRemoteCatalogCache(remoteadapter.CatalogCachePath(stateDir)),
802 newRemoteDialerFactoryWithRuntimeObserver(observer),802 newRemoteDialerFactoryWithRuntimeObserver(observer),
803 mode,803 mode,
804 ), nil804 ), nil
M internal/app/run_test.go +1 -1
@@ -1402,7 +1402,7 @@ func TestRemoteDiscoveryDaemonOptionWiresProductionPorts(t *testing.T) {
14021402 require.NoError(t, err)
14031403 _ = daemon.New(nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil)), option)
14041404 require.Equal(t, remoteadapter.HostStorePath(stateDir), hostPath)
1405- require.Equal(t, filepath.Join(stateDir, "remote-catalog-cache.json"), cachePath)
1405+ require.Equal(t, remoteadapter.CatalogCachePath(stateDir), cachePath)
14061406 require.Equal(t, 1, cache.loads, "daemon startup must load the cache once")
14071407 }
14081408
@@ -1402,7 +1402,7 @@ func TestRemoteDiscoveryDaemonOptionWiresProductionPorts(t *testing.T) {
1402 require.NoError(t, err)1402 require.NoError(t, err)
1403 _ = daemon.New(nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil)), option)1403 _ = daemon.New(nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil)), option)
1404 require.Equal(t, remoteadapter.HostStorePath(stateDir), hostPath)1404 require.Equal(t, remoteadapter.HostStorePath(stateDir), hostPath)
1405- require.Equal(t, filepath.Join(stateDir, "remote-catalog-cache.json"), cachePath)1405+ require.Equal(t, remoteadapter.CatalogCachePath(stateDir), cachePath)
1406 require.Equal(t, 1, cache.loads, "daemon startup must load the cache once")1406 require.Equal(t, 1, cache.loads, "daemon startup must load the cache once")
1407 }1407 }
1408 1408

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 12

Tags 11

↑↓ moveenter openesc close