github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/runbits/buildscript/buildscript.go (about) 1 package buildscript 2 3 import ( 4 "bytes" 5 "fmt" 6 "path/filepath" 7 8 "github.com/ActiveState/cli/internal/constants" 9 "github.com/ActiveState/cli/internal/errs" 10 "github.com/ActiveState/cli/internal/fileutils" 11 "github.com/ActiveState/cli/internal/locale" 12 "github.com/ActiveState/cli/pkg/platform/runtime/buildscript" 13 "github.com/ActiveState/cli/pkg/project" 14 "github.com/sergi/go-diff/diffmatchpatch" 15 ) 16 17 func generateDiff(script *buildscript.Script, otherScript *buildscript.Script) (string, error) { 18 local := locale.Tl("diff_local", "local") 19 remote := locale.Tl("diff_remote", "remote") 20 21 var result bytes.Buffer 22 23 diff := diffmatchpatch.New() 24 scriptLines, newScriptLines, lines := diff.DiffLinesToChars(script.String(), otherScript.String()) 25 hunks := diff.DiffMain(scriptLines, newScriptLines, false) 26 hunks = diff.DiffCharsToLines(hunks, lines) 27 hunks = diff.DiffCleanupSemantic(hunks) 28 for i := 0; i < len(hunks); i++ { 29 switch hunk := hunks[i]; hunk.Type { 30 case diffmatchpatch.DiffEqual: 31 result.WriteString(hunk.Text) 32 case diffmatchpatch.DiffDelete: 33 result.WriteString(fmt.Sprintf("<<<<<<< %s\n", local)) 34 result.WriteString(hunk.Text) 35 result.WriteString("=======\n") 36 if i+1 < len(hunks) && hunks[i+1].Type == diffmatchpatch.DiffInsert { 37 result.WriteString(hunks[i+1].Text) 38 i++ // do not process this hunk again 39 } 40 result.WriteString(fmt.Sprintf(">>>>>>> %s\n", remote)) 41 case diffmatchpatch.DiffInsert: 42 result.WriteString(fmt.Sprintf("<<<<<<< %s\n", local)) 43 result.WriteString("=======\n") 44 result.WriteString(hunk.Text) 45 result.WriteString(fmt.Sprintf(">>>>>>> %s\n", remote)) 46 } 47 } 48 49 return result.String(), nil 50 } 51 52 func GenerateAndWriteDiff(proj *project.Project, script *buildscript.Script, otherScript *buildscript.Script) error { 53 result, err := generateDiff(script, otherScript) 54 if err != nil { 55 return errs.Wrap(err, "Could not generate diff between local and remote build scripts") 56 } 57 return fileutils.WriteFile(filepath.Join(proj.Dir(), constants.BuildScriptFileName), []byte(result)) 58 }