github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/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 master; 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  	return CreateWorkspaceOnDB(ctx, dEnv.DoltDB, name, startPoint, dEnv.RepoState.CWBHeadRef())
    32  }
    33  
    34  func CreateWorkspaceOnDB(ctx context.Context, ddb *doltdb.DoltDB, name, startPoint string, headRef ref.DoltRef) error {
    35  	isBranch, err := IsBranchOnDB(ctx, ddb, name)
    36  	if err != nil {
    37  		return err
    38  	}
    39  	if isBranch {
    40  		return ErrBranchNameExists
    41  	}
    42  
    43  	if !doltdb.IsValidUserBranchName(name) {
    44  		return doltdb.ErrInvWorkspaceName
    45  	}
    46  
    47  	workRef := ref.NewWorkspaceRef(name)
    48  
    49  	hasRef, err := ddb.HasRef(ctx, workRef)
    50  	if err != nil {
    51  		return err
    52  	}
    53  	if hasRef {
    54  		return ErrAlreadyExists
    55  	}
    56  
    57  	cs, err := doltdb.NewCommitSpec(startPoint)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	cm, err := ddb.Resolve(ctx, cs, headRef)
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	return ddb.NewWorkspaceAtCommit(ctx, workRef, cm)
    68  }
    69  
    70  func IsWorkspaceOnDB(ctx context.Context, ddb *doltdb.DoltDB, str string) (bool, error) {
    71  	dref := ref.NewWorkspaceRef(str)
    72  	return ddb.HasRef(ctx, dref)
    73  }
    74  
    75  func IsWorkspace(ctx context.Context, dEnv *env.DoltEnv, str string) (bool, error) {
    76  	return IsWorkspaceOnDB(ctx, dEnv.DoltDB, str)
    77  }
    78  
    79  func DeleteWorkspace(ctx context.Context, dEnv *env.DoltEnv, workspaceName string, opts DeleteOptions) error {
    80  	var dref ref.DoltRef
    81  	if opts.Remote {
    82  		var err error
    83  		dref, err = ref.NewRemoteRefFromPathStr(workspaceName)
    84  		if err != nil {
    85  			return err
    86  		}
    87  	} else {
    88  		dref = ref.NewWorkspaceRef(workspaceName)
    89  		if ref.Equals(dEnv.RepoState.CWBHeadRef(), dref) {
    90  			return ErrCOWorkspaceDelete
    91  		}
    92  	}
    93  
    94  	return DeleteWorkspaceOnDB(ctx, dEnv.DoltDB, dref, opts)
    95  }
    96  
    97  func DeleteWorkspaceOnDB(ctx context.Context, ddb *doltdb.DoltDB, dref ref.DoltRef, opts DeleteOptions) error {
    98  	hasRef, err := ddb.HasRef(ctx, dref)
    99  
   100  	if err != nil {
   101  		return err
   102  	} else if !hasRef {
   103  		return doltdb.ErrWorkspaceNotFound
   104  	}
   105  
   106  	if !opts.Force && !opts.Remote {
   107  		ms, err := doltdb.NewCommitSpec("master")
   108  		if err != nil {
   109  			return err
   110  		}
   111  
   112  		master, err := ddb.Resolve(ctx, ms, nil)
   113  		if err != nil {
   114  			return err
   115  		}
   116  
   117  		cs, err := doltdb.NewCommitSpec(dref.String())
   118  		if err != nil {
   119  			return err
   120  		}
   121  
   122  		cm, err := ddb.Resolve(ctx, cs, nil)
   123  		if err != nil {
   124  			return err
   125  		}
   126  
   127  		isMerged, _ := master.CanFastReverseTo(ctx, cm)
   128  		if err != nil && err != doltdb.ErrUpToDate {
   129  			return err
   130  		}
   131  		if !isMerged {
   132  			return ErrUnmergedWorkspaceDelete
   133  		}
   134  	}
   135  
   136  	return ddb.DeleteWorkspace(ctx, dref)
   137  }