mirror of
https://github.com/siderolabs/talos.git
synced 2025-09-30 18:21:11 +02:00
They got broken after refactoring. Also use this PR to test things before the release. Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
130 lines
3.1 KiB
Go
130 lines
3.1 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
// Package configdiff provides a way to compare two config trees.
|
|
package configdiff
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/hexops/gotextdiff"
|
|
"github.com/hexops/gotextdiff/myers"
|
|
"github.com/hexops/gotextdiff/span"
|
|
|
|
"github.com/siderolabs/talos/pkg/machinery/config"
|
|
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
|
)
|
|
|
|
// Diff outputs (optionally) colorized diff between two machine configurations.
|
|
//
|
|
// One of the resources might be nil.
|
|
func Diff(w io.Writer, oldCfg, newCfg config.Encoder) error {
|
|
var (
|
|
oldYaml, newYaml []byte
|
|
err error
|
|
)
|
|
|
|
if oldCfg != nil {
|
|
oldYaml, err = oldCfg.EncodeBytes(encoder.WithComments(encoder.CommentsDisabled))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if newCfg != nil {
|
|
newYaml, err = newCfg.EncodeBytes(encoder.WithComments(encoder.CommentsDisabled))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
edits := myers.ComputeEdits(span.URIFromPath("a"), string(oldYaml), string(newYaml))
|
|
diff := gotextdiff.ToUnified("a", "b", string(oldYaml), edits)
|
|
|
|
outputDiff(w, diff, true)
|
|
|
|
return nil
|
|
}
|
|
|
|
// DiffToString returns a string representation of the diff between two machine configurations.
|
|
func DiffToString(oldCfg, newCfg config.Encoder) (string, error) {
|
|
var sb strings.Builder
|
|
|
|
err := Diff(&sb, oldCfg, newCfg)
|
|
|
|
return sb.String(), err
|
|
}
|
|
|
|
//nolint:gocyclo
|
|
func outputDiff(w io.Writer, u gotextdiff.Unified, noColor bool) {
|
|
if len(u.Hunks) == 0 {
|
|
return
|
|
}
|
|
|
|
bold := color.New(color.Bold)
|
|
cyan := color.New(color.FgCyan)
|
|
red := color.New(color.FgRed)
|
|
green := color.New(color.FgGreen)
|
|
|
|
if noColor {
|
|
bold.DisableColor()
|
|
cyan.DisableColor()
|
|
red.DisableColor()
|
|
green.DisableColor()
|
|
}
|
|
|
|
bold.Fprintf(w, "--- %s\n", u.From) //nolint:errcheck
|
|
bold.Fprintf(w, "+++ %s\n", u.To) //nolint:errcheck
|
|
|
|
for _, hunk := range u.Hunks {
|
|
fromCount, toCount := 0, 0
|
|
|
|
for _, l := range hunk.Lines {
|
|
switch l.Kind { //nolint:exhaustive
|
|
case gotextdiff.Delete:
|
|
fromCount++
|
|
case gotextdiff.Insert:
|
|
toCount++
|
|
default:
|
|
fromCount++
|
|
toCount++
|
|
}
|
|
}
|
|
|
|
cyan.Fprintf(w, "@@") //nolint:errcheck
|
|
|
|
if fromCount > 1 {
|
|
cyan.Fprintf(w, " -%d,%d", hunk.FromLine, fromCount) //nolint:errcheck
|
|
} else {
|
|
cyan.Fprintf(w, " -%d", hunk.FromLine) //nolint:errcheck
|
|
}
|
|
|
|
if toCount > 1 {
|
|
cyan.Fprintf(w, " +%d,%d", hunk.ToLine, toCount) //nolint:errcheck
|
|
} else {
|
|
cyan.Fprintf(w, " +%d", hunk.ToLine) //nolint:errcheck
|
|
}
|
|
|
|
cyan.Printf(" @@\n") //nolint:errcheck
|
|
|
|
for _, l := range hunk.Lines {
|
|
switch l.Kind { //nolint:exhaustive
|
|
case gotextdiff.Delete:
|
|
red.Fprintf(w, "-%s", l.Content) //nolint:errcheck
|
|
case gotextdiff.Insert:
|
|
green.Fprintf(w, "+%s", l.Content) //nolint:errcheck
|
|
default:
|
|
fmt.Fprintf(w, " %s", l.Content)
|
|
}
|
|
|
|
if !strings.HasSuffix(l.Content, "\n") {
|
|
red.Fprintf(w, "\n\\ No newline at end of file\n") //nolint:errcheck
|
|
}
|
|
}
|
|
}
|
|
}
|