github.com/rzurga/go-swagger@v0.28.1-0.20211109195225-5d1f453ffa3a/cmd/swagger/commands/diff.go (about) 1 package commands 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "log" 9 "os" 10 11 "errors" 12 13 "github.com/go-openapi/loads" 14 "github.com/go-swagger/go-swagger/cmd/swagger/commands/diff" 15 ) 16 17 // JSONFormat for json 18 const JSONFormat = "json" 19 20 // DiffCommand is a command that generates the diff of two swagger specs. 21 // 22 // There are no specific options for this expansion. 23 type DiffCommand struct { 24 OnlyBreakingChanges bool `long:"break" short:"b" description:"When present, only shows incompatible changes"` 25 Format string `long:"format" short:"f" description:"When present, writes output as json" default:"txt" choice:"txt" choice:"json"` 26 IgnoreFile string `long:"ignore" short:"i" description:"Exception file of diffs to ignore (copy output from json diff format)" default:"none specified"` 27 Destination string `long:"dest" short:"d" description:"Output destination file or stdout" default:"stdout"` 28 Args struct { 29 OldSpec string `positional-arg-name:"{old spec}"` 30 NewSpec string `positional-arg-name:"{new spec}"` 31 } `required:"2" positional-args:"specs" description:"Input specs to be diff-ed"` 32 } 33 34 // Execute diffs the two specs provided 35 func (c *DiffCommand) Execute(_ []string) error { 36 if c.Args.OldSpec == "" || c.Args.NewSpec == "" { 37 return errors.New(`missing arguments for diff command (use --help for more info)`) 38 } 39 40 c.printInfo() 41 42 var ( 43 output io.WriteCloser 44 err error 45 ) 46 if c.Destination != "stdout" { 47 output, err = os.OpenFile(c.Destination, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) 48 if err != nil { 49 return fmt.Errorf("%s: %w", c.Destination, err) 50 } 51 defer func() { 52 _ = output.Close() 53 }() 54 } else { 55 output = os.Stdout 56 } 57 58 diffs, err := c.getDiffs() 59 if err != nil { 60 return err 61 } 62 63 ignores, err := c.readIgnores() 64 if err != nil { 65 return err 66 } 67 68 diffs = diffs.FilterIgnores(ignores) 69 if len(ignores) > 0 { 70 log.Printf("Diff Report Ignored Items from IgnoreFile") 71 for _, eachItem := range ignores { 72 log.Printf("%s", eachItem.String()) 73 } 74 } 75 76 var ( 77 input io.Reader 78 warn error 79 ) 80 if c.Format != JSONFormat && c.OnlyBreakingChanges { 81 input, err, warn = diffs.ReportCompatibility() 82 } else { 83 input, err, warn = diffs.ReportAllDiffs(c.Format == JSONFormat) 84 } 85 if err != nil { 86 return err 87 } 88 _, err = io.Copy(output, input) 89 if err != nil { 90 return err 91 } 92 return warn 93 } 94 95 func (c *DiffCommand) readIgnores() (diff.SpecDifferences, error) { 96 ignoreFile := c.IgnoreFile 97 ignoreDiffs := diff.SpecDifferences{} 98 99 if ignoreFile == "none specified" || ignoreFile == "" { 100 return ignoreDiffs, nil 101 } 102 // Open our jsonFile 103 jsonFile, err := os.Open(ignoreFile) 104 if err != nil { 105 return nil, fmt.Errorf("%s: %w", ignoreFile, err) 106 } 107 defer func() { 108 _ = jsonFile.Close() 109 }() 110 byteValue, err := ioutil.ReadAll(jsonFile) 111 if err != nil { 112 return nil, fmt.Errorf("reading %s: %w", ignoreFile, err) 113 } 114 err = json.Unmarshal(byteValue, &ignoreDiffs) 115 if err != nil { 116 return nil, err 117 } 118 return ignoreDiffs, nil 119 } 120 121 func (c *DiffCommand) getDiffs() (diff.SpecDifferences, error) { 122 oldSpecPath, newSpecPath := c.Args.OldSpec, c.Args.NewSpec 123 swaggerDoc1 := oldSpecPath 124 specDoc1, err := loads.Spec(swaggerDoc1) 125 if err != nil { 126 return nil, err 127 } 128 129 swaggerDoc2 := newSpecPath 130 specDoc2, err := loads.Spec(swaggerDoc2) 131 if err != nil { 132 return nil, err 133 } 134 135 return diff.Compare(specDoc1.Spec(), specDoc2.Spec()) 136 } 137 138 func (c *DiffCommand) printInfo() { 139 log.Println("Run Config:") 140 log.Printf("Spec1: %s", c.Args.OldSpec) 141 log.Printf("Spec2: %s", c.Args.NewSpec) 142 log.Printf("ReportOnlyBreakingChanges (-c) :%v", c.OnlyBreakingChanges) 143 log.Printf("OutputFormat (-f) :%s", c.Format) 144 log.Printf("IgnoreFile (-i) :%s", c.IgnoreFile) 145 log.Printf("Diff Report Destination (-d) :%s", c.Destination) 146 }