/
cli.go
171 lines (147 loc) · 4.36 KB
/
cli.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//<developer>
// <name>linapex 曹一峰</name>
// <email>linapex@163.com</email>
// <wx>superexc</wx>
// <qqgroup>128148617</qqgroup>
// <url>https://jsq.ink</url>
// <role>pku engineer</role>
// <date>2019-03-16 19:39:52</date>
//</624455939822456832>
/*
版权所有IBM公司。保留所有权利。
SPDX许可证标识符:Apache-2.0
**/
package common
import (
"fmt"
"io"
"os"
"path/filepath"
"github.com/hyperledger/fabric/cmd/common/comm"
"github.com/hyperledger/fabric/cmd/common/signer"
"gopkg.in/alecthomas/kingpin.v2"
)
const (
saveConfigCommand = "saveConfig"
)
var (
//用于终止CLI的函数
terminate = os.Exit
//用于将输出重定向到的函数
outWriter io.Writer = os.Stderr
//CLI参数
mspID *string
tlsCA, tlsCert, tlsKey, userKey, userCert **os.File
configFile *string
)
//cli command定义添加到cli的命令
//通过外部消费者。
type CLICommand func(Config) error
//cli定义命令行解释器
type CLI struct {
app *kingpin.Application
dispatchers map[string]CLICommand
}
//new cli创建具有给定名称和帮助消息的新cli
func NewCLI(name, help string) *CLI {
return &CLI{
app: kingpin.New(name, help),
dispatchers: make(map[string]CLICommand),
}
}
//命令将新的顶级命令添加到CLI
func (cli *CLI) Command(name, help string, onCommand CLICommand) *kingpin.CmdClause {
cmd := cli.app.Command(name, help)
cli.dispatchers[name] = onCommand
return cmd
}
//run使cli处理参数并执行带有标志的命令
func (cli *CLI) Run(args []string) {
configFile = cli.app.Flag("configFile", "Specifies the config file to load the configuration from").String()
persist := cli.app.Command(saveConfigCommand, fmt.Sprintf("Save the config passed by flags into the file specified by --configFile"))
configureFlags(cli.app)
command := kingpin.MustParse(cli.app.Parse(args))
if command == persist.FullCommand() {
if *configFile == "" {
out("--configFile must be used to specify the configuration file")
return
}
persistConfig(parseFlagsToConfig(), *configFile)
return
}
var conf Config
if *configFile == "" {
conf = parseFlagsToConfig()
} else {
conf = loadConfig(*configFile)
}
f, exists := cli.dispatchers[command]
if !exists {
out("Unknown command:", command)
terminate(1)
return
}
err := f(conf)
if err != nil {
out(err)
terminate(1)
return
}
}
func configureFlags(persistCommand *kingpin.Application) {
//TLS标志
tlsCA = persistCommand.Flag("peerTLSCA", "Sets the TLS CA certificate file path that verifies the TLS peer's certificate").File()
tlsCert = persistCommand.Flag("tlsCert", "(Optional) Sets the client TLS certificate file path that is used when the peer enforces client authentication").File()
tlsKey = persistCommand.Flag("tlsKey", "(Optional) Sets the client TLS key file path that is used when the peer enforces client authentication").File()
//注册标志
userKey = persistCommand.Flag("userKey", "Sets the user's key file path that is used to sign messages sent to the peer").File()
userCert = persistCommand.Flag("userCert", "Sets the user's certificate file path that is used to authenticate the messages sent to the peer").File()
mspID = persistCommand.Flag("MSP", "Sets the MSP ID of the user, which represents the CA(s) that issued its user certificate").String()
}
func persistConfig(conf Config, file string) {
if err := conf.ToFile(file); err != nil {
out("Failed persisting configuration:", err)
terminate(1)
}
}
func loadConfig(file string) Config {
conf, err := ConfigFromFile(file)
if err != nil {
out("Failed loading config", err)
terminate(1)
return Config{}
}
return conf
}
func parseFlagsToConfig() Config {
conf := Config{
SignerConfig: signer.Config{
MSPID: *mspID,
IdentityPath: evaluateFileFlag(userCert),
KeyPath: evaluateFileFlag(userKey),
},
TLSConfig: comm.Config{
KeyPath: evaluateFileFlag(tlsKey),
CertPath: evaluateFileFlag(tlsCert),
PeerCACertPath: evaluateFileFlag(tlsCA),
},
}
return conf
}
func evaluateFileFlag(f **os.File) string {
if f == nil {
return ""
}
if *f == nil {
return ""
}
path, err := filepath.Abs((*f).Name())
if err != nil {
out("Failed listing", (*f).Name(), ":", err)
terminate(1)
}
return path
}
func out(a ...interface{}) {
fmt.Fprintln(outWriter, a...)
}