Skip to content

Commit 53e2d63

Browse files
authored
Merge pull request #2 from AlgerDu/develop_20230408
发版前合并
2 parents b19d77d + a88afd9 commit 53e2d63

File tree

7 files changed

+148
-23
lines changed

7 files changed

+148
-23
lines changed

README.md

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,75 @@
66
|:-:|:-|
77
|内置命令|内置 `help``version` 等命令,提供基础支持|
88
|参数绑定|支持将 `flag` 参数绑定到 `struct`|
9-
|全局参数|通过管道模型支持添加自定义的全局参数,进行统一化处理|
9+
|全局参数|通过管道模型支持添加自定义的全局参数,进行统一化处理|
10+
## 示例
11+
12+
### 定义命令及参数
13+
14+
```
15+
type (
16+
HelloCommandFlags struct {
17+
Name string
18+
ClassRoom string `flag:"usage:学生的教师信息"`
19+
}
20+
21+
HelloCommand struct {
22+
*cli.BaseCommand
23+
}
24+
)
25+
```
26+
### 创建命令实例及配置默认参数
27+
28+
```
29+
var (
30+
defaultHelloCommandFlags = &HelloCommandFlags{
31+
Name: "ace",
32+
}
33+
34+
helloCommand = &HelloCommand{
35+
BaseCommand: &cli.BaseCommand{
36+
Meta: &cli.CommandMeta{
37+
Name: "hello",
38+
Usage: "say hello to someone",
39+
},
40+
DefaultFlags: defaultHelloCommandFlags,
41+
},
42+
}
43+
)
44+
```
45+
46+
### 给 cli 应用添加命令
47+
48+
```
49+
func main() {
50+
51+
builder := cli.NewBuilder("hello").
52+
SetUsage("say hello to someone").
53+
AddCommand(helloCommand)
54+
55+
app := builder.Build()
56+
err := app.Run(os.Args)
57+
if err != nil {
58+
fmt.Print(err)
59+
}
60+
}
61+
```
62+
63+
## `flag` 结构体标签
64+
65+
基本试用方式如下:
66+
67+
```
68+
type HelloCommandFlags struct {
69+
Name string
70+
ClassRoom string `flag:"name:class-room,usage:学生的教师信息"`
71+
}
72+
```
73+
74+
支持的项:
75+
||示例|说明|
76+
|:-:|:-|:-|
77+
|`name`|`flag:"name:id"`|定义字段对应的命令行参数,默认是字段名称|
78+
|`aliases`|`flag:"aliases:id\|ID"`|定义一些别名,主要是为了简化参数的输入|
79+
|`require`|`flag:"require"`|是否为必填参数|
80+
|`usage`|`flag:"usage:help 提示信息"`|用于自动生成 help 命令时展示的提示信息|

v1/app.go

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,11 @@ func newInnerApp() *innerApp {
2828
GlobalFlags: []*GlobalFlag{},
2929
}
3030

31-
app.pipelines = []PipelineAction{
32-
app.checkGlobalFlags,
33-
app.findCmdPipelineAction,
34-
app.resolveFlagStruct,
35-
app.runCmd,
36-
}
37-
3831
return app
3932
}
4033

