github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/env/actions/workspace.go (about) 1 // Copyright 2020 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package actions 16 17 import ( 18 "context" 19 "errors" 20 21 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 22 "github.com/dolthub/dolt/go/libraries/doltcore/env" 23 "github.com/dolthub/dolt/go/libraries/doltcore/ref" 24 ) 25 26 var ErrUnmergedWorkspaceDelete = errors.New("attempted to delete a workspace that is not fully merged into its parent; use `-f` to force") 27 var ErrCOWorkspaceDelete = errors.New("attempted to delete checked out workspace") 28 var ErrBranchNameExists = errors.New("workspace name must not be existing branch name") 29 30 func CreateWorkspace(ctx context.Context, dEnv *env.DoltEnv, name, startPoint string) error { 31 headRef, err := dEnv.RepoStateReader().CWBHeadRef() 32 if err != nil { 33 return nil 34 } 35 return CreateWorkspaceOnDB(ctx, dEnv.DoltDB, name, startPoint, headRef) 36 } 37 38 func CreateWorkspaceOnDB(ctx context.Context, ddb *doltdb.DoltDB, name, startPoint string, headRef ref.DoltRef) error { 39 isBranch, err := IsBranchOnDB(ctx, ddb, name) 40 if err != nil { 41 return err 42 } 43 if isBranch { 44 return ErrBranchNameExists 45 } 46 47 if !doltdb.IsValidUserBranchName(name) { 48 return doltdb.ErrInvWorkspaceName 49 } 50 51 workRef := ref.NewWorkspaceRef(name) 52 53 hasRef, err := ddb.HasRef(ctx, workRef) 54 if err != nil { 55 return err 56 } 57 if hasRef { 58 return ErrAlreadyExists 59 } 60 61 cs, err := doltdb.NewCommitSpec(startPoint) 62 if err != nil { 63 return err 64 } 65 66 optCmt, err := ddb.Resolve(ctx, cs, headRef) 67 if err != nil { 68 return err 69 } 70 cm, ok := optCmt.ToCommit() 71 if !ok { 72 return doltdb.ErrGhostCommitEncountered 73 } 74 75 return ddb.NewWorkspaceAtCommit(ctx, workRef, cm) 76 } 77 78 func IsWorkspaceOnDB(ctx context.Context, ddb *doltdb.DoltDB, str string) (bool, error) { 79 dref := ref.NewWorkspaceRef(str) 80 return ddb.HasRef(ctx, dref) 81 } 82 83 func IsWorkspace(ctx context.Context, dEnv *env.DoltEnv, str string) (bool, error) { 84 return IsWorkspaceOnDB(ctx, dEnv.DoltDB, str) 85 } 86 87 func DeleteWorkspace(ctx context.Context, dEnv *env.DoltEnv, workspaceName string, opts DeleteOptions) error { 88 var dref ref.DoltRef 89 if opts.Remote { 90 var err error 91 dref, err = ref.NewRemoteRefFromPathStr(workspaceName) 92 if err != nil { 93 return err 94 } 95 } else { 96 dref = ref.NewWorkspaceRef(workspaceName) 97 headRef, err := dEnv.RepoStateReader().CWBHeadRef() 98 if err != nil { 99 return err 100 } 101 if ref.Equals(headRef, dref) { 102 return ErrCOWorkspaceDelete 103 } 104 } 105 106 return DeleteWorkspaceOnDB(ctx, dEnv, dref, opts) 107 } 108 109 func DeleteWorkspaceOnDB(ctx context.Context, dEnv *env.DoltEnv, dref ref.DoltRef, opts DeleteOptions) error { 110 ddb := dEnv.DoltDB 111 hasRef, err := ddb.HasRef(ctx, dref) 112 113 if err != nil { 114 return err 115 } else if !hasRef { 116 return doltdb.ErrWorkspaceNotFound 117 } 118 119 if !opts.Force && !opts.Remote { 120 ms, err := doltdb.NewCommitSpec(env.GetDefaultInitBranch(dEnv.Config)) 121 if err != nil { 122 return err 123 } 124 125 optCmt, err := ddb.Resolve(ctx, ms, nil) 126 if err != nil { 127 return err 128 } 129 m, ok := optCmt.ToCommit() 130 if !ok { 131 return doltdb.ErrGhostCommitEncountered 132 } 133 134 cs, err := doltdb.NewCommitSpec(dref.String()) 135 if err != nil { 136 return err 137 } 138 139 optCmt, err = ddb.Resolve(ctx, cs, nil) 140 if err != nil { 141 return err 142 } 143 cm, ok := optCmt.ToCommit() 144 if !ok { 145 return doltdb.ErrGhostCommitEncountered 146 } 147 148 isMerged, _ := m.CanFastReverseTo(ctx, cm) 149 if err != nil && err != doltdb.ErrUpToDate { 150 return err 151 } 152 if !isMerged { 153 return ErrUnmergedWorkspaceDelete 154 } 155 } 156 157 return ddb.DeleteWorkspace(ctx, dref) 158 }