-
Notifications
You must be signed in to change notification settings - Fork 100
/
command_manager.go
127 lines (106 loc) · 3.11 KB
/
command_manager.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
package lib
import (
"fmt"
"os"
"reflect"
"runtime"
"strings"
"time"
oss "github.com/aliyun/aliyun-oss-go-sdk/oss"
)
var commandLine string
func LogEnd(startT time.Time) {
LogInfo("ossutil run end,cost:%d(ms).\n", time.Now().UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
UnInitLogger()
}
// ParseAndRunCommand parse command line user input, get command and options, then run command
func ParseAndRunCommand() error {
ts := time.Now().UnixNano()
commandLine = getCommandLine()
clearEnv()
args, options, err := ParseArgOptions()
if err != nil {
return err
}
var level = oss.LogOff
strLevel, err := GetString(OptionLogLevel, options)
if strLevel == "info" {
level = oss.Info
} else if strLevel == "debug" {
level = oss.Debug
} else if len(strLevel) > 0 {
return fmt.Errorf("loglevel must be:info|debug")
}
if level > oss.LogOff {
InitLogger(level, logName)
}
startT := time.Now()
LogInfo("ossutil run begin,cmd:%s\n", commandLine)
LogInfo("ossutil version is %s\n", Version)
LogInfo("oss go sdk version is %s\n", oss.Version)
LogInfo("go version is %s\n", runtime.Version())
LogInfo("runtime.NumCPU is %d\n", runtime.NumCPU())
defer LogEnd(startT)
showElapse, err := RunCommand(args, options)
if err != nil {
LogError("%s.\n", err.Error())
return err
}
if showElapse {
te := time.Now().UnixNano()
fmt.Printf("\n%.6f(s) elapsed\n", float64(te-ts)/1e9)
return nil
}
return nil
}
func getCommandLine() string {
return strings.Join(os.Args, " ")
}
func clearEnv() {
if runtime.GOOS == "windows" {
_, renameFilePath := getBinaryPath()
os.Remove(renameFilePath)
}
}
func RunCommand(args []string, options OptionMapType) (bool, error) {
if len(args) == 0 {
if val, _ := GetBool(OptionVersion, options); val {
fmt.Printf("ossutil version: %s\n", Version)
return false, nil
}
args = append(args, "help")
}
command := args[0]
args = args[1:]
cm := CommandManager{}
cm.Init()
showElapse, err := cm.RunCommand(command, args, options)
return showElapse, err
}
// CommandManager is used to manager commands, such as build command map and run command
type CommandManager struct {
commandMap map[string]interface{}
}
// Init build command map
func (cm *CommandManager) Init() {
commandList := GetAllCommands()
cm.commandMap = make(map[string]interface{}, len(commandList))
for _, cmd := range commandList {
name := reflect.ValueOf(cmd).Elem().FieldByName("command").FieldByName("name").String()
cm.commandMap[name] = cmd
}
}
// RunCommand select command from command map, initialize command and run command
func (cm *CommandManager) RunCommand(commandName string, args []string, options OptionMapType) (bool, error) {
if cmd, ok := cm.commandMap[commandName]; ok {
if err := cmd.(Commander).Init(args, options); err != nil {
return false, err
}
if err := cmd.(Commander).RunCommand(); err != nil {
return false, err
}
group := reflect.ValueOf(cmd).Elem().FieldByName("command").FieldByName("group").String()
return group == GroupTypeNormalCommand, nil
}
return false, fmt.Errorf("no such command: \"%s\", please try \"help\" for more information", commandName)
}