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