MCPcopy Create free account
hub / github.com/github/gh-aw / UpdateFieldInFrontmatter

Function UpdateFieldInFrontmatter

pkg/cli/frontmatter_editor.go:19–106  ·  view source on GitHub ↗

UpdateFieldInFrontmatter updates a field in the frontmatter while preserving the original formatting when possible. It tries to preserve whitespace, comments, and formatting by working with the raw frontmatter lines, similar to how addSourceToWorkflow works.

(content, fieldName, fieldValue string)

Source from the content-addressed store, hash-verified

17// when possible. It tries to preserve whitespace, comments, and formatting by working with the raw
18// frontmatter lines, similar to how addSourceToWorkflow works.
19func UpdateFieldInFrontmatter(content, fieldName, fieldValue string) (string, error) {
20 frontmatterEditorLog.Printf("Updating frontmatter field: %s = %s", fieldName, fieldValue)
21
22 // Parse frontmatter using parser package
23 result, err := parser.ExtractFrontmatterFromContent(content)
24 if err != nil {
25 frontmatterEditorLog.Printf("Failed to parse frontmatter: %v", err)
26 return "", fmt.Errorf("failed to parse frontmatter: %w", err)
27 }
28
29 // Try to preserve original frontmatter formatting by manually updating the field
30 if len(result.FrontmatterLines) > 0 {
31 frontmatterEditorLog.Printf("Using raw frontmatter lines for field update (%d lines)", len(result.FrontmatterLines))
32 // Look for existing field in the raw lines
33 fieldUpdated := false
34 skipChildren := false
35 fieldIndentLevel := 0
36 newFrontmatterLines := make([]string, 0, len(result.FrontmatterLines))
37
38 for _, line := range result.FrontmatterLines {
39 trimmedLine := strings.TrimSpace(line)
40
41 // If we just updated the field, skip its child lines (block mapping values)
42 if skipChildren {
43 currentIndent := len(line) - len(strings.TrimLeft(line, " \t"))
44 if currentIndent > fieldIndentLevel {
45 // This line is a child of the replaced field — drop it
46 continue
47 }
48 // No longer in the child block
49 skipChildren = false
50 }
51
52 // Check if this line contains our field
53 if !fieldUpdated && strings.HasPrefix(trimmedLine, fieldName+":") {
54 // Preserve the original indentation and comments
55 leadingSpace := line[:len(line)-len(strings.TrimLeft(line, " \t"))]
56
57 // Check if there's a comment on the same line
58 commentIndex := strings.Index(line, "#")
59 var comment string
60 if commentIndex > strings.Index(line, ":") && commentIndex != -1 {
61 comment = line[commentIndex:]
62 }
63
64 // Update the field value while preserving formatting
65 var updatedLine string
66 if comment != "" {
67 updatedLine = fmt.Sprintf("%s%s: %s %s", leadingSpace, fieldName, fieldValue, comment)
68 } else {
69 updatedLine = fmt.Sprintf("%s%s: %s", leadingSpace, fieldName, fieldValue)
70 }
71 newFrontmatterLines = append(newFrontmatterLines, updatedLine)
72 fieldUpdated = true
73 // Track the indent level so we can skip any child lines that follow
74 fieldIndentLevel = len(leadingSpace)
75 skipChildren = true
76 frontmatterEditorLog.Printf("Updated existing field %s", fieldName)

Calls 4

PrintfMethod · 0.45
ErrorfMethod · 0.45