github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/runners/swtch/switch.go (about) 1 package swtch 2 3 import ( 4 "github.com/ActiveState/cli/internal/analytics" 5 "github.com/ActiveState/cli/internal/config" 6 "github.com/ActiveState/cli/internal/errs" 7 "github.com/ActiveState/cli/internal/locale" 8 "github.com/ActiveState/cli/internal/logging" 9 "github.com/ActiveState/cli/internal/output" 10 "github.com/ActiveState/cli/internal/primer" 11 "github.com/ActiveState/cli/internal/rtutils/ptr" 12 "github.com/ActiveState/cli/internal/runbits/rationalize" 13 "github.com/ActiveState/cli/internal/runbits/runtime" 14 "github.com/ActiveState/cli/pkg/localcommit" 15 "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" 16 "github.com/ActiveState/cli/pkg/platform/authentication" 17 "github.com/ActiveState/cli/pkg/platform/model" 18 "github.com/ActiveState/cli/pkg/platform/runtime/target" 19 "github.com/ActiveState/cli/pkg/project" 20 "github.com/go-openapi/strfmt" 21 ) 22 23 type Switch struct { 24 auth *authentication.Auth 25 out output.Outputer 26 project *project.Project 27 analytics analytics.Dispatcher 28 svcModel *model.SvcModel 29 cfg *config.Instance 30 } 31 32 type SwitchParams struct { 33 Identifier string 34 } 35 36 type primeable interface { 37 primer.Auther 38 primer.Outputer 39 primer.Projecter 40 primer.Configurer 41 primer.Analyticer 42 primer.SvcModeler 43 } 44 45 type identifier interface { 46 CommitID() strfmt.UUID 47 Locale() string 48 } 49 50 type commitIdentifier struct { 51 commitID strfmt.UUID 52 } 53 54 func (c commitIdentifier) CommitID() strfmt.UUID { 55 return c.commitID 56 } 57 58 func (c commitIdentifier) Locale() string { 59 return locale.Tl("commit_identifier_type", "commit") 60 } 61 62 type branchIdentifier struct { 63 branch *mono_models.Branch 64 } 65 66 func (b branchIdentifier) CommitID() strfmt.UUID { 67 return *b.branch.CommitID 68 } 69 70 func (b branchIdentifier) Locale() string { 71 return locale.Tl("branch_identifier_type", "branch") 72 } 73 74 func New(prime primeable) *Switch { 75 return &Switch{ 76 auth: prime.Auth(), 77 out: prime.Output(), 78 project: prime.Project(), 79 analytics: prime.Analytics(), 80 svcModel: prime.SvcModel(), 81 cfg: prime.Config(), 82 } 83 } 84 85 func (s *Switch) Run(params SwitchParams) error { 86 logging.Debug("ExecuteSwitch") 87 88 if s.project == nil { 89 return rationalize.ErrNoProject 90 } 91 s.out.Notice(locale.Tr("operating_message", s.project.NamespaceString(), s.project.Dir())) 92 93 project, err := model.LegacyFetchProjectByName(s.project.Owner(), s.project.Name()) 94 if err != nil { 95 return locale.WrapError(err, "err_fetch_project", "", s.project.Namespace().String()) 96 } 97 98 identifier, err := resolveIdentifier(project, params.Identifier) 99 if err != nil { 100 return locale.WrapError(err, "err_resolve_identifier", "Could not resolve identifier '{{.V0}}'", params.Identifier) 101 } 102 103 if id, ok := identifier.(branchIdentifier); ok { 104 err = s.project.Source().SetBranch(id.branch.Label) 105 if err != nil { 106 return locale.WrapError(err, "err_switch_set_branch", "Could not update branch") 107 } 108 } 109 110 belongs, err := model.CommitBelongsToBranch(s.project.Owner(), s.project.Name(), s.project.BranchName(), identifier.CommitID(), s.auth) 111 if err != nil { 112 return locale.WrapError(err, "err_identifier_branch", "Could not determine if commit belongs to branch") 113 } 114 if !belongs { 115 return locale.NewInputError("err_identifier_branch_not_on_branch", "Commit does not belong to history for branch [ACTIONABLE]{{.V0}}[/RESET]", s.project.BranchName()) 116 } 117 118 err = localcommit.Set(s.project.Dir(), identifier.CommitID().String()) 119 if err != nil { 120 return errs.Wrap(err, "Unable to set local commit") 121 } 122 123 _, err = runtime.SolveAndUpdate(s.auth, s.out, s.analytics, s.project, ptr.To(identifier.CommitID()), target.TriggerSwitch, s.svcModel, s.cfg, runtime.OptNone) 124 if err != nil { 125 return locale.WrapError(err, "err_refresh_runtime") 126 } 127 128 s.out.Print(output.Prepare( 129 locale.Tl("branch_switch_success", "Successfully switched to {{.V0}}: [NOTICE]{{.V1}}[/RESET]", identifier.Locale(), params.Identifier), 130 &struct { 131 Branch string `json:"branch"` 132 }{ 133 params.Identifier, 134 }, 135 )) 136 137 return nil 138 } 139 140 func resolveIdentifier(project *mono_models.Project, idParam string) (identifier, error) { 141 if strfmt.IsUUID(idParam) { 142 return commitIdentifier{strfmt.UUID(idParam)}, nil 143 } 144 145 branch, err := model.BranchForProjectByName(project, idParam) 146 if err != nil { 147 return nil, locale.WrapError(err, "err_identifier_branch", "Could not get branch '{{.V0}}' for current project", idParam) 148 149 } 150 151 return branchIdentifier{branch: branch}, nil 152 }