-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcmd_update.go
More file actions
141 lines (120 loc) · 4.13 KB
/
cmd_update.go
File metadata and controls
141 lines (120 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"context"
"errors"
"fmt"
"github.com/gustash/freecarnival/auth"
"github.com/gustash/freecarnival/download"
"github.com/gustash/freecarnival/logger"
"github.com/gustash/freecarnival/update"
"github.com/spf13/cobra"
)
func newUpdateCmd() *cobra.Command {
var (
version string
maxDownloadWorkers int
maxMemoryUsage int
infoOnly bool
skipVerify bool
verbose bool
)
cmd := &cobra.Command{
Use: "update <slug>",
Short: "Update an installed game",
Long: `Update an installed game to the latest version (or a specific version).`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
slug := args[0]
// Check if game is installed
installInfo, err := auth.GetInstalled(slug)
if err != nil {
return fmt.Errorf("failed to check installed games: %w", err)
}
if installInfo == nil {
return fmt.Errorf("%s is not installed", slug)
}
// Load library
library, err := auth.LoadLibrary()
if err != nil {
return fmt.Errorf("could not load library: %w (try running 'sync' first)", err)
}
// Find product
product := auth.FindProductBySlug(library, slug)
if product == nil {
return fmt.Errorf("game '%s' not found in your library", slug)
}
// Find old version
oldVersion := product.FindVersion(installInfo.Version, installInfo.OS)
if oldVersion == nil {
return fmt.Errorf("installed version %s not found in library", installInfo.Version)
}
// Find new version
var newVersion *auth.ProductVersion
if version != "" {
newVersion = product.FindVersion(version, installInfo.OS)
if newVersion == nil {
return fmt.Errorf("version '%s' not found for %s (OS: %s)", version, slug, installInfo.OS)
}
} else {
newVersion = product.GetLatestVersion(installInfo.OS)
if newVersion == nil {
return fmt.Errorf("no available version found for %s (OS: %s)", slug, installInfo.OS)
}
}
// Check if already up to date
if !infoOnly && oldVersion.Version == newVersion.Version {
logger.Info("Game is already up to date",
"name", product.Name,
"version", newVersion.Version)
return nil
}
logger.Info("Updating game",
"name", product.Name,
"from", oldVersion.Version,
"to", newVersion.Version,
"os", newVersion.OS)
// Load session for authenticated downloads
client, _, err := auth.LoadSessionClient()
if err != nil {
return fmt.Errorf("could not load session: %w (try running 'login' first)", err)
}
// Create update options
opts := download.Options{
MaxDownloadWorkers: maxDownloadWorkers,
MaxMemoryUsage: maxMemoryUsage,
SkipVerify: skipVerify,
InfoOnly: infoOnly,
Verbose: verbose,
}
// Create updater and start update
updater := update.New(client, product, oldVersion, newVersion, installInfo.InstallPath, opts)
err = updater.Update(cmd.Context())
// Check if update was cancelled (Ctrl+C)
if errors.Is(err, context.Canceled) {
return nil // Exit cleanly without error
}
if err != nil {
return fmt.Errorf("update failed: %w", err)
}
if !infoOnly {
// Update install info
installInfo.Version = newVersion.Version
installInfo.OS = newVersion.OS
if err := auth.AddInstalled(slug, installInfo); err != nil {
logger.Warn("Failed to update install info", "error", err)
}
logger.Info("Update complete",
"name", product.Name,
"version", newVersion.Version)
}
return nil
},
}
cmd.Flags().StringVarP(&version, "version", "v", "", "Specific version to update to (default: latest)")
cmd.Flags().IntVar(&maxDownloadWorkers, "workers", defaultMaxWorkers, "Number of parallel download workers")
cmd.Flags().IntVar(&maxMemoryUsage, "max-memory", defaultMaxMemory, "Maximum memory usage for buffering chunks (bytes)")
cmd.Flags().BoolVarP(&infoOnly, "info", "i", false, "Show update info without updating")
cmd.Flags().BoolVar(&skipVerify, "skip-verify", false, "Skip SHA verification of downloaded chunks")
cmd.Flags().BoolVar(&verbose, "verbose", false, "Show per-file progress")
return cmd
}