check_update.go RawHistoryFolder
1package usecase
2
3import (
4 "context"
5 "errors"
6
7 "github.com/bnema/dumber/internal/application/port"
8 "github.com/bnema/dumber/internal/domain/build"
9 "github.com/bnema/dumber/internal/logging"
10)
11
12// CheckUpdateInput holds the input for the check update use case.
13type CheckUpdateInput struct{}
14
15// CheckUpdateOutput holds the result of the update check.
16type CheckUpdateOutput struct {
17 // UpdateAvailable is true if a newer version exists.
18 UpdateAvailable bool
19 // CanAutoUpdate is true if the binary is writable and auto-update is possible.
20 CanAutoUpdate bool
21 // CurrentVersion is the version of the running binary.
22 CurrentVersion string
23 // LatestVersion is the latest available version.
24 LatestVersion string
25 // ReleaseURL is the URL to the GitHub release page.
26 ReleaseURL string
27 // DownloadURL is the direct download URL for the archive.
28 DownloadURL string
29}
30
31// CheckUpdateUseCase checks for available updates.
32type CheckUpdateUseCase struct {
33 checker port.UpdateChecker
34 applier port.UpdateApplier
35 buildInfo build.Info
36}
37
38// NewCheckUpdateUseCase creates a new check update use case.
39func NewCheckUpdateUseCase(
40 checker port.UpdateChecker,
41 applier port.UpdateApplier,
42 buildInfo build.Info,
43) *CheckUpdateUseCase {
44 return &CheckUpdateUseCase{
45 checker: checker,
46 applier: applier,
47 buildInfo: buildInfo,
48 }
49}
50
51// Execute checks for available updates.
52func (uc *CheckUpdateUseCase) Execute(ctx context.Context, _ CheckUpdateInput) (*CheckUpdateOutput, error) {
53 log := logging.FromContext(ctx)
54
55 info, err := uc.checker.CheckForUpdate(ctx, uc.buildInfo.Version)
56 if err != nil {
57 if errors.Is(err, port.ErrUpdateCheckTransient) {
58 log.Debug().Err(err).Msg("transient update check failure")
59 return &CheckUpdateOutput{
60 UpdateAvailable: false,
61 CanAutoUpdate: false,
62 CurrentVersion: uc.buildInfo.Version,
63 LatestVersion: uc.buildInfo.Version,
64 }, nil
65 }
66 log.Warn().Err(err).Msg("update check failed")
67 return nil, err
68 }
69
70 canAutoUpdate := false
71 if info.IsNewer {
72 canAutoUpdate = uc.applier.CanSelfUpdate(ctx)
73 }
74
75 log.Debug().
76 Str("current", uc.buildInfo.Version).
77 Str("latest", info.LatestVersion).
78 Bool("update_available", info.IsNewer).
79 Bool("can_auto_update", canAutoUpdate).
80 Msg("update check completed")
81
82 return &CheckUpdateOutput{
83 UpdateAvailable: info.IsNewer,
84 CanAutoUpdate: canAutoUpdate,
85 CurrentVersion: info.CurrentVersion,
86 LatestVersion: info.LatestVersion,
87 ReleaseURL: info.ReleaseURL,
88 DownloadURL: info.DownloadURL,
89 }, nil
90}