Skip to content

Commit 903f16a

Browse files
authored
Refactor nested YAML value extraction (#52212)
1 parent 0137e49 commit 903f16a

2 files changed

Lines changed: 40 additions & 21 deletions

File tree

pkg/parser/schema_suggestions.go

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,10 @@ func extractNestedYAMLValue(yamlContent, parentKey, childKey string) string {
545545
if err != nil {
546546
return ""
547547
}
548-
escapedChild := regexp.QuoteMeta(childKey)
548+
scalarMatchers, err := buildNestedYAMLScalarMatchers(regexp.QuoteMeta(childKey))
549+
if err != nil {
550+
return ""
551+
}
549552

550553
parentIndent := -1
551554
childIndent := -1 // indent of direct children (set on first non-blank line inside the block)
@@ -581,30 +584,40 @@ func extractNestedYAMLValue(yamlContent, parentKey, childKey string) string {
581584
continue
582585
}
583586

584-
// Try to match child key with its value (single-quoted, double-quoted, unquoted).
585-
childPrefix := `^\s+` + escapedChild + `[ \t]*:[ \t]*`
586-
//nolint:regexpdynamicpattern // The child key is quoted before compilation.
587-
reSingle, err := regexp.Compile(childPrefix + `'([^'\n]+)'`)
588-
if err != nil {
589-
return ""
590-
}
591-
if match := reSingle.FindStringSubmatch(line); len(match) >= 2 {
592-
return strings.TrimSpace(match[1])
593-
}
594-
//nolint:regexpdynamicpattern // The child key is quoted before compilation.
595-
reDouble, err := regexp.Compile(childPrefix + `"([^"\n]+)"`)
596-
if err != nil {
597-
return ""
598-
}
599-
if match := reDouble.FindStringSubmatch(line); len(match) >= 2 {
600-
return strings.TrimSpace(match[1])
587+
if value := extractNestedYAMLScalar(line, scalarMatchers); value != "" {
588+
return value
601589
}
590+
}
591+
592+
return ""
593+
}
594+
595+
// buildNestedYAMLScalarMatchers compiles the scalar value patterns for a child key once,
596+
// so they can be reused across every candidate line inside the parent block.
597+
func buildNestedYAMLScalarMatchers(escapedChild string) ([]*regexp.Regexp, error) {
598+
childPrefix := `^\s+` + escapedChild + `[ \t]*:[ \t]*`
599+
valuePatterns := []string{
600+
childPrefix + `'([^'\n]+)'`,
601+
childPrefix + `"([^"\n]+)"`,
602+
childPrefix + `([^'"\n#][^\n#]*?)(?:[ \t]*#.*)?$`,
603+
}
604+
605+
matchers := make([]*regexp.Regexp, 0, len(valuePatterns))
606+
for _, valuePattern := range valuePatterns {
602607
//nolint:regexpdynamicpattern // The child key is quoted before compilation.
603-
reUnquoted, err := regexp.Compile(childPrefix + `([^'"\n#][^\n#]*?)(?:[ \t]*#.*)?$`)
608+
valueRegexp, err := regexp.Compile(valuePattern)
604609
if err != nil {
605-
return ""
610+
return nil, err
606611
}
607-
if match := reUnquoted.FindStringSubmatch(line); len(match) >= 2 {
612+
matchers = append(matchers, valueRegexp)
613+
}
614+
615+
return matchers, nil
616+
}
617+
618+
func extractNestedYAMLScalar(line string, matchers []*regexp.Regexp) string {
619+
for _, valueRegexp := range matchers {
620+
if match := valueRegexp.FindStringSubmatch(line); len(match) >= 2 {
608621
return strings.TrimSpace(match[1])
609622
}
610623
}

pkg/parser/schema_suggestions_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,12 @@ func TestExtractYAMLValueAtPath(t *testing.T) {
405405
path: "/permissions/contents",
406406
wantValue: "raed",
407407
},
408+
{
409+
name: "nested path - unquoted value with inline comment",
410+
yaml: "permissions:\n contents: raed # typo\n",
411+
path: "/permissions/contents",
412+
wantValue: "raed",
413+
},
408414
{
409415
name: "three-level path returns empty",
410416
yaml: "a:\n b:\n c: value\n",

0 commit comments

Comments
 (0)