@@ -32,10 +32,15 @@ func Set(data []byte, docIndex int, yamlPath string, value any, opts ...goyaml.E
3232// SetLiteral replaces the node at yamlPath, rendering multiline strings as a
3333// literal block scalar (`|`).
3434//
35- // goccy/go-yaml's ReplaceWithNode corrupts literal block scalars that contain
36- // YAML-special characters (*, !, etc.) at the start of lines. To work around
37- // this, if the existing node is already a literal block scalar we replace the
38- // content directly in the byte stream, preserving the original indentation.
35+ // goccy/go-yaml's ReplaceWithNode corrupts literal block scalars because
36+ // MappingValueNode.Replace adjusts Position.Column via AddColumn but
37+ // LiteralNode.String() uses the raw Origin text, ignoring Position entirely.
38+ // This causes characters to be eaten from the beginning of each content line.
39+ // See https://github.com/goccy/go-yaml/issues/636 for details.
40+ //
41+ // A fix has been submitted upstream (https://github.com/goccy/go-yaml/pull/864).
42+ // Once merged, this workaround (replaceLiteralContent / replaceWithLiteralBlock)
43+ // can be removed and SetLiteral can delegate to Set with UseLiteralStyleIfMultiline.
3944func SetLiteral (data []byte , docIndex int , yamlPath string , content string ) ([]byte , error ) {
4045 ctx , err := newPathContext (data , docIndex , yamlPath )
4146 if err != nil {
@@ -64,6 +69,7 @@ func SetLiteral(data []byte, docIndex int, yamlPath string, content string) ([]b
6469
6570// replaceLiteralContent replaces a literal block scalar's content directly in
6671// the byte stream, avoiding goccy/go-yaml's broken ReplaceWithNode for block scalars.
72+ // TODO: remove once https://github.com/goccy/go-yaml/pull/864 is merged.
6773func replaceLiteralContent (data []byte , ln * ast.LiteralNode , newContent string ) ([]byte , error ) {
6874 origin := ln .Value .GetToken ().Origin
6975 idx := strings .Index (string (data ), origin )
@@ -100,6 +106,7 @@ func replaceLiteralContent(data []byte, ln *ast.LiteralNode, newContent string)
100106// replaceWithLiteralBlock replaces any scalar node with a literal block scalar
101107// via direct byte replacement. This avoids ReplaceWithNode which corrupts
102108// LiteralNode content due to an AddColumn/Origin mismatch in goccy/go-yaml.
109+ // TODO: remove once https://github.com/goccy/go-yaml/pull/864 is merged.
103110func replaceWithLiteralBlock (data []byte , node ast.Node , newContent string ) ([]byte , error ) {
104111 origin := node .GetToken ().Origin
105112 idx := strings .Index (string (data ), origin )
0 commit comments