fix: simplify things

Carlos Alexandro Becker created

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

Change summary

internal/app/app.go            | 26 ++++----------
internal/update/update.go      | 52 +++++++-----------------------
internal/update/update_test.go | 61 -----------------------------------
3 files changed, 22 insertions(+), 117 deletions(-)

Detailed changes

internal/app/app.go 🔗

@@ -348,26 +348,16 @@ func (app *App) Shutdown() {
 	}
 }
 
-// checkForUpdates checks for available updates in the background.
+// checkForUpdates checks for available updates.
 func (app *App) checkForUpdates(ctx context.Context) {
-	// Use a timeout to avoid hanging indefinitely.
-	checkCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
+	checkCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
 	defer cancel()
-
-	// Check for updates asynchronously.
-	updateCh := update.CheckForUpdateAsync(checkCtx, app.config.Options.DataDirectory)
-
-	select {
-	case info := <-updateCh:
-		if info != nil && info.Available {
-			// Send update notification through the event system.
-			app.events <- pubsub.UpdateAvailableMsg{
-				CurrentVersion: info.CurrentVersion,
-				LatestVersion:  info.LatestVersion,
-			}
-		}
-	case <-checkCtx.Done():
-		// Timeout or context cancelled.
+	info, err := update.Check(checkCtx)
+	if err != nil || info == nil || !info.Available {
 		return
 	}
+	app.events <- pubsub.UpdateAvailableMsg{
+		CurrentVersion: info.CurrentVersion,
+		LatestVersion:  info.LatestVersion,
+	}
 }

internal/update/update.go 🔗

@@ -6,7 +6,6 @@ import (
 	"fmt"
 	"io"
 	"net/http"
-	"os"
 	"strings"
 	"time"
 
@@ -19,23 +18,17 @@ const (
 	userAgent    = "crush/1.0"
 )
 
-// Release represents a GitHub release.
-type Release struct {
-	TagName string `json:"tag_name"`
-	HTMLURL string `json:"html_url"`
-}
-
-// UpdateInfo contains information about an available update.
-type UpdateInfo struct {
+// Info contains information about an available update.
+type Info struct {
 	CurrentVersion string
 	LatestVersion  string
 	ReleaseURL     string
 	Available      bool
 }
 
-// CheckForUpdate checks if a new version is available.
-func CheckForUpdate(ctx context.Context) (*UpdateInfo, error) {
-	info := &UpdateInfo{
+// Check checks if a new version is available.
+func Check(ctx context.Context) (*Info, error) {
+	info := &Info{
 		CurrentVersion: version.Version,
 	}
 
@@ -62,8 +55,14 @@ func CheckForUpdate(ctx context.Context) (*UpdateInfo, error) {
 	return info, nil
 }
 
+// githubRelease represents a GitHub release.
+type githubRelease struct {
+	TagName string `json:"tag_name"`
+	HTMLURL string `json:"html_url"`
+}
+
 // fetchLatestRelease fetches the latest release information from GitHub.
-func fetchLatestRelease(ctx context.Context) (*Release, error) {
+func fetchLatestRelease(ctx context.Context) (*githubRelease, error) {
 	client := &http.Client{
 		Timeout: 30 * time.Second,
 	}
@@ -86,35 +85,10 @@ func fetchLatestRelease(ctx context.Context) (*Release, error) {
 		return nil, fmt.Errorf("GitHub API returned status %d: %s", resp.StatusCode, string(body))
 	}
 
-	var release Release
+	var release githubRelease
 	if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
 		return nil, err
 	}
 
 	return &release, nil
 }
-
-// CheckForUpdateAsync performs an update check in the background and returns immediately.
-// If an update is available, it returns the update info through the channel.
-func CheckForUpdateAsync(ctx context.Context, dataDir string) <-chan *UpdateInfo {
-	ch := make(chan *UpdateInfo, 1)
-
-	go func() {
-		defer close(ch)
-
-		// Perform the check.
-		info, err := CheckForUpdate(ctx)
-		if err != nil {
-			// Log error but don't fail.
-			fmt.Fprintf(os.Stderr, "Failed to check for updates: %v\n", err)
-			return
-		}
-
-		// Send update info if available.
-		if info.Available {
-			ch <- info
-		}
-	}()
-
-	return ch
-}

internal/update/update_test.go 🔗

@@ -8,65 +8,6 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
-func TestCompareVersions(t *testing.T) {
-	tests := []struct {
-		name     string
-		v1       string
-		v2       string
-		expected int
-	}{
-		{
-			name:     "equal versions",
-			v1:       "1.0.0",
-			v2:       "1.0.0",
-			expected: 0,
-		},
-		{
-			name:     "v1 less than v2 - patch",
-			v1:       "1.0.0",
-			v2:       "1.0.1",
-			expected: -1,
-		},
-		{
-			name:     "v1 less than v2 - minor",
-			v1:       "1.0.0",
-			v2:       "1.1.0",
-			expected: -1,
-		},
-		{
-			name:     "v1 less than v2 - major",
-			v1:       "1.0.0",
-			v2:       "2.0.0",
-			expected: -1,
-		},
-		{
-			name:     "v1 greater than v2",
-			v1:       "2.0.0",
-			v2:       "1.9.9",
-			expected: 1,
-		},
-		{
-			name:     "with v prefix",
-			v1:       "v1.0.0",
-			v2:       "v1.0.1",
-			expected: -1,
-		},
-		{
-			name:     "different lengths",
-			v1:       "1.0",
-			v2:       "1.0.0",
-			expected: -1,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			result := compareVersions(tt.v1, tt.v2)
-			require.Equal(t, tt.expected, result)
-		})
-	}
-}
-
 func TestCheckForUpdate_DevelopmentVersion(t *testing.T) {
 	// Test that development versions don't trigger updates.
 	ctx := context.Background()
@@ -78,7 +19,7 @@ func TestCheckForUpdate_DevelopmentVersion(t *testing.T) {
 		version.Version = originalVersion
 	}()
 
-	info, err := CheckForUpdate(ctx)
+	info, err := Check(ctx)
 	require.NoError(t, err)
 	require.NotNil(t, info)
 	require.False(t, info.Available)