-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsubcommand.go
More file actions
132 lines (115 loc) · 2.75 KB
/
subcommand.go
File metadata and controls
132 lines (115 loc) · 2.75 KB
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
package quickclop
import (
"go/ast"
"go/token"
"strings"
)
// 解析子命令标签
func parseSubcommandTag(tag string) (string, string) {
// 去掉首尾的反引号
tag = strings.Trim(tag, "`")
// 解析标签
tags := parseTag(tag)
// 获取subcmd标签
if subcmdTag, ok := tags["subcmd"]; ok {
parts := strings.Split(subcmdTag, ",")
if len(parts) > 0 {
name := strings.TrimSpace(parts[0])
desc := ""
if len(parts) > 1 {
desc = strings.TrimSpace(parts[1])
}
return name, desc
}
}
return "", ""
}
// 检查是否有子命令
func hasSubcommands(fields []FieldInfo) bool {
for _, field := range fields {
if field.IsNested {
return true
}
}
return false
}
// 解析子命令
func parseSubcommands(structType *ast.StructType, file *ast.File, fset *token.FileSet) []SubcommandInfo {
var subcommands []SubcommandInfo
// 遍历字段
for _, field := range structType.Fields.List {
// 检查是否有标签
if field.Tag == nil {
continue
}
// 解析标签
name, desc := parseSubcommandTag(field.Tag.Value)
if name == "" {
continue
}
// 获取字段名
var fieldName string
if len(field.Names) > 0 {
fieldName = field.Names[0].Name
} else {
// 匿名字段,使用类型名作为字段名
switch t := field.Type.(type) {
case *ast.Ident:
fieldName = t.Name
case *ast.SelectorExpr:
fieldName = t.Sel.Name
case *ast.StarExpr:
if ident, ok := t.X.(*ast.Ident); ok {
fieldName = ident.Name
}
}
}
// 获取字段类型
var typeName string
switch t := field.Type.(type) {
case *ast.Ident:
typeName = t.Name
case *ast.SelectorExpr:
if x, ok := t.X.(*ast.Ident); ok {
typeName = x.Name + "." + t.Sel.Name
}
case *ast.StarExpr:
if ident, ok := t.X.(*ast.Ident); ok {
typeName = "*" + ident.Name
}
}
// 查找结构体定义
structDef := findStructDef(typeName, file, fset.Position(field.Pos()).Filename, "")
if structDef == nil {
continue
}
// 解析子命令结构体字段
var cmdFields []FieldInfo
for _, field := range structDef.Fields.List {
if len(field.Names) > 0 {
info := parseField(field, file, fset)
cmdFields = append(cmdFields, info)
}
}
// 添加子命令信息
subcommands = append(subcommands, SubcommandInfo{
Name: fieldName,
Description: desc,
Fields: cmdFields,
StructType: structDef,
})
}
return subcommands
}
// 生成子命令代码
func generateSubcommandCode(subcommand SubcommandInfo, outputFile string) error {
// 这里将使用与主命令类似的模板,但添加子命令处理逻辑
return nil
}
// 子命令信息
type SubcommandInfo struct {
Name string
Description string
Fields []FieldInfo
StructType *ast.StructType
}