-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathparser.go
More file actions
94 lines (87 loc) · 1.97 KB
/
parser.go
File metadata and controls
94 lines (87 loc) · 1.97 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
package local
import (
"bufio"
"fmt"
"os"
"reflect"
"strconv"
"strings"
)
// Tags are the permitted tags within a test file
type Tags struct {
Name string `rt:"NAME"`
Summary string `rt:"SUMMARY"`
Author string `rt:"AUTHOR,allowmultiple"`
Labels string `rt:"LABELS"`
Repeat int `rt:"REPEAT"`
Issue string `rt:"ISSUE,allowmultiple"`
}
const allowMultiple = "allowmultiple"
func stripOptions(s string) string {
parts := strings.Split(s, ",")
return parts[0]
}
func multiplesAllowed(s string) bool {
parts := strings.Split(s, ",")
if len(parts) < 2 {
return false
}
if parts[1] == allowMultiple {
return true
}
return false
}
// ParseTags reads the provided file and returns all discovered tags or an error
func ParseTags(file string) (*Tags, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer func() { _ = f.Close() }()
tags := &Tags{}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
l := scanner.Text()
if strings.HasPrefix(l, "# ") {
parts := strings.SplitN(l, ":", 2)
if len(parts) < 2 {
// Empty
continue
}
tagName := parts[0][2:]
tagValue := strings.TrimSpace(parts[1])
tt := reflect.TypeOf(*tags)
for i := 0; i < tt.NumField(); i++ {
field := tt.Field(i)
if rt, ok := field.Tag.Lookup("rt"); ok {
if stripOptions(rt) == tagName {
vt := reflect.ValueOf(tags).Elem()
v := vt.Field(i)
switch v.Kind() {
case reflect.Int:
vi, err := strconv.Atoi(tagValue)
if err != nil {
continue
}
v.SetInt(int64(vi))
case reflect.String:
if multiplesAllowed(rt) {
if v.String() != "" {
v.SetString(fmt.Sprintf("%s %s", v.String(), tagValue))
} else {
v.SetString(tagValue)
}
} else {
if v.String() != "" {
return nil, fmt.Errorf("field %s specified multiple times", rt)
}
v.SetString(tagValue)
}
}
}
}
}
}
}
return tags, nil
}