@@ -18,12 +18,13 @@ type feature struct {
18
18
Details string
19
19
}
20
20
21
- // Combined regex patterns for metadata fields
22
- var metadataPatterns = map [string ]* regexp.Regexp {
23
- "component" : regexp .MustCompile (`Component:\s*(.*?)(?:\n|$)` ),
24
- "issues" : regexp .MustCompile (`Issues:\s*(.*?)(?:\n|$)` ),
25
- "description" : regexp .MustCompile (`Description:\s*(.*?)(?:\n|$)` ),
26
- "author" : regexp .MustCompile (`Author:\s*(.*?)(?:\n|$)` ),
21
+ // Metadata field definitions
22
+ var (
23
+ metadataFields = []string {"Component" , "Issues" , "Description" , "Author" }
24
+ )
25
+
26
+ func getMetadataPattern (field string ) * regexp.Regexp {
27
+ return regexp .MustCompile (field + `:\s*(.*?)(?:\n|$)` )
27
28
}
28
29
29
30
func validateHeaders (content string ) (bool , string ) {
@@ -49,11 +50,14 @@ func validateMetadataOrder(content string) (bool, string) {
49
50
metadataEnd := 0
50
51
for i := 0 ; i < len (lines ); i ++ {
51
52
line := lines [i ]
52
- if ! strings .HasPrefix (line , "Component:" ) &&
53
- ! strings .HasPrefix (line , "Issues:" ) &&
54
- ! strings .HasPrefix (line , "Description:" ) &&
55
- ! strings .HasPrefix (line , "Author:" ) &&
56
- line != "" {
53
+ isMetadata := false
54
+ for _ , field := range metadataFields {
55
+ if strings .HasPrefix (line , field + ":" ) {
56
+ isMetadata = true
57
+ break
58
+ }
59
+ }
60
+ if ! isMetadata && line != "" {
57
61
metadataEnd = i
58
62
break
59
63
}
@@ -62,11 +66,10 @@ func validateMetadataOrder(content string) (bool, string) {
62
66
// Check if any metadata fields appear after this point
63
67
for i := metadataEnd ; i < len (lines ); i ++ {
64
68
line := lines [i ]
65
- if strings .HasPrefix (line , "Component:" ) ||
66
- strings .HasPrefix (line , "Issues:" ) ||
67
- strings .HasPrefix (line , "Description:" ) ||
68
- strings .HasPrefix (line , "Author:" ) {
69
- return false , fmt .Sprintf ("Metadata field '%s' must appear before any other content" , line )
69
+ for _ , field := range metadataFields {
70
+ if strings .HasPrefix (line , field + ":" ) {
71
+ return false , fmt .Sprintf ("Metadata field '%s' must appear before any other content" , line )
72
+ }
70
73
}
71
74
}
72
75
@@ -75,11 +78,10 @@ func validateMetadataOrder(content string) (bool, string) {
75
78
76
79
func parseContent (source string , content string ) (bool , feature , error ) {
77
80
// Check required sections
78
- requiredSections := []string {"Component:" , "Issues:" , "Description:" , "Author:" }
79
81
isValid := true
80
- for _ , section := range requiredSections {
81
- if ! strings .Contains (content , section ) {
82
- fmt .Printf ("Error: Missing required section '%s' in %s\n " , section , source )
82
+ for _ , field := range metadataFields {
83
+ if ! strings .Contains (content , field + ":" ) {
84
+ fmt .Printf ("Error: Missing required section '%s: ' in %s\n " , field , source )
83
85
isValid = false
84
86
}
85
87
}
@@ -96,7 +98,7 @@ func parseContent(source string, content string) (bool, feature, error) {
96
98
97
99
// Extract metadata fields
98
100
component := ""
99
- if matches := metadataPatterns [ "component" ] .FindStringSubmatch (content ); len (matches ) > 1 {
101
+ if matches := getMetadataPattern ( "Component" ) .FindStringSubmatch (content ); len (matches ) > 1 {
100
102
component = strings .TrimSpace (matches [1 ])
101
103
if ! isValidComponent (component ) {
102
104
fmt .Printf ("Error: Invalid component '%s' in %s. Valid components are: %s. Add more in hack/featuregen/components.go\n " , component , source , listValidComponents ())
@@ -105,7 +107,7 @@ func parseContent(source string, content string) (bool, feature, error) {
105
107
}
106
108
107
109
issuesSection := ""
108
- if matches := metadataPatterns [ "issues" ] .FindStringSubmatch (content ); len (matches ) > 1 {
110
+ if matches := getMetadataPattern ( "Issues" ) .FindStringSubmatch (content ); len (matches ) > 1 {
109
111
issuesSection = matches [1 ]
110
112
}
111
113
issues := regexp .MustCompile (`(\d+)` ).FindAllStringSubmatch (issuesSection , - 1 )
@@ -119,18 +121,19 @@ func parseContent(source string, content string) (bool, feature, error) {
119
121
}
120
122
121
123
description := ""
122
- if matches := metadataPatterns [ "description" ] .FindStringSubmatch (content ); len (matches ) > 1 {
124
+ if matches := getMetadataPattern ( "Description" ) .FindStringSubmatch (content ); len (matches ) > 1 {
123
125
description = strings .TrimSpace (matches [1 ])
124
126
}
125
127
126
128
author := ""
127
- if matches := metadataPatterns [ "author" ] .FindStringSubmatch (content ); len (matches ) > 1 {
129
+ if matches := getMetadataPattern ( "Author" ) .FindStringSubmatch (content ); len (matches ) > 1 {
128
130
author = strings .TrimSpace (matches [1 ])
129
131
}
130
132
131
133
// Extract details (everything after metadata)
132
134
details := ""
133
- if detailsMatch := regexp .MustCompile (`(?s)(?:Component:|Issues:|Description:|Author:).*?\n\n(.*)` ).FindStringSubmatch (content ); len (detailsMatch ) > 1 {
135
+ pattern := `(?s)(?:` + strings .Join (metadataFields , ":|" ) + `:).*?\n\n(.*)`
136
+ if detailsMatch := regexp .MustCompile (pattern ).FindStringSubmatch (content ); len (detailsMatch ) > 1 {
134
137
details = strings .TrimSpace (detailsMatch [1 ])
135
138
}
136
139
0 commit comments