| 121 | } |
| 122 | |
| 123 | func updateRun(opts *UpdateOptions) error { |
| 124 | io := opts.Factory.IOStreams |
| 125 | cur := currentVersion() |
| 126 | updater := newUpdater() |
| 127 | |
| 128 | if !opts.Check { |
| 129 | updater.CleanupStaleFiles() |
| 130 | } |
| 131 | output.PendingNotice = nil |
| 132 | |
| 133 | // 1. Fetch latest version |
| 134 | latest, err := fetchLatest() |
| 135 | if err != nil { |
| 136 | return reportError(opts, io, "network", |
| 137 | errs.NewNetworkError(errs.SubtypeNetworkTransport, "failed to check latest version: %s", err).WithCause(err)) |
| 138 | } |
| 139 | |
| 140 | // 2. Validate version format |
| 141 | if update.ParseVersion(latest) == nil { |
| 142 | return reportError(opts, io, "update_error", |
| 143 | errs.NewInternalError(errs.SubtypeInvalidResponse, "invalid version from registry: %s", latest)) |
| 144 | } |
| 145 | |
| 146 | // 3. Compare versions |
| 147 | if !opts.Force && !update.IsNewer(latest, cur) { |
| 148 | var skillsResult *skillscheck.SyncResult |
| 149 | if !opts.Check { |
| 150 | skillsResult = runSkillsAndState(updater, io, cur, opts.Force) |
| 151 | } |
| 152 | return reportAlreadyUpToDate(opts, io, cur, latest, skillsResult, opts.Check) |
| 153 | } |
| 154 | |
| 155 | // 4. Detect installation method |
| 156 | detect := updater.DetectInstallMethod() |
| 157 | |
| 158 | // 5. --check |
| 159 | if opts.Check { |
| 160 | return reportCheckResult(opts, io, cur, latest, detect.CanAutoUpdate()) |
| 161 | } |
| 162 | |
| 163 | // 6. Execute update |
| 164 | if !detect.CanAutoUpdate() { |
| 165 | return doManualUpdate(opts, io, cur, latest, detect, updater) |
| 166 | } |
| 167 | return doNpmUpdate(opts, io, cur, latest, updater) |
| 168 | } |
| 169 | |
| 170 | // --- Output helpers --- |
| 171 | |