in internal/packages/changelog/yaml.go [20:100]
func PatchYAML(d []byte, patch Revision) ([]byte, error) {
var nodes []yaml.Node
err := yaml.Unmarshal(d, &nodes)
if err != nil {
return nil, err
}
patchVersion, err := semver.NewVersion(patch.Version)
if err != nil {
return nil, err
}
patched := false
var result []yaml.Node
for _, node := range nodes {
if patched {
result = append(result, node)
continue
}
var entry Revision
err := node.Decode(&entry)
if err != nil {
result = append(result, node)
continue
}
foundVersion, err := semver.NewVersion(entry.Version)
if err != nil {
return nil, err
}
if foundVersion.GreaterThan(patchVersion) {
return nil, errors.New("cannot add change to old version")
}
var newNode yaml.Node
if patchVersion.Equal(foundVersion) {
// Add the change to current entry.
entry.Changes = append(patch.Changes, entry.Changes...)
err := newNode.Encode(entry)
if err != nil {
return nil, err
}
// Keep comments of the original node.
newNode.HeadComment = node.HeadComment
newNode.LineComment = node.LineComment
newNode.FootComment = node.FootComment
// Quote version to keep common style.
setYamlMapValueStyle(&newNode, "version", yaml.DoubleQuotedStyle)
result = append(result, newNode)
patched = true
continue
}
// Add the change before first entry
err = newNode.Encode(patch)
if err != nil {
return nil, err
}
// If there is a comment on top, leave it there.
if node.HeadComment != "" {
newNode.HeadComment = node.HeadComment
node.HeadComment = ""
}
// Quote version to keep common style.
setYamlMapValueStyle(&newNode, "version", yaml.DoubleQuotedStyle)
result = append(result, newNode, node)
patched = true
}
if !patched {
return nil, errors.New("changelog entry was not added, this is probably a bug")
}
d, err = formatResult(result)
if err != nil {
return nil, fmt.Errorf("failed to format manifest: %w", err)
}
return d, nil
}