go scratch code for atproto

basic diff support

+97
+96
cmd/glot/diff.go
··· 1 + package main 2 + 3 + import ( 4 + "context" 5 + "encoding/json" 6 + "fmt" 7 + "reflect" 8 + 9 + "github.com/bluesky-social/indigo/atproto/data" 10 + "github.com/bluesky-social/indigo/atproto/syntax" 11 + 12 + "github.com/urfave/cli/v3" 13 + "github.com/yudai/gojsondiff" 14 + "github.com/yudai/gojsondiff/formatter" 15 + ) 16 + 17 + var cmdDiff = &cli.Command{ 18 + Name: "diff", 19 + Usage: "print differences for any updated lexicon schemas", 20 + ArgsUsage: `<file-or-dir>*`, 21 + Flags: []cli.Flag{ 22 + &cli.StringFlag{ 23 + Name: "lexicons-dir", 24 + Value: "./lexicons/", 25 + Usage: "base directory for project Lexicon files", 26 + Sources: cli.EnvVars("LEXICONS_DIR"), 27 + }, 28 + }, 29 + Action: runDiff, 30 + } 31 + 32 + func runDiff(ctx context.Context, cmd *cli.Command) error { 33 + return compareSchemas(ctx, cmd, diffCompare) 34 + } 35 + 36 + func diffCompare(ctx context.Context, cmd *cli.Command, nsid syntax.NSID, localJSON, remoteJSON json.RawMessage) error { 37 + 38 + // skip schemas which aren't in both locations 39 + if localJSON == nil || remoteJSON == nil { 40 + return nil 41 + } 42 + 43 + local, err := data.UnmarshalJSON(localJSON) 44 + if err != nil { 45 + return err 46 + } 47 + remote, err := data.UnmarshalJSON(remoteJSON) 48 + if err != nil { 49 + return err 50 + } 51 + delete(local, "$type") 52 + delete(remote, "$type") 53 + 54 + // skip if rqual 55 + if reflect.DeepEqual(local, remote) { 56 + return nil 57 + } 58 + 59 + // re-marshal with type removed 60 + localJSON, err = json.Marshal(local) 61 + if err != nil { 62 + return err 63 + } 64 + remoteJSON, err = json.Marshal(remote) 65 + if err != nil { 66 + return err 67 + } 68 + 69 + // compute and print diff 70 + var diffString string 71 + var outJSON map[string]interface{} 72 + differ := gojsondiff.New() 73 + d, err := differ.Compare(localJSON, remoteJSON) 74 + if err != nil { 75 + return nil 76 + } 77 + json.Unmarshal(localJSON, &outJSON) 78 + config := formatter.AsciiFormatterConfig{ 79 + //ShowArrayIndex: true, 80 + // TODO: Coloring: c.Bool("coloring"), 81 + Coloring: true, 82 + } 83 + formatter := formatter.NewAsciiFormatter(outJSON, config) 84 + diffString, err = formatter.Format(d) 85 + if err != nil { 86 + return err 87 + } 88 + 89 + fmt.Printf("diff %s\n", nsid) 90 + fmt.Println("--- local") 91 + fmt.Println("+++ remote") 92 + fmt.Print(diffString) 93 + fmt.Println() 94 + 95 + return nil 96 + }
+1
cmd/glot/main.go
··· 39 39 cmdLint, 40 40 cmdPull, 41 41 cmdStatus, 42 + cmdDiff, 42 43 } 43 44 return app.Run(context.Background(), args) 44 45 }