Skip to content

Instantly share code, notes, and snippets.

@shahidhk
Created October 14, 2019 04:53
Show Gist options
  • Select an option

  • Save shahidhk/f39bf76e5fdf1e7a364638de1d12114b to your computer and use it in GitHub Desktop.

Select an option

Save shahidhk/f39bf76e5fdf1e7a364638de1d12114b to your computer and use it in GitHub Desktop.

Revisions

  1. shahidhk created this gist Oct 14, 2019.
    96 changes: 96 additions & 0 deletions diff.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@
    // usage:
    // DiffYaml(d2, d1, os.Stdout)
    package diff

    import (
    "fmt"
    "io"
    "strings"

    "github.com/aryann/difflib"
    "github.com/ghodss/yaml"
    "github.com/mgutz/ansi"
    )

    func yamlToMap(y []byte) (map[string]string, error) {
    var obj map[string]interface{}
    m := make(map[string]string)
    err := yaml.Unmarshal(y, &obj)
    if err != nil {
    return nil, err
    }
    for key, value := range obj {
    val, err := yaml.Marshal(value)
    if err != nil {
    return m, err
    }
    m[key] = string(val)
    }
    return m, nil
    }

    func DiffYaml(oldYaml, newYaml []byte, to io.Writer) error {
    oldIndex, err := yamlToMap(oldYaml)
    if err != nil {
    return err
    }
    newIndex, err := yamlToMap(newYaml)
    if err != nil {
    return err
    }
    for key, oldContent := range oldIndex {
    if newContent, ok := newIndex[key]; ok {
    if oldContent != newContent {
    // modified
    fmt.Fprintf(to, ansi.Color("%s has changed:", "yellow")+"\n", key)
    PrintDiff(oldContent, newContent, to)
    }
    } else {
    // removed
    fmt.Fprintf(to, ansi.Color("%s has been removed:", "yellow")+"\n", key)
    PrintDiff(oldContent, "", to)
    }
    }

    for key, newContent := range newIndex {
    if _, ok := oldIndex[key]; !ok {
    // added
    fmt.Fprintf(to, ansi.Color("%s has been added:", "yellow")+"\n", key)
    PrintDiff("", newContent, to)
    }
    }
    return nil
    }

    func PrintDiff(before, after string, to io.Writer) {
    diffs := difflib.Diff(strings.Split(before, "\n"), strings.Split(after, "\n"))

    for _, diff := range diffs {
    text := diff.Payload

    switch diff.Delta {
    case difflib.RightOnly:
    fmt.Fprintf(to, "%s\n", ansi.Color("+ "+text, "green"))
    case difflib.LeftOnly:
    fmt.Fprintf(to, "%s\n", ansi.Color("- "+text, "red"))
    case difflib.Common:
    fmt.Fprintf(to, "%s\n", " "+text)
    }
    }
    }

    func DiffString(before, after string, to io.Writer) {
    diffs := difflib.Diff(strings.Split(before, "\n"), strings.Split(after, "\n"))

    for _, diff := range diffs {
    text := diff.Payload

    switch diff.Delta {
    case difflib.RightOnly:
    fmt.Fprintf(to, "%s\n", ansi.Color("+ "+text, "green"))
    case difflib.LeftOnly:
    fmt.Fprintf(to, "%s\n", ansi.Color("- "+text, "red"))
    }
    }

    }