-
Notifications
You must be signed in to change notification settings - Fork 13
/
rm.go
123 lines (105 loc) · 3.23 KB
/
rm.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
package main
import (
"fmt"
"path/filepath"
typ "github.com/aos-dev/go-storage/v2/types"
"github.com/c-bata/go-prompt"
"github.com/qingstor/noah/task"
"github.com/spf13/cobra"
"github.com/qingstor/qsctl/v2/cmd/qsctl/shellutils"
"github.com/qingstor/qsctl/v2/cmd/qsctl/taskutils"
"github.com/qingstor/qsctl/v2/constants"
"github.com/qingstor/qsctl/v2/pkg/i18n"
"github.com/qingstor/qsctl/v2/utils"
)
type rmFlags struct {
recursive bool
}
var rmFlag = rmFlags{}
// RmCommand will handle remove object command.
var RmCommand = &cobra.Command{
Use: "rm qs://<bucket_name>/<object_key>",
Short: i18n.Sprintf("remove a remote object"),
Long: i18n.Sprintf("qsctl rm remove the object with given object key"),
Example: utils.AlignPrintWithColon(
i18n.Sprintf("Remove a single object: qsctl rm qs://bucket-name/object-key"),
i18n.Sprintf("Remove objects with prefix: qsctl rm qs://bucket-name/prefix -r"),
),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceErrors = true // handle runtime errors with i18n, do not show error
if err := rmRun(cmd, args); err != nil {
i18n.Fprintf(cmd.OutOrStderr(), "Execute %s command error: %s\n", "rm", err.Error())
return err
}
return nil
},
}
func initRmFlag() {
RmCommand.Flags().BoolVarP(&rmFlag.recursive, constants.RecursiveFlag, "r",
false, i18n.Sprintf("recursively delete keys under a specific prefix"))
}
func rmRun(c *cobra.Command, args []string) (err error) {
silenceUsage(c) // silence usage when handled error returns
rootTask := taskutils.NewAtStorageTask(10)
workDir, err := utils.ParseAtStorageInput(rootTask, args[0])
if err != nil {
return
}
if rootTask.GetType() == typ.ObjectTypeDir && !rmFlag.recursive {
return fmt.Errorf(i18n.Sprintf("-r is required to remove a directory"))
}
if rmFlag.recursive && rootTask.GetType() != typ.ObjectTypeDir {
return fmt.Errorf(i18n.Sprintf("path should be a directory while -r is set"))
}
key := filepath.Join(workDir, rootTask.GetPath())
if rmFlag.recursive {
t := task.NewDeleteDir(rootTask)
t.SetHandleObjCallback(func(o *typ.Object) {
i18n.Fprintf(c.OutOrStdout(), "<%s> removed\n", o.Name)
})
t.Run(c.Context())
if t.GetFault().HasError() {
return t.GetFault()
}
i18n.Fprintf(c.OutOrStdout(), "Dir <%s> removed.\n", key)
return nil
}
t := task.NewDeleteFile(rootTask)
t.Run(c.Context())
if t.GetFault().HasError() {
return t.GetFault()
}
i18n.Fprintf(c.OutOrStdout(), "File <%s> removed.\n", key)
return nil
}
// rmShellHandler handle rm in shell
type rmShellHandler struct{}
func (r rmShellHandler) preRunE(args []string) error {
err := RmCommand.Flags().Parse(args)
if err != nil {
return err
}
if len(RmCommand.Flags().Args()) <= 0 {
return fmt.Errorf(i18n.Sprintf("Error: at least one arg is needed for %s", "rm"))
}
_, _, key, err := utils.ParseQsPath(RmCommand.Flags().Args()[0])
if err != nil {
return err
}
// try to get confirm input
input := prompt.Input(
i18n.Sprintf("confirm to remove <%s>? [y/N] ", key),
noSuggests)
if !shellutils.CheckYes(input) {
return fmt.Errorf(i18n.Sprintf("not confirmed"))
}
return nil
}
func (r rmShellHandler) postRun(_ error) {
resetRmFlag()
return
}
func resetRmFlag() {
rmFlag = rmFlags{}
}