mirror of
https://github.com/tendermint/tendermint.git
synced 2026-02-03 02:22:04 +00:00
Pull out the library functionality from scripts/confix and move it to internal/libs/confix. Replace scripts/confix with a simple stub that has the same command-line API, but uses the library instead. Related: - Move and update unit tests. - Move scripts/confix/condiff to scripts/condiff. - Update test data for v34, v35, and v36. - Update reference diffs. - Update testdata README.
153 lines
3.4 KiB
Go
153 lines
3.4 KiB
Go
// Program condiff performs a keyspace diff on two TOML documents.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/creachadair/tomledit"
|
|
"github.com/creachadair/tomledit/parser"
|
|
"github.com/creachadair/tomledit/transform"
|
|
)
|
|
|
|
var (
|
|
doDesnake = flag.Bool("desnake", false, "Convert snake_case to kebab-case before comparing")
|
|
)
|
|
|
|
func init() {
|
|
flag.Usage = func() {
|
|
fmt.Fprintf(os.Stderr, `Usage: %[1]s [options] f1 f2
|
|
|
|
Diff the keyspaces of the TOML documents in files f1 and f2.
|
|
The output prints one line per key that differs:
|
|
|
|
-S name -- section exists in f1 but not f2
|
|
+S name -- section exists in f2 but not f1
|
|
-M name -- mapping exists in f1 but not f2
|
|
+M name -- mapping exists in f2 but not f1
|
|
|
|
Comments, order, and values are ignored for comparison purposes.
|
|
|
|
Options:
|
|
`, filepath.Base(os.Args[0]))
|
|
flag.PrintDefaults()
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
if flag.NArg() != 2 {
|
|
log.Fatalf("Usage: %[1]s <lhs> <rhs>", filepath.Base(os.Args[0]))
|
|
}
|
|
lhs := mustParse(flag.Arg(0))
|
|
rhs := mustParse(flag.Arg(1))
|
|
if *doDesnake {
|
|
log.Printf("Converting all names from snake_case to kebab-case")
|
|
fix := transform.SnakeToKebab()
|
|
_ = fix(context.Background(), lhs)
|
|
_ = fix(context.Background(), rhs)
|
|
}
|
|
diffDocs(os.Stdout, lhs, rhs)
|
|
}
|
|
|
|
func mustParse(path string) *tomledit.Document {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
log.Fatalf("Opening TOML input: %v", err)
|
|
}
|
|
defer f.Close()
|
|
doc, err := tomledit.Parse(f)
|
|
if err != nil {
|
|
log.Fatalf("Parsing %q: %v", path, err)
|
|
}
|
|
return doc
|
|
}
|
|
|
|
func allKeys(s *tomledit.Section) []string {
|
|
var keys []string
|
|
s.Scan(func(key parser.Key, _ *tomledit.Entry) bool {
|
|
keys = append(keys, key.String())
|
|
return true
|
|
})
|
|
return keys
|
|
}
|
|
|
|
const (
|
|
delSection = "-S"
|
|
delMapping = "-M"
|
|
addSection = "+S"
|
|
addMapping = "+M"
|
|
|
|
delMapSep = "\n" + delMapping + " "
|
|
addMapSep = "\n" + addMapping + " "
|
|
)
|
|
|
|
func diffDocs(w io.Writer, lhs, rhs *tomledit.Document) {
|
|
diffSections(w, lhs.Global, rhs.Global)
|
|
lsec, rsec := lhs.Sections, rhs.Sections
|
|
transform.SortSectionsByName(lsec)
|
|
transform.SortSectionsByName(rsec)
|
|
|
|
i, j := 0, 0
|
|
for i < len(lsec) && j < len(rsec) {
|
|
if lsec[i].Name.Before(rsec[j].Name) {
|
|
fmt.Fprintln(w, delSection, lsec[i].Name)
|
|
fmt.Fprintln(w, delMapping, strings.Join(allKeys(lsec[i]), delMapSep))
|
|
i++
|
|
} else if rsec[j].Name.Before(lsec[i].Name) {
|
|
fmt.Fprintln(w, addSection, rsec[j].Name)
|
|
fmt.Fprintln(w, addMapping, strings.Join(allKeys(rsec[j]), addMapSep))
|
|
j++
|
|
} else {
|
|
diffSections(w, lsec[i], rsec[j])
|
|
i++
|
|
j++
|
|
}
|
|
}
|
|
for ; i < len(lsec); i++ {
|
|
fmt.Fprintln(w, delSection, lsec[i].Name)
|
|
fmt.Fprintln(w, delMapping, strings.Join(allKeys(lsec[i]), delMapSep))
|
|
}
|
|
for ; j < len(rsec); j++ {
|
|
fmt.Fprintln(w, addSection, rsec[j].Name)
|
|
fmt.Fprintln(w, addMapping, strings.Join(allKeys(rsec[j]), addMapSep))
|
|
}
|
|
}
|
|
|
|
func diffSections(w io.Writer, lhs, rhs *tomledit.Section) {
|
|
diffKeys(w, allKeys(lhs), allKeys(rhs))
|
|
}
|
|
|
|
func diffKeys(w io.Writer, lhs, rhs []string) {
|
|
sort.Strings(lhs)
|
|
sort.Strings(rhs)
|
|
|
|
i, j := 0, 0
|
|
for i < len(lhs) && j < len(rhs) {
|
|
if lhs[i] < rhs[j] {
|
|
fmt.Fprintln(w, delMapping, lhs[i])
|
|
i++
|
|
} else if lhs[i] > rhs[j] {
|
|
fmt.Fprintln(w, addMapping, rhs[j])
|
|
j++
|
|
} else {
|
|
i++
|
|
j++
|
|
}
|
|
}
|
|
for ; i < len(lhs); i++ {
|
|
fmt.Fprintln(w, delMapping, lhs[i])
|
|
}
|
|
for ; j < len(rhs); j++ {
|
|
fmt.Fprintln(w, addMapping, rhs[j])
|
|
}
|
|
}
|