(opts *UpdateOptions, io *cmdutil.IOStreams, cur, latest string, updater *selfupdate.Updater)
| 232 | } |
| 233 | |
| 234 | func doNpmUpdate(opts *UpdateOptions, io *cmdutil.IOStreams, cur, latest string, updater *selfupdate.Updater) error { |
| 235 | restore, err := updater.PrepareSelfReplace() |
| 236 | if err != nil { |
| 237 | return reportError(opts, io, "update_error", |
| 238 | errs.NewAPIError(errs.SubtypeUnknown, "failed to prepare update: %s", err).WithCause(err)) |
| 239 | } |
| 240 | |
| 241 | if !opts.JSON { |
| 242 | fmt.Fprintf(io.ErrOut, "Updating lark-cli %s %s %s via npm ...\n", cur, symArrow(), latest) |
| 243 | } |
| 244 | |
| 245 | npmResult := updater.RunNpmInstall(latest) |
| 246 | if npmResult.Err != nil { |
| 247 | restore() |
| 248 | combined := npmResult.CombinedOutput() |
| 249 | if opts.JSON { |
| 250 | output.PrintJson(io.Out, map[string]interface{}{ |
| 251 | "ok": false, "error": map[string]interface{}{ |
| 252 | "type": "update_error", "message": fmt.Sprintf("npm install failed: %s", npmResult.Err), |
| 253 | "detail": selfupdate.Truncate(combined, maxNpmOutput), |
| 254 | "hint": permissionHint(combined), |
| 255 | }, |
| 256 | }) |
| 257 | return output.ErrBare(output.ExitAPI) |
| 258 | } |
| 259 | if npmResult.Stdout.Len() > 0 { |
| 260 | fmt.Fprint(io.ErrOut, npmResult.Stdout.String()) |
| 261 | } |
| 262 | if npmResult.Stderr.Len() > 0 { |
| 263 | fmt.Fprint(io.ErrOut, npmResult.Stderr.String()) |
| 264 | } |
| 265 | fmt.Fprintf(io.ErrOut, "\n%s Update failed: %s\n", symFail(), npmResult.Err) |
| 266 | if hint := permissionHint(combined); hint != "" { |
| 267 | fmt.Fprintf(io.ErrOut, " %s\n", hint) |
| 268 | } |
| 269 | return output.ErrBare(output.ExitAPI) |
| 270 | } |
| 271 | |
| 272 | // Verify the new binary is functional before proceeding. |
| 273 | // If corrupt, restore the previous version from .old. |
| 274 | if err := updater.VerifyBinary(latest); err != nil { |
| 275 | restore() |
| 276 | msg := fmt.Sprintf("new binary verification failed: %s", err) |
| 277 | hint := verificationFailureHint(updater, latest) |
| 278 | if opts.JSON { |
| 279 | output.PrintJson(io.Out, map[string]interface{}{ |
| 280 | "ok": false, |
| 281 | "error": map[string]interface{}{"type": "update_error", "message": msg, "hint": hint}, |
| 282 | }) |
| 283 | return output.ErrBare(output.ExitAPI) |
| 284 | } |
| 285 | fmt.Fprintf(io.ErrOut, "\n%s %s\n", symFail(), msg) |
| 286 | fmt.Fprintf(io.ErrOut, " %s\n", hint) |
| 287 | return output.ErrBare(output.ExitAPI) |
| 288 | } |
| 289 | |
| 290 | skillsResult := runSkillsAndState(updater, io, latest, opts.Force) |
| 291 |
no test coverage detected