4134
func (app *innerApp) Run(args []string) error {
4235

43-
fmt.Printf("args: %v\n", args)
44-
4536
context := newContext()
4637
context.CommandPaths, context.UserSetFlags = app.anaylseArgs(args)
4738

@@ -129,6 +120,10 @@ func (app *innerApp) findCmdPipelineAction(context *Context) error {
129120

130121
func (app *innerApp) resolveFlagStruct(context *Context) error {
131122

123+
if context.toRunCmd.DefaultFlags == nil {
124+
return nil
125+
}
126+
132127
supportFlags := context.anaylseCmdSupportFlags(context.toRunCmd)
133128
ctxValue := exts.Reflect_New(reflect.TypeOf(context.toRunCmd.DefaultFlags).Elem()).Interface()
134129

@@ -154,7 +149,7 @@ func (app *innerApp) resolveFlagStruct(context *Context) error {
154149
return fmt.Errorf("flag %s must set value", flag.Name)
155150
}
156151

157-
if !set {
152+
if !set && !flag.Multiple {
158153
userSetValaues = append(userSetValaues, fmt.Sprintf("%v", flag.Default))
159154
}
160155

v1/builder.go

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package cli
22

33
type defaultBuilder struct {
4-
app *innerApp
4+
app *innerApp
5+
pipelineSettings *PipelineSettings
56
}
67

78
func NewBuilder(name string) AppBuilder {
@@ -20,12 +21,17 @@ func (builder *defaultBuilder) SetUsage(usage string) AppBuilder {
2021
return builder
2122
}
2223

24+
func (builder *defaultBuilder) SetPipeline(settings *PipelineSettings) AppBuilder {
25+
builder.pipelineSettings = settings
26+
return builder
27+
}
28+
2329
func (builder *defaultBuilder) AddCommand(command Command, opt ...AddCommandOption) AppBuilder {
2430

2531
innerCommand := NewInnerCommand(command)
2632

2733
if innerCommand.Name == "" {
28-
builder.app.Action = innerCommand.Action
34+
builder.app.innerCommand = innerCommand
2935
innerCommand = builder.app.innerCommand
3036

3137
for _, option := range opt {
@@ -44,15 +50,17 @@ func (builder *defaultBuilder) Build() App {
4450
builder.useHelp()
4551
builder.useVersion()
4652

53+
builder.buildPipelines()
54+
4755
return builder.app
4856
}
4957

5058
func (builder *defaultBuilder) useHelp() {
5159

5260
builder.app.GlobalFlags = append(builder.app.GlobalFlags, helpGloblaFlag)
5361

54-
innerHelpCmd := newHelp(builder.app)
55-
builder.AddCommand(innerHelpCmd)
62+
cmd := newHelp(builder.app)
63+
builder.AddCommand(cmd)
5664
}
5765

5866
func (builder *defaultBuilder) useVersion() {
@@ -61,6 +69,27 @@ func (builder *defaultBuilder) useVersion() {
6169

6270
builder.app.GlobalFlags = append(builder.app.GlobalFlags, versionGloblaFlag)
6371

64-
innerHelpCmd := newVersion(builder.app)
65-
builder.AddCommand(innerHelpCmd)
72+
cmd := newVersion(builder.app)
73+
builder.AddCommand(cmd)
74+
}
75+
76+
func (builder *defaultBuilder) buildPipelines() {
77+
settings := builder.pipelineSettings
78+
if settings == nil {
79+
settings = &PipelineSettings{}
80+
}
81+
82+
settings.checkGlobalFlags = []PipelineAction{builder.app.checkGlobalFlags}
83+
settings.findCmd = builder.app.findCmdPipelineAction
84+
settings.resolveFlag = builder.app.resolveFlagStruct
85+
settings.runCmd = builder.app.runCmd
86+
87+
pipelines := []PipelineAction{}
88+
pipelines = append(pipelines, settings.BeferCheckGlobalFlags...)
89+
pipelines = append(pipelines, settings.checkGlobalFlags...)
90+
pipelines = append(pipelines, settings.findCmd)
91+
pipelines = append(pipelines, settings.resolveFlag)
92+
pipelines = append(pipelines, settings.runCmd)
93+
94+
builder.app.pipelines = pipelines
6695
}

v1/cli.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ type (
99

1010
PipelineAction func(*Context) error
1111

12+
// 管道的配置
13+
PipelineSettings struct {
14+
BeferCheckGlobalFlags []PipelineAction // 可以用来做一些初始化的工作
15+
16+
checkGlobalFlags []PipelineAction // 检查全局 flag
17+
findCmd PipelineAction // 查找要执行的命令
18+
resolveFlag PipelineAction // 将用户设置的 flags 解析为要执行命令的 flas 结构体,方便使用
19+
runCmd PipelineAction // 运行命令
20+
}
21+
1222
Command interface {
1323
GetDescripton() *CommandMeta
1424
GetDefaultFlags() any
@@ -28,6 +38,7 @@ type (
2838
AppBuilder interface {
2939
SetVersion(version string) AppBuilder
3040
SetUsage(usage string) AppBuilder
41+
SetPipeline(settings *PipelineSettings) AppBuilder
3142
AddCommand(Command, ...AddCommandOption) AppBuilder
3243
Build() App
3344
}

v1/context.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"os"
5+
"strings"
56
)
67

78
type (
@@ -24,6 +25,7 @@ type (
2425
Stdout Stdout
2526

2627
Value any
28+
Items map[string]any
2729

2830
toRunCmd *innerCommand
2931
}
@@ -32,6 +34,7 @@ type (
3234
func newContext() *Context {
3335

3436
wd, _ := os.Getwd()
37+
wd = strings.ReplaceAll(wd, "\\", "/")
3538

3639
return &Context{
3740
WorkDir: wd,
@@ -40,6 +43,8 @@ func newContext() *Context {
4043
UserSetFlags: map[string][]string{},
4144

4245
Stdout: newStdout(),
46+
47+
Items: map[string]any{},
4348
}
4449
}
4550

v1/flag.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,23 @@ func bindFlagsToStruct(value string, flag *Flag, dst any) error {
173173
}
174174
}
175175

176-
v, err := exts.Reflect_ParseString(value, fieldValue.Kind())
177-
if err != nil {
178-
return err
179-
}
176+
if exts.Reflect_IsArray(fieldValue.Type()) {
177+
178+
v, err := exts.Reflect_ParseString(value, fieldValue.Type().Elem().Kind())
179+
if err != nil {
180+
return err
181+
}
182+
183+
fieldValue.Set(reflect.Append(fieldValue, v))
180184

181-
fieldValue.Set(v)
185+
} else {
186+
v, err := exts.Reflect_ParseString(value, fieldValue.Kind())
187+
if err != nil {
188+
return err
189+
}
190+
191+
fieldValue.Set(v)
192+
}
182193
return nil
183194
}
184195

v1/help.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ func newHelp(
5757

5858
func (cmd *HelpCommand) Action(c *Context) error {
5959

60-
flags := c.Value.(*helpCommandFlag)
60+
flags := &helpCommandFlag{}
61+
if c.Value != nil {
62+
flags = c.Value.(*helpCommandFlag)
63+
}
6164

6265
toDescriptCmd, exist := cmd.app.findCmd(flags.CmdPaths...)
6366
if !exist {

0 commit comments

Comments
 (0)