mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-07-28 23:08:59 +02:00
refactor(go): rename extension store files and internals to repo
extension_store.go -> extension_repo.go, exports_store.go -> exports_repo.go; unexported types/functions/log tag renamed to match the user-facing repo terminology. The gomobile-exported function names (InitExtensionStoreJSON etc.) are the bridge ABI called from Kotlin/Swift and stay unchanged, as does the store_registry_url pref key that guards existing users' settings.
This commit is contained in:
@@ -8,14 +8,14 @@ import (
|
||||
)
|
||||
|
||||
func InitExtensionStoreJSON(cacheDir string) error {
|
||||
initExtensionStore(cacheDir)
|
||||
initExtensionRepo(cacheDir)
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetStoreRegistryURLJSON(registryURL string) error {
|
||||
store := getExtensionStore()
|
||||
if store == nil {
|
||||
return fmt.Errorf("extension store not initialized")
|
||||
repo := getExtensionRepo()
|
||||
if repo == nil {
|
||||
return fmt.Errorf("extension repo not initialized")
|
||||
}
|
||||
|
||||
resolved, err := resolveRegistryURL(registryURL)
|
||||
@@ -27,37 +27,37 @@ func SetStoreRegistryURLJSON(registryURL string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
store.setRegistryURL(resolved)
|
||||
repo.setRegistryURL(resolved)
|
||||
return nil
|
||||
}
|
||||
|
||||
func ClearStoreRegistryURLJSON() error {
|
||||
store := getExtensionStore()
|
||||
if store == nil {
|
||||
return fmt.Errorf("extension store not initialized")
|
||||
repo := getExtensionRepo()
|
||||
if repo == nil {
|
||||
return fmt.Errorf("extension repo not initialized")
|
||||
}
|
||||
|
||||
store.setRegistryURL("")
|
||||
store.clearCache()
|
||||
repo.setRegistryURL("")
|
||||
repo.clearCache()
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetStoreRegistryURLJSON() (string, error) {
|
||||
store := getExtensionStore()
|
||||
if store == nil {
|
||||
return "", fmt.Errorf("extension store not initialized")
|
||||
repo := getExtensionRepo()
|
||||
if repo == nil {
|
||||
return "", fmt.Errorf("extension repo not initialized")
|
||||
}
|
||||
|
||||
return store.getRegistryURL(), nil
|
||||
return repo.getRegistryURL(), nil
|
||||
}
|
||||
|
||||
func GetStoreExtensionsJSON(forceRefresh bool) (string, error) {
|
||||
store := getExtensionStore()
|
||||
if store == nil {
|
||||
return "", fmt.Errorf("extension store not initialized")
|
||||
repo := getExtensionRepo()
|
||||
if repo == nil {
|
||||
return "", fmt.Errorf("extension repo not initialized")
|
||||
}
|
||||
|
||||
extensions, err := store.getExtensionsWithStatus(forceRefresh)
|
||||
extensions, err := repo.getExtensionsWithStatus(forceRefresh)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -66,12 +66,12 @@ func GetStoreExtensionsJSON(forceRefresh bool) (string, error) {
|
||||
}
|
||||
|
||||
func SearchStoreExtensionsJSON(query, category string) (string, error) {
|
||||
store := getExtensionStore()
|
||||
if store == nil {
|
||||
return "", fmt.Errorf("extension store not initialized")
|
||||
repo := getExtensionRepo()
|
||||
if repo == nil {
|
||||
return "", fmt.Errorf("extension repo not initialized")
|
||||
}
|
||||
|
||||
extensions, err := store.searchExtensions(query, category)
|
||||
extensions, err := repo.searchExtensions(query, category)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -80,16 +80,16 @@ func SearchStoreExtensionsJSON(query, category string) (string, error) {
|
||||
}
|
||||
|
||||
func GetStoreCategoriesJSON() (string, error) {
|
||||
store := getExtensionStore()
|
||||
if store == nil {
|
||||
return "", fmt.Errorf("extension store not initialized")
|
||||
repo := getExtensionRepo()
|
||||
if repo == nil {
|
||||
return "", fmt.Errorf("extension repo not initialized")
|
||||
}
|
||||
|
||||
categories := store.getCategories()
|
||||
categories := repo.getCategories()
|
||||
return marshalJSONString(categories)
|
||||
}
|
||||
|
||||
func storeExtensionPackageSuffix(downloadURL string) string {
|
||||
func repoExtensionPackageSuffix(downloadURL string) string {
|
||||
rawPath := downloadURL
|
||||
if parsed, err := url.Parse(downloadURL); err == nil {
|
||||
rawPath = parsed.Path
|
||||
@@ -105,31 +105,31 @@ func storeExtensionPackageSuffix(downloadURL string) string {
|
||||
return ".spotiflac-ext"
|
||||
}
|
||||
|
||||
func buildStoreExtensionDestPath(destDir, extensionID, downloadURL string) (string, error) {
|
||||
func buildRepoExtensionDestPath(destDir, extensionID, downloadURL string) (string, error) {
|
||||
if strings.TrimSpace(extensionID) == "" {
|
||||
return "", fmt.Errorf("invalid extension id")
|
||||
}
|
||||
|
||||
safeExtensionID := sanitizeFilename(extensionID)
|
||||
return filepath.Join(destDir, safeExtensionID+storeExtensionPackageSuffix(downloadURL)), nil
|
||||
return filepath.Join(destDir, safeExtensionID+repoExtensionPackageSuffix(downloadURL)), nil
|
||||
}
|
||||
|
||||
func DownloadStoreExtensionJSON(extensionID, destDir string) (string, error) {
|
||||
store := getExtensionStore()
|
||||
if store == nil {
|
||||
return "", fmt.Errorf("extension store not initialized")
|
||||
repo := getExtensionRepo()
|
||||
if repo == nil {
|
||||
return "", fmt.Errorf("extension repo not initialized")
|
||||
}
|
||||
|
||||
ext, err := store.findExtension(extensionID)
|
||||
ext, err := repo.findExtension(extensionID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
destPath, err := buildStoreExtensionDestPath(destDir, extensionID, ext.getDownloadURL())
|
||||
destPath, err := buildRepoExtensionDestPath(destDir, extensionID, ext.getDownloadURL())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = store.downloadExtension(extensionID, destPath)
|
||||
err = repo.downloadExtension(extensionID, destPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -138,11 +138,11 @@ func DownloadStoreExtensionJSON(extensionID, destDir string) (string, error) {
|
||||
}
|
||||
|
||||
func ClearStoreCacheJSON() error {
|
||||
store := getExtensionStore()
|
||||
if store == nil {
|
||||
return fmt.Errorf("extension store not initialized")
|
||||
repo := getExtensionRepo()
|
||||
if repo == nil {
|
||||
return fmt.Errorf("extension repo not initialized")
|
||||
}
|
||||
|
||||
store.clearCache()
|
||||
repo.clearCache()
|
||||
return nil
|
||||
}
|
||||
@@ -405,8 +405,8 @@ func TestExportsJSONWrappersAndExtensionManagerSurface(t *testing.T) {
|
||||
if err := SetStoreRegistryURLJSON("https://registry.example.com/index.json"); err != nil {
|
||||
t.Fatalf("SetStoreRegistryURLJSON: %v", err)
|
||||
}
|
||||
store := getExtensionStore()
|
||||
store.cache = &storeRegistry{Extensions: []storeExtension{{
|
||||
store := getExtensionRepo()
|
||||
store.cache = &repoRegistry{Extensions: []repoExtension{{
|
||||
ID: "coverage-ext",
|
||||
Name: "coverage-ext",
|
||||
Version: "1.0.0",
|
||||
@@ -428,21 +428,21 @@ func TestExportsJSONWrappersAndExtensionManagerSurface(t *testing.T) {
|
||||
if catsJSON, err := GetStoreCategoriesJSON(); err != nil || !strings.Contains(catsJSON, "metadata") {
|
||||
t.Fatalf("GetStoreCategoriesJSON = %q/%v", catsJSON, err)
|
||||
}
|
||||
if dest, err := buildStoreExtensionDestPath(
|
||||
if dest, err := buildRepoExtensionDestPath(
|
||||
dir,
|
||||
"coverage/ext",
|
||||
"https://registry.example.com/coverage.spotiflac-ext",
|
||||
); err != nil || !strings.HasSuffix(dest, ".spotiflac-ext") {
|
||||
t.Fatalf("buildStoreExtensionDestPath = %q/%v", dest, err)
|
||||
t.Fatalf("buildRepoExtensionDestPath = %q/%v", dest, err)
|
||||
}
|
||||
if dest, err := buildStoreExtensionDestPath(
|
||||
if dest, err := buildRepoExtensionDestPath(
|
||||
dir,
|
||||
"coverage/ext",
|
||||
"https://registry.example.com/coverage.sflx",
|
||||
); err != nil || !strings.HasSuffix(dest, ".sflx") {
|
||||
t.Fatalf("buildStoreExtensionDestPath sflx = %q/%v", dest, err)
|
||||
t.Fatalf("buildRepoExtensionDestPath sflx = %q/%v", dest, err)
|
||||
}
|
||||
if _, err := buildStoreExtensionDestPath(
|
||||
if _, err := buildRepoExtensionDestPath(
|
||||
dir,
|
||||
" ",
|
||||
"https://registry.example.com/coverage.sflx",
|
||||
|
||||
@@ -21,7 +21,7 @@ const (
|
||||
CategoryIntegration = "integration"
|
||||
)
|
||||
|
||||
type storeExtension struct {
|
||||
type repoExtension struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name,omitempty"`
|
||||
@@ -40,7 +40,7 @@ type storeExtension struct {
|
||||
MinAppVersionAlt string `json:"minAppVersion,omitempty"`
|
||||
}
|
||||
|
||||
func (e *storeExtension) getDisplayName() string {
|
||||
func (e *repoExtension) getDisplayName() string {
|
||||
if e.DisplayName != "" {
|
||||
return e.DisplayName
|
||||
}
|
||||
@@ -50,34 +50,34 @@ func (e *storeExtension) getDisplayName() string {
|
||||
return e.Name
|
||||
}
|
||||
|
||||
func (e *storeExtension) getDownloadURL() string {
|
||||
func (e *repoExtension) getDownloadURL() string {
|
||||
if e.DownloadURL != "" {
|
||||
return e.DownloadURL
|
||||
}
|
||||
return e.DownloadURLAlt
|
||||
}
|
||||
|
||||
func (e *storeExtension) getIconURL() string {
|
||||
func (e *repoExtension) getIconURL() string {
|
||||
if e.IconURL != "" {
|
||||
return e.IconURL
|
||||
}
|
||||
return e.IconURLAlt
|
||||
}
|
||||
|
||||
func (e *storeExtension) getMinAppVersion() string {
|
||||
func (e *repoExtension) getMinAppVersion() string {
|
||||
if e.MinAppVersion != "" {
|
||||
return e.MinAppVersion
|
||||
}
|
||||
return e.MinAppVersionAlt
|
||||
}
|
||||
|
||||
type storeRegistry struct {
|
||||
Version int `json:"version"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
Extensions []storeExtension `json:"extensions"`
|
||||
type repoRegistry struct {
|
||||
Version int `json:"version"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
Extensions []repoExtension `json:"extensions"`
|
||||
}
|
||||
|
||||
type storeExtensionResponse struct {
|
||||
type repoExtensionResponse struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
@@ -95,8 +95,8 @@ type storeExtensionResponse struct {
|
||||
HasUpdate bool `json:"has_update"`
|
||||
}
|
||||
|
||||
func (e *storeExtension) toResponse() storeExtensionResponse {
|
||||
resp := storeExtensionResponse{
|
||||
func (e *repoExtension) toResponse() repoExtensionResponse {
|
||||
resp := repoExtensionResponse{
|
||||
ID: e.ID,
|
||||
Name: e.Name,
|
||||
DisplayName: e.getDisplayName(),
|
||||
@@ -117,18 +117,18 @@ func (e *storeExtension) toResponse() storeExtensionResponse {
|
||||
return resp
|
||||
}
|
||||
|
||||
type extensionStore struct {
|
||||
type extensionRepo struct {
|
||||
registryURL string
|
||||
cacheDir string
|
||||
cache *storeRegistry
|
||||
cache *repoRegistry
|
||||
cacheMu sync.RWMutex
|
||||
cacheTime time.Time
|
||||
cacheTTL time.Duration
|
||||
}
|
||||
|
||||
var (
|
||||
globalExtensionStore *extensionStore
|
||||
extensionStoreMu sync.Mutex
|
||||
globalExtensionRepo *extensionRepo
|
||||
extensionRepoMu sync.Mutex
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -136,22 +136,22 @@ const (
|
||||
cacheFileName = "store_cache.json"
|
||||
)
|
||||
|
||||
func initExtensionStore(cacheDir string) *extensionStore {
|
||||
extensionStoreMu.Lock()
|
||||
defer extensionStoreMu.Unlock()
|
||||
func initExtensionRepo(cacheDir string) *extensionRepo {
|
||||
extensionRepoMu.Lock()
|
||||
defer extensionRepoMu.Unlock()
|
||||
|
||||
if globalExtensionStore == nil {
|
||||
globalExtensionStore = &extensionStore{
|
||||
if globalExtensionRepo == nil {
|
||||
globalExtensionRepo = &extensionRepo{
|
||||
registryURL: "",
|
||||
cacheDir: cacheDir,
|
||||
cacheTTL: cacheTTL,
|
||||
}
|
||||
globalExtensionStore.loadDiskCache()
|
||||
globalExtensionRepo.loadDiskCache()
|
||||
}
|
||||
return globalExtensionStore
|
||||
return globalExtensionRepo
|
||||
}
|
||||
|
||||
func (s *extensionStore) setRegistryURL(registryURL string) {
|
||||
func (s *extensionRepo) setRegistryURL(registryURL string) {
|
||||
s.cacheMu.Lock()
|
||||
defer s.cacheMu.Unlock()
|
||||
|
||||
@@ -168,22 +168,22 @@ func (s *extensionStore) setRegistryURL(registryURL string) {
|
||||
os.Remove(cachePath)
|
||||
}
|
||||
|
||||
LogInfo("ExtensionStore", "Registry URL updated to: %s", registryURL)
|
||||
LogInfo("ExtensionRepo", "Registry URL updated to: %s", registryURL)
|
||||
}
|
||||
|
||||
func (s *extensionStore) getRegistryURL() string {
|
||||
func (s *extensionRepo) getRegistryURL() string {
|
||||
s.cacheMu.RLock()
|
||||
defer s.cacheMu.RUnlock()
|
||||
return s.registryURL
|
||||
}
|
||||
|
||||
func getExtensionStore() *extensionStore {
|
||||
extensionStoreMu.Lock()
|
||||
defer extensionStoreMu.Unlock()
|
||||
return globalExtensionStore
|
||||
func getExtensionRepo() *extensionRepo {
|
||||
extensionRepoMu.Lock()
|
||||
defer extensionRepoMu.Unlock()
|
||||
return globalExtensionRepo
|
||||
}
|
||||
|
||||
func (s *extensionStore) loadDiskCache() {
|
||||
func (s *extensionRepo) loadDiskCache() {
|
||||
if s.cacheDir == "" {
|
||||
return
|
||||
}
|
||||
@@ -195,9 +195,9 @@ func (s *extensionStore) loadDiskCache() {
|
||||
}
|
||||
|
||||
var cacheData struct {
|
||||
RegistryURL string `json:"registry_url"`
|
||||
Registry storeRegistry `json:"registry"`
|
||||
CacheTime int64 `json:"cache_time"`
|
||||
RegistryURL string `json:"registry_url"`
|
||||
Registry repoRegistry `json:"registry"`
|
||||
CacheTime int64 `json:"cache_time"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, &cacheData); err != nil {
|
||||
@@ -211,18 +211,18 @@ func (s *extensionStore) loadDiskCache() {
|
||||
// with the same URL keeps the cache instead of wiping it.
|
||||
s.registryURL = cacheData.RegistryURL
|
||||
}
|
||||
LogDebug("ExtensionStore", "Loaded %d extensions from disk cache", len(s.cache.Extensions))
|
||||
LogDebug("ExtensionRepo", "Loaded %d extensions from disk cache", len(s.cache.Extensions))
|
||||
}
|
||||
|
||||
func (s *extensionStore) saveDiskCache() {
|
||||
func (s *extensionRepo) saveDiskCache() {
|
||||
if s.cacheDir == "" || s.cache == nil {
|
||||
return
|
||||
}
|
||||
|
||||
cacheData := struct {
|
||||
RegistryURL string `json:"registry_url"`
|
||||
Registry storeRegistry `json:"registry"`
|
||||
CacheTime int64 `json:"cache_time"`
|
||||
RegistryURL string `json:"registry_url"`
|
||||
Registry repoRegistry `json:"registry"`
|
||||
CacheTime int64 `json:"cache_time"`
|
||||
}{
|
||||
RegistryURL: s.registryURL,
|
||||
Registry: *s.cache,
|
||||
@@ -238,7 +238,7 @@ func (s *extensionStore) saveDiskCache() {
|
||||
os.WriteFile(cachePath, data, 0644)
|
||||
}
|
||||
|
||||
func (s *extensionStore) fetchRegistry(forceRefresh bool) (*storeRegistry, error) {
|
||||
func (s *extensionRepo) fetchRegistry(forceRefresh bool) (*repoRegistry, error) {
|
||||
s.cacheMu.Lock()
|
||||
defer s.cacheMu.Unlock()
|
||||
|
||||
@@ -247,7 +247,7 @@ func (s *extensionStore) fetchRegistry(forceRefresh bool) (*storeRegistry, error
|
||||
}
|
||||
|
||||
if !forceRefresh && s.cache != nil && time.Since(s.cacheTime) < s.cacheTTL {
|
||||
LogDebug("ExtensionStore", "Using cached registry (%d extensions)", len(s.cache.Extensions))
|
||||
LogDebug("ExtensionRepo", "Using cached registry (%d extensions)", len(s.cache.Extensions))
|
||||
return s.cache, nil
|
||||
}
|
||||
|
||||
@@ -255,13 +255,13 @@ func (s *extensionStore) fetchRegistry(forceRefresh bool) (*storeRegistry, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
LogInfo("ExtensionStore", "Fetching registry from %s", s.registryURL)
|
||||
LogInfo("ExtensionRepo", "Fetching registry from %s", s.registryURL)
|
||||
|
||||
client := NewHTTPClientWithTimeout(30 * time.Second)
|
||||
req, err := http.NewRequest(http.MethodGet, s.registryURL, nil)
|
||||
if err != nil {
|
||||
if s.cache != nil {
|
||||
LogWarn("ExtensionStore", "Failed to build registry request, using cached registry: %v", err)
|
||||
LogWarn("ExtensionRepo", "Failed to build registry request, using cached registry: %v", err)
|
||||
return s.cache, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to build registry request: %w", err)
|
||||
@@ -271,7 +271,7 @@ func (s *extensionStore) fetchRegistry(forceRefresh bool) (*storeRegistry, error
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
if s.cache != nil {
|
||||
LogWarn("ExtensionStore", "Network error, using cached registry: %v", err)
|
||||
LogWarn("ExtensionRepo", "Network error, using cached registry: %v", err)
|
||||
return s.cache, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to fetch registry: %w", err)
|
||||
@@ -280,7 +280,7 @@ func (s *extensionStore) fetchRegistry(forceRefresh bool) (*storeRegistry, error
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
if s.cache != nil {
|
||||
LogWarn("ExtensionStore", "HTTP %d, using cached registry", resp.StatusCode)
|
||||
LogWarn("ExtensionRepo", "HTTP %d, using cached registry", resp.StatusCode)
|
||||
return s.cache, nil
|
||||
}
|
||||
return nil, fmt.Errorf("registry returned HTTP %d", resp.StatusCode)
|
||||
@@ -294,7 +294,7 @@ func (s *extensionStore) fetchRegistry(forceRefresh bool) (*storeRegistry, error
|
||||
registry, err := parseRegistryBody(body)
|
||||
if err != nil {
|
||||
if s.cache != nil {
|
||||
LogWarn("ExtensionStore", "Failed to parse registry, using cached registry: %v", err)
|
||||
LogWarn("ExtensionRepo", "Failed to parse registry, using cached registry: %v", err)
|
||||
return s.cache, nil
|
||||
}
|
||||
return nil, err
|
||||
@@ -304,12 +304,12 @@ func (s *extensionStore) fetchRegistry(forceRefresh bool) (*storeRegistry, error
|
||||
s.cacheTime = time.Now()
|
||||
s.saveDiskCache()
|
||||
|
||||
LogInfo("ExtensionStore", "Fetched %d extensions from registry", len(registry.Extensions))
|
||||
LogInfo("ExtensionRepo", "Fetched %d extensions from registry", len(registry.Extensions))
|
||||
return registry, nil
|
||||
}
|
||||
|
||||
func parseRegistryBody(body []byte) (*storeRegistry, error) {
|
||||
var registry storeRegistry
|
||||
func parseRegistryBody(body []byte) (*repoRegistry, error) {
|
||||
var registry repoRegistry
|
||||
if err := json.Unmarshal(body, ®istry); err != nil {
|
||||
if strings.HasPrefix(strings.TrimSpace(string(body)), "<") {
|
||||
return nil, fmt.Errorf("registry URL returned a web page instead of JSON. Make sure the URL points to a registry.json file or a GitHub repository that contains one")
|
||||
@@ -319,7 +319,7 @@ func parseRegistryBody(body []byte) (*storeRegistry, error) {
|
||||
return ®istry, nil
|
||||
}
|
||||
|
||||
func (s *extensionStore) getExtensionsWithStatus(forceRefresh bool) ([]storeExtensionResponse, error) {
|
||||
func (s *extensionRepo) getExtensionsWithStatus(forceRefresh bool) ([]repoExtensionResponse, error) {
|
||||
registry, err := s.fetchRegistry(forceRefresh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -334,9 +334,9 @@ func (s *extensionStore) getExtensionsWithStatus(forceRefresh bool) ([]storeExte
|
||||
}
|
||||
}
|
||||
|
||||
LogDebug("ExtensionStore", "Building store response for %d registry extensions (%d installed)", len(registry.Extensions), len(installed))
|
||||
LogDebug("ExtensionRepo", "Building store response for %d registry extensions (%d installed)", len(registry.Extensions), len(installed))
|
||||
|
||||
result := make([]storeExtensionResponse, 0, len(registry.Extensions))
|
||||
result := make([]repoExtensionResponse, 0, len(registry.Extensions))
|
||||
for i := range registry.Extensions {
|
||||
ext := ®istry.Extensions[i]
|
||||
resp := ext.toResponse()
|
||||
@@ -349,11 +349,11 @@ func (s *extensionStore) getExtensionsWithStatus(forceRefresh bool) ([]storeExte
|
||||
result = append(result, resp)
|
||||
}
|
||||
|
||||
LogDebug("ExtensionStore", "Built store response payload for %d extensions", len(result))
|
||||
LogDebug("ExtensionRepo", "Built store response payload for %d extensions", len(result))
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *extensionStore) findExtension(extensionID string) (*storeExtension, error) {
|
||||
func (s *extensionRepo) findExtension(extensionID string) (*repoExtension, error) {
|
||||
registry, err := s.fetchRegistry(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -369,7 +369,7 @@ func (s *extensionStore) findExtension(extensionID string) (*storeExtension, err
|
||||
return nil, fmt.Errorf("extension %s not found in repo", extensionID)
|
||||
}
|
||||
|
||||
func (s *extensionStore) downloadExtension(extensionID string, destPath string) error {
|
||||
func (s *extensionRepo) downloadExtension(extensionID string, destPath string) error {
|
||||
ext, err := s.findExtension(extensionID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -379,7 +379,7 @@ func (s *extensionStore) downloadExtension(extensionID string, destPath string)
|
||||
return err
|
||||
}
|
||||
|
||||
LogInfo("ExtensionStore", "Downloading %s from %s", ext.getDisplayName(), ext.getDownloadURL())
|
||||
LogInfo("ExtensionRepo", "Downloading %s from %s", ext.getDisplayName(), ext.getDownloadURL())
|
||||
|
||||
client := NewHTTPClientWithTimeout(5 * time.Minute)
|
||||
req, err := http.NewRequest(http.MethodGet, ext.getDownloadURL(), nil)
|
||||
@@ -410,7 +410,7 @@ func (s *extensionStore) downloadExtension(extensionID string, destPath string)
|
||||
return fmt.Errorf("failed to write file: %w", err)
|
||||
}
|
||||
|
||||
LogInfo("ExtensionStore", "Downloaded %s to %s", ext.getDisplayName(), destPath)
|
||||
LogInfo("ExtensionRepo", "Downloaded %s to %s", ext.getDisplayName(), destPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -445,7 +445,7 @@ func resolveRegistryURL(input string) (string, error) {
|
||||
branch := resolveGitHubDefaultBranch(owner, repo)
|
||||
|
||||
resolved := fmt.Sprintf("https://raw.githubusercontent.com/%s/%s/%s/registry.json", owner, repo, branch)
|
||||
LogInfo("ExtensionStore", "Resolved %s → %s (branch: %s)", input, resolved, branch)
|
||||
LogInfo("ExtensionRepo", "Resolved %s → %s (branch: %s)", input, resolved, branch)
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
@@ -455,13 +455,13 @@ func resolveGitHubDefaultBranch(owner, repo string) string {
|
||||
|
||||
resp, err := client.Get(apiURL)
|
||||
if err != nil {
|
||||
LogWarn("ExtensionStore", "GitHub API request failed for %s/%s: %v – falling back to main", owner, repo, err)
|
||||
LogWarn("ExtensionRepo", "GitHub API request failed for %s/%s: %v – falling back to main", owner, repo, err)
|
||||
return "main"
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
LogWarn("ExtensionStore", "GitHub API returned %d for %s/%s – falling back to main", resp.StatusCode, owner, repo)
|
||||
LogWarn("ExtensionRepo", "GitHub API returned %d for %s/%s – falling back to main", resp.StatusCode, owner, repo)
|
||||
return "main"
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ func resolveGitHubDefaultBranch(owner, repo string) string {
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&info); err != nil || info.DefaultBranch == "" {
|
||||
LogWarn("ExtensionStore", "Could not parse default_branch for %s/%s – falling back to main", owner, repo)
|
||||
LogWarn("ExtensionRepo", "Could not parse default_branch for %s/%s – falling back to main", owner, repo)
|
||||
return "main"
|
||||
}
|
||||
|
||||
@@ -490,7 +490,7 @@ func requireHTTPSURL(rawURL string, context string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *extensionStore) getCategories() []string {
|
||||
func (s *extensionRepo) getCategories() []string {
|
||||
return []string{
|
||||
CategoryMetadata,
|
||||
CategoryDownload,
|
||||
@@ -500,7 +500,7 @@ func (s *extensionStore) getCategories() []string {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *extensionStore) searchExtensions(query string, category string) ([]storeExtensionResponse, error) {
|
||||
func (s *extensionRepo) searchExtensions(query string, category string) ([]repoExtensionResponse, error) {
|
||||
extensions, err := s.getExtensionsWithStatus(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -510,7 +510,7 @@ func (s *extensionStore) searchExtensions(query string, category string) ([]stor
|
||||
return extensions, nil
|
||||
}
|
||||
|
||||
result := make([]storeExtensionResponse, 0, len(extensions))
|
||||
result := make([]repoExtensionResponse, 0, len(extensions))
|
||||
queryLower := strings.ToLower(query)
|
||||
|
||||
for _, ext := range extensions {
|
||||
@@ -541,7 +541,7 @@ func (s *extensionStore) searchExtensions(query string, category string) ([]stor
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *extensionStore) clearCache() {
|
||||
func (s *extensionRepo) clearCache() {
|
||||
s.cacheMu.Lock()
|
||||
defer s.cacheMu.Unlock()
|
||||
|
||||
@@ -553,5 +553,5 @@ func (s *extensionStore) clearCache() {
|
||||
os.Remove(cachePath)
|
||||
}
|
||||
|
||||
LogInfo("ExtensionStore", "Cache cleared")
|
||||
LogInfo("ExtensionRepo", "Cache cleared")
|
||||
}
|
||||
@@ -342,13 +342,13 @@ func TestDeezerTrackIsExplicit(t *testing.T) {
|
||||
func TestExtensionStoreDiskCacheSurvivesRestart(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
registryURL := "https://registry.example.com/registry.json"
|
||||
store := &extensionStore{
|
||||
store := &extensionRepo{
|
||||
registryURL: registryURL,
|
||||
cacheDir: dir,
|
||||
cacheTTL: time.Hour,
|
||||
cache: &storeRegistry{
|
||||
cache: &repoRegistry{
|
||||
Version: 1,
|
||||
Extensions: []storeExtension{{ID: "ext", Name: "ext", Version: "1.0.0"}},
|
||||
Extensions: []repoExtension{{ID: "ext", Name: "ext", Version: "1.0.0"}},
|
||||
},
|
||||
cacheTime: time.Now(),
|
||||
}
|
||||
@@ -356,7 +356,7 @@ func TestExtensionStoreDiskCacheSurvivesRestart(t *testing.T) {
|
||||
|
||||
// Simulates an app restart: a fresh store loads the disk cache, then the
|
||||
// Dart layer re-applies the same registry URL.
|
||||
restarted := &extensionStore{cacheDir: dir, cacheTTL: time.Hour}
|
||||
restarted := &extensionRepo{cacheDir: dir, cacheTTL: time.Hour}
|
||||
restarted.loadDiskCache()
|
||||
if restarted.getRegistryURL() != registryURL {
|
||||
t.Fatalf("registry URL after restart = %q", restarted.getRegistryURL())
|
||||
@@ -389,14 +389,14 @@ func TestParseRegistryBody(t *testing.T) {
|
||||
|
||||
func TestExtensionStoreSettingsAndRuntimeStorage(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
store := &extensionStore{
|
||||
store := &extensionRepo{
|
||||
registryURL: "https://registry.example.com/registry.json",
|
||||
cacheDir: dir,
|
||||
cacheTTL: time.Hour,
|
||||
cache: &storeRegistry{
|
||||
cache: &repoRegistry{
|
||||
Version: 1,
|
||||
UpdatedAt: "2026-05-04",
|
||||
Extensions: []storeExtension{
|
||||
Extensions: []repoExtension{
|
||||
{
|
||||
ID: "coverage-ext",
|
||||
Name: "coverage-ext",
|
||||
@@ -425,7 +425,7 @@ func TestExtensionStoreSettingsAndRuntimeStorage(t *testing.T) {
|
||||
cacheTime: time.Now(),
|
||||
}
|
||||
store.saveDiskCache()
|
||||
loadedStore := &extensionStore{cacheDir: dir}
|
||||
loadedStore := &extensionRepo{cacheDir: dir}
|
||||
loadedStore.loadDiskCache()
|
||||
if loadedStore.cache == nil || len(loadedStore.cache.Extensions) != 2 {
|
||||
t.Fatalf("loaded cache = %#v", loadedStore.cache)
|
||||
|
||||
Reference in New Issue
Block a user