github.com/jfrog/jfrog-cli-core/v2@v2.51.0/artifactory/commands/generic/delete.go (about)

     1  package generic
     2  
     3  import (
     4  	ioutils "github.com/jfrog/gofrog/io"
     5  	"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
     6  	"github.com/jfrog/jfrog-cli-core/v2/common/spec"
     7  	"github.com/jfrog/jfrog-client-go/artifactory/services"
     8  	clientutils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
     9  	"github.com/jfrog/jfrog-client-go/utils/errorutils"
    10  	"github.com/jfrog/jfrog-client-go/utils/io/content"
    11  )
    12  
    13  type DeleteCommand struct {
    14  	GenericCommand
    15  	threads int
    16  }
    17  
    18  func NewDeleteCommand() *DeleteCommand {
    19  	return &DeleteCommand{GenericCommand: *NewGenericCommand()}
    20  }
    21  
    22  func (dc *DeleteCommand) Threads() int {
    23  	return dc.threads
    24  }
    25  
    26  func (dc *DeleteCommand) SetThreads(threads int) *DeleteCommand {
    27  	dc.threads = threads
    28  	return dc
    29  }
    30  
    31  func (dc *DeleteCommand) CommandName() string {
    32  	return "rt_delete"
    33  }
    34  
    35  func (dc *DeleteCommand) Run() (err error) {
    36  	reader, err := dc.GetPathsToDelete()
    37  	if err != nil {
    38  		return
    39  	}
    40  	defer ioutils.Close(reader, &err)
    41  	allowDelete := true
    42  	if !dc.quiet {
    43  		allowDelete, err = utils.ConfirmDelete(reader)
    44  		if err != nil {
    45  			return
    46  		}
    47  	}
    48  	if allowDelete {
    49  		var successCount int
    50  		var failedCount int
    51  		successCount, failedCount, err = dc.DeleteFiles(reader)
    52  		result := dc.Result()
    53  		result.SetFailCount(failedCount)
    54  		result.SetSuccessCount(successCount)
    55  	}
    56  	return
    57  }
    58  
    59  func (dc *DeleteCommand) GetPathsToDelete() (contentReader *content.ContentReader, err error) {
    60  	serverDetails, err := dc.ServerDetails()
    61  	if errorutils.CheckError(err) != nil {
    62  		return
    63  	}
    64  	servicesManager, err := utils.CreateServiceManager(serverDetails, dc.retries, dc.retryWaitTimeMilliSecs, dc.DryRun())
    65  	if err != nil {
    66  		return
    67  	}
    68  	var temp []*content.ContentReader
    69  	defer func() {
    70  		for _, reader := range temp {
    71  			ioutils.Close(reader, &err)
    72  		}
    73  	}()
    74  	for i := 0; i < len(dc.Spec().Files); i++ {
    75  		var deleteParams services.DeleteParams
    76  		deleteParams, err = getDeleteParams(dc.Spec().Get(i))
    77  		if err != nil {
    78  			return
    79  		}
    80  		var reader *content.ContentReader
    81  		reader, err = servicesManager.GetPathsToDelete(deleteParams)
    82  		if err != nil {
    83  			return
    84  		}
    85  		temp = append(temp, reader)
    86  	}
    87  	tempMergedReader, err := content.MergeReaders(temp, content.DefaultKey)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  	defer ioutils.Close(tempMergedReader, &err)
    92  	// After merge, remove top chain dirs as we may encounter duplicates and collisions between files and directories to delete.
    93  	// For example:
    94  	// Reader1: {"a"}
    95  	// Reader2: {"a/b","a/c"}
    96  	// After merge, received a Reader: {"a","a/b","a/c"}.
    97  	// If "a" is deleted prior to "a/b" or "a/c", the delete operation returns a failure.
    98  	contentReader, err = clientutils.ReduceTopChainDirResult(clientutils.ResultItem{}, tempMergedReader)
    99  	return
   100  }
   101  
   102  func (dc *DeleteCommand) DeleteFiles(reader *content.ContentReader) (successCount, failedCount int, err error) {
   103  	serverDetails, err := dc.ServerDetails()
   104  	if errorutils.CheckError(err) != nil {
   105  		return 0, 0, err
   106  	}
   107  	servicesManager, err := utils.CreateDeleteServiceManager(serverDetails, dc.Threads(), dc.retries, dc.retryWaitTimeMilliSecs, dc.DryRun())
   108  	if err != nil {
   109  		return 0, 0, err
   110  	}
   111  	deletedCount, err := servicesManager.DeleteFiles(reader)
   112  	if err != nil {
   113  		return 0, 0, err
   114  	}
   115  	length, err := reader.Length()
   116  	if err != nil {
   117  		return 0, 0, err
   118  	}
   119  	return deletedCount, length - deletedCount, err
   120  }
   121  
   122  func getDeleteParams(f *spec.File) (deleteParams services.DeleteParams, err error) {
   123  	deleteParams = services.NewDeleteParams()
   124  	deleteParams.CommonParams, err = f.ToCommonParams()
   125  	if err != nil {
   126  		return
   127  	}
   128  	deleteParams.ExcludeArtifacts, err = f.IsExcludeArtifacts(false)
   129  	if err != nil {
   130  		return
   131  	}
   132  	deleteParams.IncludeDeps, err = f.IsIncludeDeps(false)
   133  	if err != nil {
   134  		return
   135  	}
   136  	deleteParams.Recursive, err = f.IsRecursive(true)
   137  	return
   138  }