Patcher/standard.go

75 lines
1.9 KiB
Go

package main
import (
"fmt"
"os"
"strings"
)
// applyStandardModifications handles `standard` type patches
func applyStandardModifications(filePath string, modifications []string) error {
contentBytes, err := os.ReadFile(filePath)
if err != nil {
return fmt.Errorf("failed to read file: %v", err)
}
lines := strings.Split(string(contentBytes), "\n")
var delBlock []string
var addBlock []string
var patchBlocks []struct {
del []string
add []string
}
// Group lines into delete and add blocks
for _, line := range modifications {
if strings.HasPrefix(line, "-") {
delBlock = append(delBlock, strings.TrimPrefix(line, "-"))
} else if strings.HasPrefix(line, "+") {
addBlock = append(addBlock, strings.TrimPrefix(line, "+"))
} else if line == "" && len(delBlock) > 0 {
patchBlocks = append(patchBlocks, struct {
del []string
add []string
}{append([]string{}, delBlock...), append([]string{}, addBlock...)})
delBlock = nil
addBlock = nil
}
}
if len(delBlock) > 0 || len(addBlock) > 0 {
patchBlocks = append(patchBlocks, struct {
del []string
add []string
}{delBlock, addBlock})
}
// Apply each block
for _, patch := range patchBlocks {
matchIndex := -1
for i := 0; i <= len(lines)-len(patch.del); i++ {
matched := true
for j := range patch.del {
if strings.TrimSpace(lines[i+j]) != strings.TrimSpace(patch.del[j]) {
matched = false
break
}
}
if matched {
matchIndex = i
break
}
}
if matchIndex == -1 {
return fmt.Errorf("patch block not found in file: %v", patch.del)
}
// Replace matched block
newLines := append([]string{}, lines[:matchIndex]...)
newLines = append(newLines, patch.add...)
newLines = append(newLines, lines[matchIndex+len(patch.del):]...)
lines = newLines
}
// Write updated file
return os.WriteFile(filePath, []byte(strings.Join(lines, "\n")), 0644)
}