github.com/osievert/jfrog-cli-core@v1.2.7/artifactory/commands/generic/delete.go (about)

     1  package generic
     2  
     3  import (
     4  	"github.com/jfrog/jfrog-cli-core/artifactory/spec"
     5  	"github.com/jfrog/jfrog-cli-core/artifactory/utils"
     6  	"github.com/jfrog/jfrog-client-go/artifactory/services"
     7  	clientutils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
     8  	"github.com/jfrog/jfrog-client-go/utils/errorutils"
     9  	"github.com/jfrog/jfrog-client-go/utils/io/content"
    10  )
    11  
    12  type DeleteCommand struct {
    13  	GenericCommand
    14  	quiet   bool
    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) Quiet() bool {
    32  	return dc.quiet
    33  }
    34  
    35  func (dc *DeleteCommand) SetQuiet(quiet bool) *DeleteCommand {
    36  	dc.quiet = quiet
    37  	return dc
    38  }
    39  
    40  func (dc *DeleteCommand) CommandName() string {
    41  	return "rt_delete"
    42  }
    43  
    44  func (dc *DeleteCommand) Run() error {
    45  	reader, err := dc.GetPathsToDelete()
    46  	if err != nil {
    47  		return err
    48  	}
    49  	defer reader.Close()
    50  	allowDelete := true
    51  	if !dc.quiet {
    52  		allowDelete, err = utils.ConfirmDelete(reader)
    53  		if err != nil {
    54  			return err
    55  		}
    56  	}
    57  	if allowDelete {
    58  		success, failed, err := dc.DeleteFiles(reader)
    59  		result := dc.Result()
    60  		result.SetFailCount(failed)
    61  		result.SetSuccessCount(success)
    62  		return err
    63  	}
    64  	return nil
    65  }
    66  
    67  func (dc *DeleteCommand) GetPathsToDelete() (*content.ContentReader, error) {
    68  	rtDetails, err := dc.RtDetails()
    69  	if errorutils.CheckError(err) != nil {
    70  		return nil, err
    71  	}
    72  	servicesManager, err := utils.CreateServiceManager(rtDetails, dc.DryRun())
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	temp := []*content.ContentReader{}
    77  	defer func() {
    78  		for _, reader := range temp {
    79  			reader.Close()
    80  		}
    81  	}()
    82  	for i := 0; i < len(dc.Spec().Files); i++ {
    83  		deleteParams, err := getDeleteParams(dc.Spec().Get(i))
    84  		if err != nil {
    85  			return nil, err
    86  		}
    87  		reader, err := servicesManager.GetPathsToDelete(deleteParams)
    88  		if err != nil {
    89  			return nil, err
    90  		}
    91  		temp = append(temp, reader)
    92  	}
    93  	tempMergedReader, err := content.MergeReaders(temp, content.DefaultKey)
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  	defer tempMergedReader.Close()
    98  
    99  	// After merge, remove top chain dirs as we may encounter duplicates and collisions between files and directories to delete.
   100  	// For example:
   101  	// Reader1: {"a"}
   102  	// Reader2: {"a/b","a/c"}
   103  	// After merge, received a Reader: {"a","a/b","a/c"}.
   104  	// If "a" is deleted prior to "a/b" or "a/c", the delete operation returns a failure.
   105  	return clientutils.ReduceTopChainDirResult(clientutils.ResultItem{}, tempMergedReader)
   106  }
   107  
   108  func (dc *DeleteCommand) DeleteFiles(reader *content.ContentReader) (successCount, failedCount int, err error) {
   109  	rtDetails, err := dc.RtDetails()
   110  	if errorutils.CheckError(err) != nil {
   111  		return 0, 0, err
   112  	}
   113  	servicesManager, err := utils.CreateDeleteServiceManager(rtDetails, dc.Threads(), dc.DryRun())
   114  	if err != nil {
   115  		return 0, 0, err
   116  	}
   117  	deletedCount, err := servicesManager.DeleteFiles(reader)
   118  	length, err := reader.Length()
   119  	if err != nil {
   120  		return 0, 0, err
   121  	}
   122  	return deletedCount, length - deletedCount, err
   123  }
   124  
   125  func getDeleteParams(f *spec.File) (deleteParams services.DeleteParams, err error) {
   126  	deleteParams = services.NewDeleteParams()
   127  	deleteParams.ArtifactoryCommonParams = f.ToArtifactoryCommonParams()
   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  }