mirror of
https://github.com/go-gitea/gitea.git
synced 2025-08-18 06:34:07 +09:00
Use vendored go-swagger (#8087)
* Use vendored go-swagger * vendor go-swagger * revert un wanteed change * remove un-needed GO111MODULE * Update Makefile Co-Authored-By: techknowlogick <matti@mdranta.net>
This commit is contained in:
committed by
Lauris BH
parent
4cb1bdddc8
commit
9fe4437bda
5
vendor/github.com/go-swagger/go-swagger/cmd/swagger/.gitignore
generated
vendored
Normal file
5
vendor/github.com/go-swagger/go-swagger/cmd/swagger/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
swagger
|
||||
swagger.json
|
||||
models
|
||||
operations
|
||||
cmd
|
115
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go
generated
vendored
Normal file
115
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-swagger/go-swagger/cmd/swagger/commands/diff"
|
||||
)
|
||||
|
||||
// JSONFormat for json
|
||||
const JSONFormat = "json"
|
||||
|
||||
// DiffCommand is a command that generates the diff of two swagger specs.
|
||||
//
|
||||
// There are no specific options for this expansion.
|
||||
type DiffCommand struct {
|
||||
OnlyBreakingChanges bool `long:"break" short:"b" description:"When present, only shows incompatible changes"`
|
||||
Format string `long:"format" short:"f" description:"When present, writes output as json" default:"txt" choice:"txt" choice:"json"`
|
||||
IgnoreFile string `long:"ignore" short:"i" description:"Exception file of diffs to ignore (copy output from json diff format)" default:"none specified"`
|
||||
Destination string `long:"dest" short:"d" description:"Output destination file or stdout" default:"stdout"`
|
||||
}
|
||||
|
||||
// Execute diffs the two specs provided
|
||||
func (c *DiffCommand) Execute(args []string) error {
|
||||
if len(args) != 2 {
|
||||
msg := `missing arguments for diff command (use --help for more info)`
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
log.Println("Run Config:")
|
||||
log.Printf("Spec1: %s", args[0])
|
||||
log.Printf("Spec2: %s", args[1])
|
||||
log.Printf("ReportOnlyBreakingChanges (-c) :%v", c.OnlyBreakingChanges)
|
||||
log.Printf("OutputFormat (-f) :%s", c.Format)
|
||||
log.Printf("IgnoreFile (-i) :%s", c.IgnoreFile)
|
||||
log.Printf("Diff Report Destination (-d) :%s", c.Destination)
|
||||
|
||||
diffs, err := getDiffs(args[0], args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ignores, err := readIgnores(c.IgnoreFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
diffs = diffs.FilterIgnores(ignores)
|
||||
if len(ignores) > 0 {
|
||||
log.Printf("Diff Report Ignored Items from IgnoreFile")
|
||||
for _, eachItem := range ignores {
|
||||
log.Printf("%s", eachItem.String())
|
||||
}
|
||||
}
|
||||
|
||||
if c.Format == JSONFormat {
|
||||
err = diffs.ReportAllDiffs(true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if c.OnlyBreakingChanges {
|
||||
err = diffs.ReportCompatibility()
|
||||
} else {
|
||||
err = diffs.ReportAllDiffs(false)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func readIgnores(ignoreFile string) (diff.SpecDifferences, error) {
|
||||
ignoreDiffs := diff.SpecDifferences{}
|
||||
|
||||
if ignoreFile == "none specified" {
|
||||
return ignoreDiffs, nil
|
||||
}
|
||||
// Open our jsonFile
|
||||
jsonFile, err := os.Open(ignoreFile)
|
||||
// if we os.Open returns an error then handle it
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// defer the closing of our jsonFile so that we can parse it later on
|
||||
defer jsonFile.Close()
|
||||
byteValue, err := ioutil.ReadAll(jsonFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// def
|
||||
err = json.Unmarshal(byteValue, &ignoreDiffs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ignoreDiffs, nil
|
||||
}
|
||||
|
||||
func getDiffs(oldSpecPath, newSpecPath string) (diff.SpecDifferences, error) {
|
||||
swaggerDoc1 := oldSpecPath
|
||||
specDoc1, err := loads.Spec(swaggerDoc1)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
swaggerDoc2 := newSpecPath
|
||||
specDoc2, err := loads.Spec(swaggerDoc2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return diff.Compare(specDoc1.Spec(), specDoc2.Spec())
|
||||
}
|
99
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/array_diff.go
generated
vendored
Normal file
99
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/array_diff.go
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
package diff
|
||||
|
||||
// This is a simple DSL for diffing arrays
|
||||
|
||||
// FromArrayStruct utility struct to encompass diffing of string arrays
|
||||
type FromArrayStruct struct {
|
||||
from []string
|
||||
}
|
||||
|
||||
// FromStringArray starts a fluent diff expression
|
||||
func FromStringArray(from []string) FromArrayStruct {
|
||||
return FromArrayStruct{from}
|
||||
}
|
||||
|
||||
// DiffsTo completes a fluent dff expression
|
||||
func (f FromArrayStruct) DiffsTo(toArray []string) (added, deleted, common []string) {
|
||||
inFrom := 1
|
||||
inTo := 2
|
||||
|
||||
m := make(map[string]int)
|
||||
|
||||
for _, item := range f.from {
|
||||
m[item] = inFrom
|
||||
}
|
||||
|
||||
for _, item := range toArray {
|
||||
if _, ok := m[item]; ok {
|
||||
m[item] |= inTo
|
||||
} else {
|
||||
m[item] = inTo
|
||||
}
|
||||
}
|
||||
for key, val := range m {
|
||||
switch val {
|
||||
case inFrom:
|
||||
deleted = append(deleted, key)
|
||||
case inTo:
|
||||
added = append(added, key)
|
||||
default:
|
||||
common = append(common, key)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FromMapStruct utility struct to encompass diffing of string arrays
|
||||
type FromMapStruct struct {
|
||||
srcMap map[string]interface{}
|
||||
}
|
||||
|
||||
// FromStringMap starts a comparison by declaring a source map
|
||||
func FromStringMap(srcMap map[string]interface{}) FromMapStruct {
|
||||
return FromMapStruct{srcMap}
|
||||
}
|
||||
|
||||
// Pair stores a pair of items which share a key in two maps
|
||||
type Pair struct {
|
||||
First interface{}
|
||||
Second interface{}
|
||||
}
|
||||
|
||||
// DiffsTo - generates diffs for a comparison
|
||||
func (f FromMapStruct) DiffsTo(destMap map[string]interface{}) (added, deleted, common map[string]interface{}) {
|
||||
added = make(map[string]interface{})
|
||||
deleted = make(map[string]interface{})
|
||||
common = make(map[string]interface{})
|
||||
|
||||
inSrc := 1
|
||||
inDest := 2
|
||||
|
||||
m := make(map[string]int)
|
||||
|
||||
// enter values for all items in the source array
|
||||
for key := range f.srcMap {
|
||||
m[key] = inSrc
|
||||
}
|
||||
|
||||
// now either set or 'boolean or' a new flag if in the second collection
|
||||
for key := range destMap {
|
||||
if _, ok := m[key]; ok {
|
||||
m[key] |= inDest
|
||||
} else {
|
||||
m[key] = inDest
|
||||
}
|
||||
}
|
||||
// finally inspect the values and generate the left,right and shared collections
|
||||
// for the shared items, store both values in case there's a diff
|
||||
for key, val := range m {
|
||||
switch val {
|
||||
case inSrc:
|
||||
deleted[key] = f.srcMap[key]
|
||||
case inDest:
|
||||
added[key] = destMap[key]
|
||||
default:
|
||||
common[key] = Pair{f.srcMap[key], destMap[key]}
|
||||
}
|
||||
}
|
||||
return added, deleted, common
|
||||
}
|
90
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/compatibility.go
generated
vendored
Normal file
90
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/compatibility.go
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
package diff
|
||||
|
||||
// CompatibilityPolicy decides which changes are breaking and which are not
|
||||
type CompatibilityPolicy struct {
|
||||
ForResponse map[SpecChangeCode]Compatibility
|
||||
ForRequest map[SpecChangeCode]Compatibility
|
||||
ForChange map[SpecChangeCode]Compatibility
|
||||
}
|
||||
|
||||
var compatibility CompatibilityPolicy
|
||||
|
||||
func init() {
|
||||
compatibility = CompatibilityPolicy{
|
||||
ForResponse: map[SpecChangeCode]Compatibility{
|
||||
AddedRequiredProperty: Breaking,
|
||||
DeletedProperty: Breaking,
|
||||
AddedProperty: NonBreaking,
|
||||
DeletedResponse: Breaking,
|
||||
AddedResponse: NonBreaking,
|
||||
WidenedType: NonBreaking,
|
||||
NarrowedType: NonBreaking,
|
||||
ChangedType: Breaking,
|
||||
ChangedToCompatibleType: NonBreaking,
|
||||
AddedEnumValue: Breaking,
|
||||
DeletedEnumValue: NonBreaking,
|
||||
AddedResponseHeader: NonBreaking,
|
||||
ChangedResponseHeader: Breaking,
|
||||
DeletedResponseHeader: Breaking,
|
||||
ChangedDescripton: NonBreaking,
|
||||
AddedDescripton: NonBreaking,
|
||||
DeletedDescripton: NonBreaking,
|
||||
ChangedTag: NonBreaking,
|
||||
AddedTag: NonBreaking,
|
||||
DeletedTag: NonBreaking,
|
||||
},
|
||||
ForRequest: map[SpecChangeCode]Compatibility{
|
||||
AddedRequiredProperty: Breaking,
|
||||
DeletedProperty: Breaking,
|
||||
AddedProperty: Breaking,
|
||||
AddedOptionalParam: NonBreaking,
|
||||
AddedRequiredParam: Breaking,
|
||||
DeletedOptionalParam: NonBreaking,
|
||||
DeletedRequiredParam: NonBreaking,
|
||||
WidenedType: NonBreaking,
|
||||
NarrowedType: Breaking,
|
||||
ChangedType: Breaking,
|
||||
ChangedToCompatibleType: NonBreaking,
|
||||
ChangedOptionalToRequiredParam: Breaking,
|
||||
ChangedRequiredToOptionalParam: NonBreaking,
|
||||
AddedEnumValue: NonBreaking,
|
||||
DeletedEnumValue: Breaking,
|
||||
ChangedDescripton: NonBreaking,
|
||||
AddedDescripton: NonBreaking,
|
||||
DeletedDescripton: NonBreaking,
|
||||
ChangedTag: NonBreaking,
|
||||
AddedTag: NonBreaking,
|
||||
DeletedTag: NonBreaking,
|
||||
},
|
||||
ForChange: map[SpecChangeCode]Compatibility{
|
||||
NoChangeDetected: NonBreaking,
|
||||
AddedEndpoint: NonBreaking,
|
||||
DeletedEndpoint: Breaking,
|
||||
DeletedDeprecatedEndpoint: NonBreaking,
|
||||
AddedConsumesFormat: NonBreaking,
|
||||
DeletedConsumesFormat: Breaking,
|
||||
AddedProducesFormat: Breaking,
|
||||
DeletedProducesFormat: NonBreaking,
|
||||
AddedSchemes: NonBreaking,
|
||||
DeletedSchemes: Breaking,
|
||||
ChangedHostURL: Breaking,
|
||||
ChangedBasePath: Breaking,
|
||||
ChangedDescripton: NonBreaking,
|
||||
AddedDescripton: NonBreaking,
|
||||
DeletedDescripton: NonBreaking,
|
||||
ChangedTag: NonBreaking,
|
||||
AddedTag: NonBreaking,
|
||||
DeletedTag: NonBreaking,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getCompatibilityForChange(diffCode SpecChangeCode, where DataDirection) Compatibility {
|
||||
if compat, commonChange := compatibility.ForChange[diffCode]; commonChange {
|
||||
return compat
|
||||
}
|
||||
if where == Request {
|
||||
return compatibility.ForRequest[diffCode]
|
||||
}
|
||||
return compatibility.ForResponse[diffCode]
|
||||
}
|
22
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/difference_location.go
generated
vendored
Normal file
22
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/difference_location.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
package diff
|
||||
|
||||
// DifferenceLocation indicates where the difference occurs
|
||||
type DifferenceLocation struct {
|
||||
URL string `json:"url"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Response int `json:"response,omitempty"`
|
||||
Node *Node `json:"node,omitempty"`
|
||||
}
|
||||
|
||||
// AddNode returns a copy of this location with the leaf node added
|
||||
func (dl DifferenceLocation) AddNode(node *Node) DifferenceLocation {
|
||||
newLoc := dl
|
||||
|
||||
if newLoc.Node != nil {
|
||||
newLoc.Node = newLoc.Node.Copy()
|
||||
newLoc.Node.AddLeafNode(node)
|
||||
} else {
|
||||
newLoc.Node = node
|
||||
}
|
||||
return newLoc
|
||||
}
|
276
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/difftypes.go
generated
vendored
Normal file
276
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/difftypes.go
generated
vendored
Normal file
@ -0,0 +1,276 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// SpecChangeCode enumerates the various types of diffs from one spec to another
|
||||
type SpecChangeCode int
|
||||
|
||||
const (
|
||||
// NoChangeDetected - the specs have no changes
|
||||
NoChangeDetected SpecChangeCode = iota
|
||||
// DeletedProperty - A message property has been deleted in the new spec
|
||||
DeletedProperty
|
||||
// AddedProperty - A message property has been added in the new spec
|
||||
AddedProperty
|
||||
// AddedRequiredProperty - A required message property has been added in the new spec
|
||||
AddedRequiredProperty
|
||||
// DeletedOptionalParam - An endpoint parameter has been deleted in the new spec
|
||||
DeletedOptionalParam
|
||||
// ChangedDescripton - Changed a description
|
||||
ChangedDescripton
|
||||
// AddedDescripton - Added a description
|
||||
AddedDescripton
|
||||
// DeletedDescripton - Deleted a description
|
||||
DeletedDescripton
|
||||
// ChangedTag - Changed a tag
|
||||
ChangedTag
|
||||
// AddedTag - Added a tag
|
||||
AddedTag
|
||||
// DeletedTag - Deleted a tag
|
||||
DeletedTag
|
||||
// DeletedResponse - An endpoint response has been deleted in the new spec
|
||||
DeletedResponse
|
||||
// DeletedEndpoint - An endpoint has been deleted in the new spec
|
||||
DeletedEndpoint
|
||||
// DeletedDeprecatedEndpoint - A deprecated endpoint has been deleted in the new spec
|
||||
DeletedDeprecatedEndpoint
|
||||
// AddedRequiredParam - A required parameter has been added in the new spec
|
||||
AddedRequiredParam
|
||||
// DeletedRequiredParam - A required parameter has been deleted in the new spec
|
||||
DeletedRequiredParam
|
||||
// ChangedRequiredToOptional - A required parameter has been made optional in the new spec
|
||||
ChangedRequiredToOptional
|
||||
// AddedEndpoint - An endpoint has been added in the new spec
|
||||
AddedEndpoint
|
||||
// WidenedType - An type has been changed to a more permissive type eg int->string
|
||||
WidenedType
|
||||
// NarrowedType - An type has been changed to a less permissive type eg string->int
|
||||
NarrowedType
|
||||
// ChangedToCompatibleType - An type has been changed to a compatible type eg password->string
|
||||
ChangedToCompatibleType
|
||||
// ChangedType - An type has been changed to a type whose relative compatibility cannot be determined
|
||||
ChangedType
|
||||
// AddedEnumValue - An enum type has had a new potential value added to it
|
||||
AddedEnumValue
|
||||
// DeletedEnumValue - An enum type has had a existing value removed from it
|
||||
DeletedEnumValue
|
||||
// AddedOptionalParam - A new optional parameter has been added to the new spec
|
||||
AddedOptionalParam
|
||||
// ChangedOptionalToRequiredParam - An optional parameter is now required in the new spec
|
||||
ChangedOptionalToRequiredParam
|
||||
// ChangedRequiredToOptionalParam - An required parameter is now optional in the new spec
|
||||
ChangedRequiredToOptionalParam
|
||||
// AddedResponse An endpoint has new response code in the new spec
|
||||
AddedResponse
|
||||
// AddedConsumesFormat - a new consumes format (json/xml/yaml etc) has been added in the new spec
|
||||
AddedConsumesFormat
|
||||
// DeletedConsumesFormat - an existing format has been removed in the new spec
|
||||
DeletedConsumesFormat
|
||||
// AddedProducesFormat - a new produces format (json/xml/yaml etc) has been added in the new spec
|
||||
AddedProducesFormat
|
||||
// DeletedProducesFormat - an existing produces format has been removed in the new spec
|
||||
DeletedProducesFormat
|
||||
// AddedSchemes - a new scheme has been added to the new spec
|
||||
AddedSchemes
|
||||
// DeletedSchemes - a scheme has been removed from the new spec
|
||||
DeletedSchemes
|
||||
// ChangedHostURL - the host url has been changed. If this is used in the client generation, then clients will break.
|
||||
ChangedHostURL
|
||||
// ChangedBasePath - the host base path has been changed. If this is used in the client generation, then clients will break.
|
||||
ChangedBasePath
|
||||
// AddedResponseHeader Added a header Item
|
||||
AddedResponseHeader
|
||||
// ChangedResponseHeader Added a header Item
|
||||
ChangedResponseHeader
|
||||
// DeletedResponseHeader Added a header Item
|
||||
DeletedResponseHeader
|
||||
)
|
||||
|
||||
var toLongStringSpecChangeCode = map[SpecChangeCode]string{
|
||||
NoChangeDetected: "No Change detected",
|
||||
AddedEndpoint: "Added endpoint",
|
||||
DeletedEndpoint: "Deleted endpoint",
|
||||
DeletedDeprecatedEndpoint: "Deleted a deprecated endpoint",
|
||||
AddedRequiredProperty: "Added required property",
|
||||
DeletedProperty: "Deleted property",
|
||||
ChangedDescripton: "Changed a description",
|
||||
AddedDescripton: "Added a description",
|
||||
DeletedDescripton: "Deleted a description",
|
||||
ChangedTag: "Changed a tag",
|
||||
AddedTag: "Added a tag",
|
||||
DeletedTag: "Deleted a tag",
|
||||
AddedProperty: "Added property",
|
||||
AddedOptionalParam: "Added optional param",
|
||||
AddedRequiredParam: "Added required param",
|
||||
DeletedOptionalParam: "Deleted optional param",
|
||||
DeletedRequiredParam: "Deleted required param",
|
||||
DeletedResponse: "Deleted response",
|
||||
AddedResponse: "Added response",
|
||||
WidenedType: "Widened type",
|
||||
NarrowedType: "Narrowed type",
|
||||
ChangedType: "Changed type",
|
||||
ChangedToCompatibleType: "Changed type to equivalent type",
|
||||
ChangedOptionalToRequiredParam: "Changed optional param to required",
|
||||
ChangedRequiredToOptionalParam: "Changed required param to optional",
|
||||
AddedEnumValue: "Added possible enumeration(s)",
|
||||
DeletedEnumValue: "Deleted possible enumeration(s)",
|
||||
AddedConsumesFormat: "Added a consumes format",
|
||||
DeletedConsumesFormat: "Deleted a consumes format",
|
||||
AddedProducesFormat: "Added produces format",
|
||||
DeletedProducesFormat: "Deleted produces format",
|
||||
AddedSchemes: "Added schemes",
|
||||
DeletedSchemes: "Deleted schemes",
|
||||
ChangedHostURL: "Changed host URL",
|
||||
ChangedBasePath: "Changed base path",
|
||||
AddedResponseHeader: "Added response header",
|
||||
ChangedResponseHeader: "Changed response header",
|
||||
DeletedResponseHeader: "Deleted response header",
|
||||
}
|
||||
|
||||
var toStringSpecChangeCode = map[SpecChangeCode]string{
|
||||
AddedEndpoint: "AddedEndpoint",
|
||||
NoChangeDetected: "NoChangeDetected",
|
||||
DeletedEndpoint: "DeletedEndpoint",
|
||||
DeletedDeprecatedEndpoint: "DeletedDeprecatedEndpoint",
|
||||
AddedRequiredProperty: "AddedRequiredProperty",
|
||||
DeletedProperty: "DeletedProperty",
|
||||
AddedProperty: "AddedProperty",
|
||||
ChangedDescripton: "ChangedDescription",
|
||||
AddedDescripton: "AddedDescription",
|
||||
DeletedDescripton: "DeletedDescription",
|
||||
ChangedTag: "ChangedTag",
|
||||
AddedTag: "AddedTag",
|
||||
DeletedTag: "DeletedTag",
|
||||
AddedOptionalParam: "AddedOptionalParam",
|
||||
AddedRequiredParam: "AddedRequiredParam",
|
||||
DeletedOptionalParam: "DeletedRequiredParam",
|
||||
DeletedRequiredParam: "Deleted required param",
|
||||
DeletedResponse: "DeletedResponse",
|
||||
AddedResponse: "AddedResponse",
|
||||
WidenedType: "WidenedType",
|
||||
NarrowedType: "NarrowedType",
|
||||
ChangedType: "ChangedType",
|
||||
ChangedToCompatibleType: "ChangedToCompatibleType",
|
||||
ChangedOptionalToRequiredParam: "ChangedOptionalToRequiredParam",
|
||||
ChangedRequiredToOptionalParam: "ChangedRequiredToOptionalParam",
|
||||
AddedEnumValue: "AddedEnumValue",
|
||||
DeletedEnumValue: "DeletedEnumValue",
|
||||
AddedConsumesFormat: "AddedConsumesFormat",
|
||||
DeletedConsumesFormat: "DeletedConsumesFormat",
|
||||
AddedProducesFormat: "AddedProducesFormat",
|
||||
DeletedProducesFormat: "DeletedProducesFormat",
|
||||
AddedSchemes: "AddedSchemes",
|
||||
DeletedSchemes: "DeletedSchemes",
|
||||
ChangedHostURL: "ChangedHostURL",
|
||||
ChangedBasePath: "ChangedBasePath",
|
||||
AddedResponseHeader: "AddedResponseHeader",
|
||||
ChangedResponseHeader: "ChangedResponseHeader",
|
||||
DeletedResponseHeader: "DeletedResponseHeader",
|
||||
}
|
||||
|
||||
var toIDSpecChangeCode = map[string]SpecChangeCode{}
|
||||
|
||||
// Description returns an english version of this error
|
||||
func (s *SpecChangeCode) Description() (result string) {
|
||||
result, ok := toLongStringSpecChangeCode[*s]
|
||||
if !ok {
|
||||
fmt.Printf("WARNING: No description for %v", *s)
|
||||
result = "UNDEFINED"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalJSON marshals the enum as a quoted json string
|
||||
func (s *SpecChangeCode) MarshalJSON() ([]byte, error) {
|
||||
return stringAsQuotedBytes(toStringSpecChangeCode[*s])
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmashalls a quoted json string to the enum value
|
||||
func (s *SpecChangeCode) UnmarshalJSON(b []byte) error {
|
||||
str, err := readStringFromByteStream(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Note that if the string cannot be found then it will return an error to the caller.
|
||||
val, ok := toIDSpecChangeCode[str]
|
||||
|
||||
if ok {
|
||||
*s = val
|
||||
} else {
|
||||
return fmt.Errorf("unknown enum value. cannot unmarshal '%s'", str)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Compatibility - whether this is a breaking or non-breaking change
|
||||
type Compatibility int
|
||||
|
||||
const (
|
||||
// Breaking this change could break existing clients
|
||||
Breaking Compatibility = iota
|
||||
// NonBreaking This is a backwards-compatible API change
|
||||
NonBreaking
|
||||
)
|
||||
|
||||
func (s Compatibility) String() string {
|
||||
return toStringCompatibility[s]
|
||||
}
|
||||
|
||||
var toStringCompatibility = map[Compatibility]string{
|
||||
Breaking: "Breaking",
|
||||
NonBreaking: "NonBreaking",
|
||||
}
|
||||
|
||||
var toIDCompatibility = map[string]Compatibility{}
|
||||
|
||||
// MarshalJSON marshals the enum as a quoted json string
|
||||
func (s *Compatibility) MarshalJSON() ([]byte, error) {
|
||||
return stringAsQuotedBytes(toStringCompatibility[*s])
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmashals a quoted json string to the enum value
|
||||
func (s *Compatibility) UnmarshalJSON(b []byte) error {
|
||||
str, err := readStringFromByteStream(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Note that if the string cannot be found then it will return an error to the caller.
|
||||
val, ok := toIDCompatibility[str]
|
||||
|
||||
if ok {
|
||||
*s = val
|
||||
} else {
|
||||
return fmt.Errorf("unknown enum value. cannot unmarshal '%s'", str)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stringAsQuotedBytes(str string) ([]byte, error) {
|
||||
buffer := bytes.NewBufferString(`"`)
|
||||
buffer.WriteString(str)
|
||||
buffer.WriteString(`"`)
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
func readStringFromByteStream(b []byte) (string, error) {
|
||||
var j string
|
||||
err := json.Unmarshal(b, &j)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return j, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
for key, val := range toStringSpecChangeCode {
|
||||
toIDSpecChangeCode[val] = key
|
||||
}
|
||||
for key, val := range toStringCompatibility {
|
||||
toIDCompatibility[val] = key
|
||||
}
|
||||
|
||||
}
|
47
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go
generated
vendored
Normal file
47
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package diff
|
||||
|
||||
// Node is the position od a diff in a spec
|
||||
type Node struct {
|
||||
Field string `json:"name,omitempty"`
|
||||
TypeName string `json:"type,omitempty"`
|
||||
IsArray bool `json:"is_array,omitempty"`
|
||||
ChildNode *Node `json:"child,omitempty"`
|
||||
}
|
||||
|
||||
// String std string render
|
||||
func (n *Node) String() string {
|
||||
name := n.Field
|
||||
if n.IsArray {
|
||||
name = "array[" + n.TypeName + "]"
|
||||
}
|
||||
|
||||
if n.ChildNode != nil {
|
||||
return name + "." + n.ChildNode.String()
|
||||
}
|
||||
if len(n.TypeName) > 0 {
|
||||
return name + " : " + n.TypeName
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// AddLeafNode Adds (recursive) a Child to the first non-nil child found
|
||||
func (n *Node) AddLeafNode(toAdd *Node) *Node {
|
||||
|
||||
if n.ChildNode == nil {
|
||||
n.ChildNode = toAdd
|
||||
} else {
|
||||
n.ChildNode.AddLeafNode(toAdd)
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
//Copy deep copy of this node and children
|
||||
func (n Node) Copy() *Node {
|
||||
newNode := n
|
||||
|
||||
if newNode.ChildNode != nil {
|
||||
n.ChildNode = newNode.ChildNode.Copy()
|
||||
}
|
||||
return &newNode
|
||||
}
|
169
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/reporting.go
generated
vendored
Normal file
169
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/reporting.go
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
// ArrayType const for array
|
||||
var ArrayType = "array"
|
||||
|
||||
// Compare returns the result of analysing breaking and non breaking changes
|
||||
// between to Swagger specs
|
||||
func Compare(spec1, spec2 *spec.Swagger) (diffs SpecDifferences, err error) {
|
||||
analyser := NewSpecAnalyser()
|
||||
err = analyser.Analyse(spec1, spec2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diffs = analyser.Diffs
|
||||
return
|
||||
}
|
||||
|
||||
// PathItemOp - combines path and operation into a single keyed entity
|
||||
type PathItemOp struct {
|
||||
ParentPathItem *spec.PathItem `json:"pathitem"`
|
||||
Operation *spec.Operation `json:"operation"`
|
||||
}
|
||||
|
||||
// URLMethod - combines url and method into a single keyed entity
|
||||
type URLMethod struct {
|
||||
Path string `json:"path"`
|
||||
Method string `json:"method"`
|
||||
}
|
||||
|
||||
// DataDirection indicates the direction of change Request vs Response
|
||||
type DataDirection int
|
||||
|
||||
const (
|
||||
// Request Used for messages/param diffs in a request
|
||||
Request DataDirection = iota
|
||||
// Response Used for messages/param diffs in a response
|
||||
Response
|
||||
)
|
||||
|
||||
func getParams(pathParams, opParams []spec.Parameter, location string) map[string]spec.Parameter {
|
||||
params := map[string]spec.Parameter{}
|
||||
// add shared path params
|
||||
for _, eachParam := range pathParams {
|
||||
if eachParam.In == location {
|
||||
params[eachParam.Name] = eachParam
|
||||
}
|
||||
}
|
||||
// add any overridden params
|
||||
for _, eachParam := range opParams {
|
||||
if eachParam.In == location {
|
||||
params[eachParam.Name] = eachParam
|
||||
}
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
func getNameOnlyDiffNode(forLocation string) *Node {
|
||||
node := Node{
|
||||
Field: forLocation,
|
||||
}
|
||||
return &node
|
||||
}
|
||||
|
||||
func getSimpleSchemaDiffNode(name string, schema *spec.SimpleSchema) *Node {
|
||||
node := Node{
|
||||
Field: name,
|
||||
}
|
||||
if schema != nil {
|
||||
node.TypeName, node.IsArray = getSimpleSchemaType(schema)
|
||||
}
|
||||
return &node
|
||||
}
|
||||
|
||||
func getSchemaDiffNode(name string, schema *spec.Schema) *Node {
|
||||
node := Node{
|
||||
Field: name,
|
||||
}
|
||||
if schema != nil {
|
||||
node.TypeName, node.IsArray = getSchemaType(&schema.SchemaProps)
|
||||
}
|
||||
return &node
|
||||
}
|
||||
|
||||
func definitonFromURL(url *url.URL) string {
|
||||
if url == nil {
|
||||
return ""
|
||||
}
|
||||
fragmentParts := strings.Split(url.Fragment, "/")
|
||||
numParts := len(fragmentParts)
|
||||
if numParts == 0 {
|
||||
return ""
|
||||
}
|
||||
return fragmentParts[numParts-1]
|
||||
}
|
||||
|
||||
func getSimpleSchemaType(schema *spec.SimpleSchema) (typeName string, isArray bool) {
|
||||
typeName = schema.Type
|
||||
if typeName == ArrayType {
|
||||
typeName, _ = getSimpleSchemaType(&schema.Items.SimpleSchema)
|
||||
return typeName, true
|
||||
}
|
||||
return typeName, false
|
||||
}
|
||||
|
||||
func getSchemaType(schema *spec.SchemaProps) (typeName string, isArray bool) {
|
||||
refStr := definitonFromURL(schema.Ref.GetURL())
|
||||
if len(refStr) > 0 {
|
||||
return refStr, false
|
||||
}
|
||||
typeName = schema.Type[0]
|
||||
if typeName == ArrayType {
|
||||
typeName, _ = getSchemaType(&schema.Items.Schema.SchemaProps)
|
||||
return typeName, true
|
||||
}
|
||||
return typeName, false
|
||||
}
|
||||
|
||||
func primitiveTypeString(typeName, typeFormat string) string {
|
||||
if typeFormat != "" {
|
||||
return fmt.Sprintf("%s.%s", typeName, typeFormat)
|
||||
}
|
||||
return typeName
|
||||
}
|
||||
|
||||
// TypeDiff - describes a primitive type change
|
||||
type TypeDiff struct {
|
||||
Change SpecChangeCode `json:"change-type,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
FromType string `json:"from-type,omitempty"`
|
||||
ToType string `json:"to-type,omitempty"`
|
||||
}
|
||||
|
||||
// didn't use 'width' so as not to confuse with bit width
|
||||
var numberWideness = map[string]int{
|
||||
"number": 3,
|
||||
"number.double": 3,
|
||||
"double": 3,
|
||||
"number.float": 2,
|
||||
"float": 2,
|
||||
"long": 1,
|
||||
"integer.int64": 1,
|
||||
"integer": 0,
|
||||
"integer.int32": 0,
|
||||
}
|
||||
|
||||
func prettyprint(b []byte) ([]byte, error) {
|
||||
var out bytes.Buffer
|
||||
err := json.Indent(&out, b, "", " ")
|
||||
return out.Bytes(), err
|
||||
}
|
||||
|
||||
// JSONMarshal allows the item to be correctly rendered to json
|
||||
func JSONMarshal(t interface{}) ([]byte, error) {
|
||||
buffer := &bytes.Buffer{}
|
||||
encoder := json.NewEncoder(buffer)
|
||||
encoder.SetEscapeHTML(false)
|
||||
err := encoder.Encode(t)
|
||||
return buffer.Bytes(), err
|
||||
}
|
654
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go
generated
vendored
Normal file
654
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go
generated
vendored
Normal file
@ -0,0 +1,654 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
const StringType = "string"
|
||||
|
||||
// URLMethodResponse encapsulates these three elements to act as a map key
|
||||
type URLMethodResponse struct {
|
||||
Path string `json:"path"`
|
||||
Method string `json:"method"`
|
||||
Response string `json:"response"`
|
||||
}
|
||||
|
||||
// MarshalText - for serializing as a map key
|
||||
func (p URLMethod) MarshalText() (text []byte, err error) {
|
||||
return []byte(fmt.Sprintf("%s %s", p.Path, p.Method)), nil
|
||||
}
|
||||
|
||||
// URLMethods allows iteration of endpoints based on url and method
|
||||
type URLMethods map[URLMethod]*PathItemOp
|
||||
|
||||
// SpecAnalyser contains all the differences for a Spec
|
||||
type SpecAnalyser struct {
|
||||
Diffs SpecDifferences
|
||||
urlMethods1 URLMethods
|
||||
urlMethods2 URLMethods
|
||||
Definitions1 spec.Definitions
|
||||
Definitions2 spec.Definitions
|
||||
AlreadyComparedDefinitions map[string]bool
|
||||
}
|
||||
|
||||
// NewSpecAnalyser returns an empty SpecDiffs
|
||||
func NewSpecAnalyser() *SpecAnalyser {
|
||||
return &SpecAnalyser{
|
||||
Diffs: SpecDifferences{},
|
||||
}
|
||||
}
|
||||
|
||||
// Analyse the differences in two specs
|
||||
func (sd *SpecAnalyser) Analyse(spec1, spec2 *spec.Swagger) error {
|
||||
sd.Definitions1 = spec1.Definitions
|
||||
sd.Definitions2 = spec2.Definitions
|
||||
sd.urlMethods1 = getURLMethodsFor(spec1)
|
||||
sd.urlMethods2 = getURLMethodsFor(spec2)
|
||||
|
||||
sd.analyseSpecMetadata(spec1, spec2)
|
||||
sd.analyseEndpoints()
|
||||
sd.analyseParams()
|
||||
sd.analyseEndpointData()
|
||||
sd.analyseResponseParams()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) analyseSpecMetadata(spec1, spec2 *spec.Swagger) {
|
||||
// breaking if it no longer consumes any formats
|
||||
added, deleted, _ := FromStringArray(spec1.Consumes).DiffsTo(spec2.Consumes)
|
||||
|
||||
node := getNameOnlyDiffNode("Spec")
|
||||
location := DifferenceLocation{Node: node}
|
||||
consumesLoation := location.AddNode(getNameOnlyDiffNode("consumes"))
|
||||
|
||||
for _, eachAdded := range added {
|
||||
sd.Diffs = sd.Diffs.addDiff(
|
||||
SpecDifference{DifferenceLocation: consumesLoation, Code: AddedConsumesFormat, Compatibility: NonBreaking, DiffInfo: eachAdded})
|
||||
}
|
||||
for _, eachDeleted := range deleted {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: consumesLoation, Code: DeletedConsumesFormat, Compatibility: Breaking, DiffInfo: eachDeleted})
|
||||
}
|
||||
|
||||
// // breaking if it no longer produces any formats
|
||||
added, deleted, _ = FromStringArray(spec1.Produces).DiffsTo(spec2.Produces)
|
||||
producesLocation := location.AddNode(getNameOnlyDiffNode("produces"))
|
||||
for _, eachAdded := range added {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: producesLocation, Code: AddedProducesFormat, Compatibility: NonBreaking, DiffInfo: eachAdded})
|
||||
}
|
||||
for _, eachDeleted := range deleted {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: producesLocation, Code: DeletedProducesFormat, Compatibility: Breaking, DiffInfo: eachDeleted})
|
||||
}
|
||||
|
||||
// // breaking if it no longer supports a scheme
|
||||
added, deleted, _ = FromStringArray(spec1.Schemes).DiffsTo(spec2.Schemes)
|
||||
schemesLocation := location.AddNode(getNameOnlyDiffNode("schemes"))
|
||||
|
||||
for _, eachAdded := range added {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: schemesLocation, Code: AddedSchemes, Compatibility: NonBreaking, DiffInfo: eachAdded})
|
||||
}
|
||||
for _, eachDeleted := range deleted {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: schemesLocation, Code: DeletedSchemes, Compatibility: Breaking, DiffInfo: eachDeleted})
|
||||
}
|
||||
|
||||
// // host should be able to change without any issues?
|
||||
sd.analyseMetaDataProperty(spec1.Info.Description, spec2.Info.Description, ChangedDescripton, NonBreaking)
|
||||
|
||||
// // host should be able to change without any issues?
|
||||
sd.analyseMetaDataProperty(spec1.Host, spec2.Host, ChangedHostURL, Breaking)
|
||||
// sd.Host = compareStrings(spec1.Host, spec2.Host)
|
||||
|
||||
// // Base Path change will break non generated clients
|
||||
sd.analyseMetaDataProperty(spec1.BasePath, spec2.BasePath, ChangedBasePath, Breaking)
|
||||
|
||||
// TODO: what to do about security?
|
||||
// Missing security scheme will break a client
|
||||
// Security []map[string][]string `json:"security,omitempty"`
|
||||
// Tags []Tag `json:"tags,omitempty"`
|
||||
// ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) analyseEndpoints() {
|
||||
sd.findDeletedEndpoints()
|
||||
sd.findAddedEndpoints()
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) analyseEndpointData() {
|
||||
|
||||
for URLMethod, op2 := range sd.urlMethods2 {
|
||||
if op1, ok := sd.urlMethods1[URLMethod]; ok {
|
||||
addedTags, deletedTags, _ := FromStringArray(op1.Operation.Tags).DiffsTo(op2.Operation.Tags)
|
||||
location := DifferenceLocation{URL: URLMethod.Path, Method: URLMethod.Method}
|
||||
|
||||
for _, eachAddedTag := range addedTags {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: AddedTag, DiffInfo: eachAddedTag})
|
||||
}
|
||||
for _, eachDeletedTag := range deletedTags {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: DeletedTag, DiffInfo: eachDeletedTag})
|
||||
}
|
||||
|
||||
sd.compareDescripton(location, op1.Operation.Description, op2.Operation.Description)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) analyseParams() {
|
||||
locations := []string{"query", "path", "body", "header"}
|
||||
|
||||
for _, paramLocation := range locations {
|
||||
rootNode := getNameOnlyDiffNode(strings.Title(paramLocation))
|
||||
for URLMethod, op2 := range sd.urlMethods2 {
|
||||
if op1, ok := sd.urlMethods1[URLMethod]; ok {
|
||||
|
||||
params1 := getParams(op1.ParentPathItem.Parameters, op1.Operation.Parameters, paramLocation)
|
||||
params2 := getParams(op2.ParentPathItem.Parameters, op2.Operation.Parameters, paramLocation)
|
||||
|
||||
location := DifferenceLocation{URL: URLMethod.Path, Method: URLMethod.Method, Node: rootNode}
|
||||
|
||||
// detect deleted params
|
||||
for paramName1, param1 := range params1 {
|
||||
if _, ok := params2[paramName1]; !ok {
|
||||
childLocation := location.AddNode(getSchemaDiffNode(paramName1, param1.Schema))
|
||||
code := DeletedOptionalParam
|
||||
if param1.Required {
|
||||
code = DeletedRequiredParam
|
||||
}
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: childLocation, Code: code})
|
||||
}
|
||||
}
|
||||
// detect added changed params
|
||||
for paramName2, param2 := range params2 {
|
||||
//changed?
|
||||
if param1, ok := params1[paramName2]; ok {
|
||||
sd.compareParams(URLMethod, paramLocation, paramName2, param1, param2)
|
||||
} else {
|
||||
// Added
|
||||
childLocation := location.AddNode(getSchemaDiffNode(paramName2, param2.Schema))
|
||||
code := AddedOptionalParam
|
||||
if param2.Required {
|
||||
code = AddedRequiredParam
|
||||
}
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: childLocation, Code: code})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) analyseResponseParams() {
|
||||
// Loop through url+methods in spec 2 - check deleted and changed
|
||||
for URLMethod2, op2 := range sd.urlMethods2 {
|
||||
if op1, ok := sd.urlMethods1[URLMethod2]; ok {
|
||||
// compare responses for url and method
|
||||
op1Responses := op1.Operation.Responses.StatusCodeResponses
|
||||
op2Responses := op2.Operation.Responses.StatusCodeResponses
|
||||
|
||||
// deleted responses
|
||||
for code1 := range op1Responses {
|
||||
if _, ok := op2Responses[code1]; !ok {
|
||||
location := DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code1}
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: DeletedResponse})
|
||||
}
|
||||
}
|
||||
// Added updated Response Codes
|
||||
for code2, op2Response := range op2Responses {
|
||||
|
||||
if op1Response, ok := op1Responses[code2]; ok {
|
||||
op1Headers := op1Response.ResponseProps.Headers
|
||||
headerRootNode := getNameOnlyDiffNode("Headers")
|
||||
location := DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code2, Node: headerRootNode}
|
||||
|
||||
// Iterate Spec2 Headers looking for added and updated
|
||||
for op2HeaderName, op2Header := range op2Response.ResponseProps.Headers {
|
||||
if op1Header, ok := op1Headers[op2HeaderName]; ok {
|
||||
sd.compareSimpleSchema(location.AddNode(getNameOnlyDiffNode(op2HeaderName)),
|
||||
&op1Header.SimpleSchema,
|
||||
&op2Header.SimpleSchema, false, false)
|
||||
} else {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{
|
||||
DifferenceLocation: location.AddNode(getNameOnlyDiffNode(op2HeaderName)),
|
||||
Code: AddedResponseHeader})
|
||||
}
|
||||
}
|
||||
for op1HeaderName := range op1Response.ResponseProps.Headers {
|
||||
if _, ok := op2Response.ResponseProps.Headers[op1HeaderName]; !ok {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{
|
||||
DifferenceLocation: location.AddNode(getNameOnlyDiffNode(op1HeaderName)),
|
||||
Code: DeletedResponseHeader})
|
||||
}
|
||||
}
|
||||
responseLocation := DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code2}
|
||||
sd.compareDescripton(responseLocation, op1Response.Description, op2Response.Description)
|
||||
|
||||
if op1Response.Schema != nil {
|
||||
sd.compareSchema(
|
||||
DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code2},
|
||||
op1Response.Schema,
|
||||
op2Response.Schema, true, true)
|
||||
}
|
||||
} else {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{
|
||||
DifferenceLocation: DifferenceLocation{URL: URLMethod2.Path, Method: URLMethod2.Method, Response: code2},
|
||||
Code: AddedResponse})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addTypeDiff(diffs []TypeDiff, diff TypeDiff) []TypeDiff {
|
||||
if diff.Change != NoChangeDetected {
|
||||
diffs = append(diffs, diff)
|
||||
}
|
||||
return diffs
|
||||
}
|
||||
|
||||
// CheckToFromPrimitiveType check for diff to or from a primitive
|
||||
func (sd *SpecAnalyser) CheckToFromPrimitiveType(diffs []TypeDiff, type1, type2 spec.SchemaProps) []TypeDiff {
|
||||
|
||||
type1IsPrimitive := len(type1.Type) > 0
|
||||
type2IsPrimitive := len(type2.Type) > 0
|
||||
|
||||
// Primitive to Obj or Obj to Primitive
|
||||
if type1IsPrimitive && !type2IsPrimitive {
|
||||
return addTypeDiff(diffs, TypeDiff{Change: ChangedType, FromType: type1.Type[0], ToType: "obj"})
|
||||
}
|
||||
|
||||
if !type1IsPrimitive && type2IsPrimitive {
|
||||
return addTypeDiff(diffs, TypeDiff{Change: ChangedType, FromType: type2.Type[0], ToType: "obj"})
|
||||
}
|
||||
|
||||
return diffs
|
||||
}
|
||||
|
||||
// CheckToFromArrayType check for changes to or from an Array type
|
||||
func (sd *SpecAnalyser) CheckToFromArrayType(diffs []TypeDiff, type1, type2 spec.SchemaProps) []TypeDiff {
|
||||
// Single to Array or Array to Single
|
||||
type1Array := type1.Type[0] == ArrayType
|
||||
type2Array := type2.Type[0] == ArrayType
|
||||
|
||||
if type1Array && !type2Array {
|
||||
return addTypeDiff(diffs, TypeDiff{Change: ChangedType, FromType: "obj", ToType: type2.Type[0]})
|
||||
}
|
||||
|
||||
if !type1Array && type2Array {
|
||||
return addTypeDiff(diffs, TypeDiff{Change: ChangedType, FromType: type1.Type[0], ToType: ArrayType})
|
||||
}
|
||||
|
||||
if type1Array && type2Array {
|
||||
// array
|
||||
// TODO: Items??
|
||||
diffs = addTypeDiff(diffs, compareIntValues("MaxItems", type1.MaxItems, type2.MaxItems, WidenedType, NarrowedType))
|
||||
diffs = addTypeDiff(diffs, compareIntValues("MinItems", type1.MinItems, type2.MinItems, NarrowedType, WidenedType))
|
||||
|
||||
}
|
||||
return diffs
|
||||
}
|
||||
|
||||
// CheckStringTypeChanges checks for changes to or from a string type
|
||||
func (sd *SpecAnalyser) CheckStringTypeChanges(diffs []TypeDiff, type1, type2 spec.SchemaProps) []TypeDiff {
|
||||
// string changes
|
||||
if type1.Type[0] == StringType &&
|
||||
type2.Type[0] == StringType {
|
||||
diffs = addTypeDiff(diffs, compareIntValues("MinLength", type1.MinLength, type2.MinLength, NarrowedType, WidenedType))
|
||||
diffs = addTypeDiff(diffs, compareIntValues("MaxLength", type1.MinLength, type2.MinLength, WidenedType, NarrowedType))
|
||||
if type1.Pattern != type2.Pattern {
|
||||
diffs = addTypeDiff(diffs, TypeDiff{Change: ChangedType, Description: fmt.Sprintf("Pattern Changed:%s->%s", type1.Pattern, type2.Pattern)})
|
||||
}
|
||||
if type1.Type[0] == StringType {
|
||||
if len(type1.Enum) > 0 {
|
||||
enumDiffs := sd.compareEnums(type1.Enum, type2.Enum)
|
||||
diffs = append(diffs, enumDiffs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return diffs
|
||||
}
|
||||
|
||||
// CheckNumericTypeChanges checks for changes to or from a numeric type
|
||||
func (sd *SpecAnalyser) CheckNumericTypeChanges(diffs []TypeDiff, type1, type2 spec.SchemaProps) []TypeDiff {
|
||||
// Number
|
||||
_, type1IsNumeric := numberWideness[type1.Type[0]]
|
||||
_, type2IsNumeric := numberWideness[type2.Type[0]]
|
||||
|
||||
if type1IsNumeric && type2IsNumeric {
|
||||
diffs = addTypeDiff(diffs, compareFloatValues("Maximum", type1.Maximum, type2.Maximum, WidenedType, NarrowedType))
|
||||
diffs = addTypeDiff(diffs, compareFloatValues("Minimum", type1.Minimum, type2.Minimum, NarrowedType, WidenedType))
|
||||
if type1.ExclusiveMaximum && !type2.ExclusiveMaximum {
|
||||
diffs = addTypeDiff(diffs, TypeDiff{Change: WidenedType, Description: fmt.Sprintf("Exclusive Maximum Removed:%v->%v", type1.ExclusiveMaximum, type2.ExclusiveMaximum)})
|
||||
}
|
||||
if !type1.ExclusiveMaximum && type2.ExclusiveMaximum {
|
||||
diffs = addTypeDiff(diffs, TypeDiff{Change: NarrowedType, Description: fmt.Sprintf("Exclusive Maximum Added:%v->%v", type1.ExclusiveMaximum, type2.ExclusiveMaximum)})
|
||||
}
|
||||
if type1.ExclusiveMinimum && !type2.ExclusiveMinimum {
|
||||
diffs = addTypeDiff(diffs, TypeDiff{Change: WidenedType, Description: fmt.Sprintf("Exclusive Minimum Removed:%v->%v", type1.ExclusiveMaximum, type2.ExclusiveMaximum)})
|
||||
}
|
||||
if !type1.ExclusiveMinimum && type2.ExclusiveMinimum {
|
||||
diffs = addTypeDiff(diffs, TypeDiff{Change: NarrowedType, Description: fmt.Sprintf("Exclusive Minimum Added:%v->%v", type1.ExclusiveMinimum, type2.ExclusiveMinimum)})
|
||||
}
|
||||
}
|
||||
return diffs
|
||||
}
|
||||
|
||||
// CompareTypes computes type specific property diffs
|
||||
func (sd *SpecAnalyser) CompareTypes(type1, type2 spec.SchemaProps) []TypeDiff {
|
||||
|
||||
diffs := []TypeDiff{}
|
||||
|
||||
diffs = sd.CheckToFromPrimitiveType(diffs, type1, type2)
|
||||
|
||||
if len(diffs) > 0 {
|
||||
return diffs
|
||||
}
|
||||
|
||||
diffs = sd.CheckToFromArrayType(diffs, type1, type2)
|
||||
|
||||
if len(diffs) > 0 {
|
||||
return diffs
|
||||
}
|
||||
|
||||
// check type hierarchy change eg string -> integer = NarrowedChange
|
||||
//Type
|
||||
//Format
|
||||
if type1.Type[0] != type2.Type[0] ||
|
||||
type1.Format != type2.Format {
|
||||
diff := getTypeHierarchyChange(primitiveTypeString(type1.Type[0], type1.Format), primitiveTypeString(type2.Type[0], type2.Format))
|
||||
diffs = addTypeDiff(diffs, diff)
|
||||
}
|
||||
|
||||
diffs = sd.CheckStringTypeChanges(diffs, type1, type2)
|
||||
|
||||
if len(diffs) > 0 {
|
||||
return diffs
|
||||
}
|
||||
|
||||
diffs = sd.CheckNumericTypeChanges(diffs, type1, type2)
|
||||
|
||||
if len(diffs) > 0 {
|
||||
return diffs
|
||||
}
|
||||
|
||||
return diffs
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) compareParams(urlMethod URLMethod, location string, name string, param1, param2 spec.Parameter) {
|
||||
diffLocation := DifferenceLocation{URL: urlMethod.Path, Method: urlMethod.Method}
|
||||
|
||||
childLocation := diffLocation.AddNode(getNameOnlyDiffNode(strings.Title(location)))
|
||||
paramLocation := diffLocation.AddNode(getNameOnlyDiffNode(name))
|
||||
sd.compareDescripton(paramLocation, param1.Description, param2.Description)
|
||||
|
||||
if param1.Schema != nil && param2.Schema != nil {
|
||||
childLocation = childLocation.AddNode(getSchemaDiffNode(name, param2.Schema))
|
||||
sd.compareSchema(childLocation, param1.Schema, param2.Schema, param1.Required, param2.Required)
|
||||
}
|
||||
diffs := sd.CompareTypes(forParam(param1), forParam(param2))
|
||||
|
||||
childLocation = childLocation.AddNode(getSchemaDiffNode(name, param2.Schema))
|
||||
for _, eachDiff := range diffs {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{
|
||||
DifferenceLocation: childLocation,
|
||||
Code: eachDiff.Change,
|
||||
DiffInfo: eachDiff.Description})
|
||||
}
|
||||
if param1.Required != param2.Required {
|
||||
code := ChangedRequiredToOptionalParam
|
||||
if param2.Required {
|
||||
code = ChangedOptionalToRequiredParam
|
||||
}
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: childLocation, Code: code})
|
||||
}
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) compareSimpleSchema(location DifferenceLocation, schema1, schema2 *spec.SimpleSchema, required1, required2 bool) {
|
||||
if schema1 == nil || schema2 == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if schema1.Type == ArrayType {
|
||||
refSchema1 := schema1.Items.SimpleSchema
|
||||
refSchema2 := schema2.Items.SimpleSchema
|
||||
|
||||
childLocation := location.AddNode(getSimpleSchemaDiffNode("", schema1))
|
||||
sd.compareSimpleSchema(childLocation, &refSchema1, &refSchema2, required1, required2)
|
||||
return
|
||||
}
|
||||
if required1 != required2 {
|
||||
code := AddedRequiredProperty
|
||||
if required1 {
|
||||
code = ChangedRequiredToOptional
|
||||
|
||||
}
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: code})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) compareDescripton(location DifferenceLocation, desc1, desc2 string) {
|
||||
if desc1 != desc2 {
|
||||
code := ChangedDescripton
|
||||
if len(desc1) > 0 {
|
||||
code = DeletedDescripton
|
||||
} else if len(desc2) > 0 {
|
||||
code = AddedDescripton
|
||||
}
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: code})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) compareSchema(location DifferenceLocation, schema1, schema2 *spec.Schema, required1, required2 bool) {
|
||||
|
||||
if schema1 == nil || schema2 == nil {
|
||||
return
|
||||
}
|
||||
|
||||
sd.compareDescripton(location, schema1.Description, schema2.Description)
|
||||
|
||||
if len(schema1.Type) == 0 {
|
||||
refSchema1, definition1 := sd.schemaFromRef(schema1, &sd.Definitions1)
|
||||
refSchema2, definition2 := sd.schemaFromRef(schema2, &sd.Definitions2)
|
||||
|
||||
if len(definition1) > 0 {
|
||||
info := fmt.Sprintf("[%s -> %s]", definition1, definition2)
|
||||
|
||||
if definition1 != definition2 {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location,
|
||||
Code: ChangedType,
|
||||
DiffInfo: info,
|
||||
})
|
||||
}
|
||||
sd.compareSchema(location, refSchema1, refSchema2, required1, required2)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if schema1.Type[0] == ArrayType {
|
||||
refSchema1, definition1 := sd.schemaFromRef(schema1.Items.Schema, &sd.Definitions1)
|
||||
refSchema2, _ := sd.schemaFromRef(schema2.Items.Schema, &sd.Definitions2)
|
||||
|
||||
if len(definition1) > 0 {
|
||||
childLocation := location.AddNode(getSchemaDiffNode("", schema1))
|
||||
sd.compareSchema(childLocation, refSchema1, refSchema2, required1, required2)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
diffs := sd.CompareTypes(schema1.SchemaProps, schema2.SchemaProps)
|
||||
|
||||
for _, eachTypeDiff := range diffs {
|
||||
if eachTypeDiff.Change != NoChangeDetected {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: eachTypeDiff.Change, DiffInfo: eachTypeDiff.Description})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if required1 != required2 {
|
||||
code := AddedRequiredProperty
|
||||
if required1 {
|
||||
code = ChangedRequiredToOptional
|
||||
|
||||
}
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: location, Code: code})
|
||||
}
|
||||
requiredProps2 := sliceToStrMap(schema2.Required)
|
||||
requiredProps1 := sliceToStrMap(schema1.Required)
|
||||
schema1Props := sd.propertiesFor(schema1, &sd.Definitions1)
|
||||
schema2Props := sd.propertiesFor(schema2, &sd.Definitions2)
|
||||
// find deleted and changed properties
|
||||
for eachProp1Name, eachProp1 := range schema1Props {
|
||||
eachProp1 := eachProp1
|
||||
_, required1 := requiredProps1[eachProp1Name]
|
||||
_, required2 := requiredProps2[eachProp1Name]
|
||||
childLoc := sd.addChildDiffNode(location, eachProp1Name, &eachProp1)
|
||||
|
||||
if eachProp2, ok := schema2Props[eachProp1Name]; ok {
|
||||
sd.compareSchema(childLoc, &eachProp1, &eachProp2, required1, required2)
|
||||
sd.compareDescripton(childLoc, eachProp1.Description, eachProp2.Description)
|
||||
} else {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: childLoc, Code: DeletedProperty})
|
||||
}
|
||||
}
|
||||
|
||||
// find added properties
|
||||
for eachProp2Name, eachProp2 := range schema2.Properties {
|
||||
eachProp2 := eachProp2
|
||||
if _, ok := schema1.Properties[eachProp2Name]; !ok {
|
||||
childLoc := sd.addChildDiffNode(location, eachProp2Name, &eachProp2)
|
||||
_, required2 := requiredProps2[eachProp2Name]
|
||||
code := AddedProperty
|
||||
if required2 {
|
||||
code = AddedRequiredProperty
|
||||
}
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: childLoc, Code: code})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) addChildDiffNode(location DifferenceLocation, propName string, propSchema *spec.Schema) DifferenceLocation {
|
||||
newLoc := location
|
||||
if newLoc.Node != nil {
|
||||
newLoc.Node = newLoc.Node.Copy()
|
||||
}
|
||||
|
||||
childNode := sd.fromSchemaProps(propName, &propSchema.SchemaProps)
|
||||
if newLoc.Node != nil {
|
||||
newLoc.Node.AddLeafNode(&childNode)
|
||||
} else {
|
||||
newLoc.Node = &childNode
|
||||
}
|
||||
return newLoc
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) fromSchemaProps(fieldName string, props *spec.SchemaProps) Node {
|
||||
node := Node{}
|
||||
node.IsArray = props.Type[0] == ArrayType
|
||||
if !node.IsArray {
|
||||
node.TypeName = props.Type[0]
|
||||
}
|
||||
node.Field = fieldName
|
||||
return node
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) compareEnums(left, right []interface{}) []TypeDiff {
|
||||
diffs := []TypeDiff{}
|
||||
|
||||
leftStrs := []string{}
|
||||
rightStrs := []string{}
|
||||
for _, eachLeft := range left {
|
||||
leftStrs = append(leftStrs, fmt.Sprintf("%v", eachLeft))
|
||||
}
|
||||
for _, eachRight := range right {
|
||||
rightStrs = append(rightStrs, fmt.Sprintf("%v", eachRight))
|
||||
}
|
||||
added, deleted, _ := FromStringArray(leftStrs).DiffsTo(rightStrs)
|
||||
if len(added) > 0 {
|
||||
typeChange := strings.Join(added, ",")
|
||||
diffs = append(diffs, TypeDiff{Change: AddedEnumValue, Description: typeChange})
|
||||
}
|
||||
if len(deleted) > 0 {
|
||||
typeChange := strings.Join(deleted, ",")
|
||||
diffs = append(diffs, TypeDiff{Change: DeletedEnumValue, Description: typeChange})
|
||||
}
|
||||
|
||||
return diffs
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) findAddedEndpoints() {
|
||||
for URLMethod := range sd.urlMethods2 {
|
||||
if _, ok := sd.urlMethods1[URLMethod]; !ok {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: DifferenceLocation{URL: URLMethod.Path, Method: URLMethod.Method}, Code: AddedEndpoint})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) findDeletedEndpoints() {
|
||||
for eachURLMethod, operation1 := range sd.urlMethods1 {
|
||||
code := DeletedEndpoint
|
||||
if (operation1.ParentPathItem.Options != nil && operation1.ParentPathItem.Options.Deprecated) ||
|
||||
(operation1.Operation.Deprecated) {
|
||||
code = DeletedDeprecatedEndpoint
|
||||
}
|
||||
if _, ok := sd.urlMethods2[eachURLMethod]; !ok {
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: DifferenceLocation{URL: eachURLMethod.Path, Method: eachURLMethod.Method}, Code: code})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) analyseMetaDataProperty(item1, item2 string, codeIfDiff SpecChangeCode, compatIfDiff Compatibility) {
|
||||
if item1 != item2 {
|
||||
diffSpec := fmt.Sprintf("%s -> %s", item1, item2)
|
||||
sd.Diffs = sd.Diffs.addDiff(SpecDifference{DifferenceLocation: DifferenceLocation{Node: &Node{Field: "Spec Metadata"}}, Code: codeIfDiff, Compatibility: compatIfDiff, DiffInfo: diffSpec})
|
||||
}
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) schemaFromRef(schema *spec.Schema, defns *spec.Definitions) (actualSchema *spec.Schema, definitionName string) {
|
||||
ref := schema.Ref
|
||||
url := ref.GetURL()
|
||||
if url == nil {
|
||||
return schema, ""
|
||||
}
|
||||
fragmentParts := strings.Split(url.Fragment, "/")
|
||||
numParts := len(fragmentParts)
|
||||
if numParts == 0 {
|
||||
return schema, ""
|
||||
}
|
||||
|
||||
definitionName = fragmentParts[numParts-1]
|
||||
foundSchema, ok := (*defns)[definitionName]
|
||||
if !ok {
|
||||
return nil, definitionName
|
||||
}
|
||||
actualSchema = &foundSchema
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func (sd *SpecAnalyser) propertiesFor(schema *spec.Schema, defns *spec.Definitions) map[string]spec.Schema {
|
||||
schemaFromRef, _ := sd.schemaFromRef(schema, defns)
|
||||
schema = schemaFromRef
|
||||
props := map[string]spec.Schema{}
|
||||
|
||||
if schema.Properties != nil {
|
||||
for name, prop := range schema.Properties {
|
||||
prop := prop
|
||||
eachProp, _ := sd.schemaFromRef(&prop, defns)
|
||||
props[name] = *eachProp
|
||||
}
|
||||
}
|
||||
for _, eachAllOf := range schema.AllOf {
|
||||
eachAllOf := eachAllOf
|
||||
eachAllOfActual, _ := sd.schemaFromRef(&eachAllOf, defns)
|
||||
for name, prop := range eachAllOfActual.Properties {
|
||||
prop := prop
|
||||
eachProp, _ := sd.schemaFromRef(&prop, defns)
|
||||
props[name] = *eachProp
|
||||
}
|
||||
}
|
||||
return props
|
||||
}
|
190
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go
generated
vendored
Normal file
190
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go
generated
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// SpecDifference encapsulates the details of an individual diff in part of a spec
|
||||
type SpecDifference struct {
|
||||
DifferenceLocation DifferenceLocation `json:"location"`
|
||||
Code SpecChangeCode `json:"code"`
|
||||
Compatibility Compatibility `json:"compatibility"`
|
||||
DiffInfo string `json:"info,omitempty"`
|
||||
}
|
||||
|
||||
// SpecDifferences list of differences
|
||||
type SpecDifferences []SpecDifference
|
||||
|
||||
// Matches returns true if the diff matches another
|
||||
func (sd SpecDifference) Matches(other SpecDifference) bool {
|
||||
return sd.Code == other.Code &&
|
||||
sd.Compatibility == other.Compatibility &&
|
||||
sd.DiffInfo == other.DiffInfo &&
|
||||
equalLocations(sd.DifferenceLocation, other.DifferenceLocation)
|
||||
}
|
||||
|
||||
func equalLocations(a, b DifferenceLocation) bool {
|
||||
return a.Method == b.Method &&
|
||||
a.Response == b.Response &&
|
||||
a.URL == b.URL &&
|
||||
equalNodes(a.Node, b.Node)
|
||||
}
|
||||
|
||||
func equalNodes(a, b *Node) bool {
|
||||
if a == nil && b == nil {
|
||||
return true
|
||||
}
|
||||
if a == nil || b == nil {
|
||||
return false
|
||||
}
|
||||
return a.Field == b.Field &&
|
||||
a.IsArray == b.IsArray &&
|
||||
a.TypeName == b.TypeName &&
|
||||
equalNodes(a.ChildNode, b.ChildNode)
|
||||
|
||||
}
|
||||
|
||||
// BreakingChangeCount Calculates the breaking change count
|
||||
func (sd SpecDifferences) BreakingChangeCount() int {
|
||||
count := 0
|
||||
for _, eachDiff := range sd {
|
||||
if eachDiff.Compatibility == Breaking {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// FilterIgnores returns a copy of the list without the items in the specified ignore list
|
||||
func (sd SpecDifferences) FilterIgnores(ignores SpecDifferences) SpecDifferences {
|
||||
newDiffs := SpecDifferences{}
|
||||
for _, eachDiff := range sd {
|
||||
if !ignores.Contains(eachDiff) {
|
||||
newDiffs = newDiffs.addDiff(eachDiff)
|
||||
}
|
||||
}
|
||||
return newDiffs
|
||||
}
|
||||
|
||||
// Contains Returns true if the item contains the specified item
|
||||
func (sd SpecDifferences) Contains(diff SpecDifference) bool {
|
||||
for _, eachDiff := range sd {
|
||||
if eachDiff.Matches(diff) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// String std string renderer
|
||||
func (sd SpecDifference) String() string {
|
||||
isResponse := sd.DifferenceLocation.Response > 0
|
||||
hasMethod := len(sd.DifferenceLocation.Method) > 0
|
||||
hasURL := len(sd.DifferenceLocation.URL) > 0
|
||||
|
||||
prefix := ""
|
||||
direction := ""
|
||||
|
||||
if isResponse {
|
||||
direction = " Response"
|
||||
if hasURL {
|
||||
if hasMethod {
|
||||
prefix = fmt.Sprintf("%s:%s -> %d", sd.DifferenceLocation.URL, sd.DifferenceLocation.Method, sd.DifferenceLocation.Response)
|
||||
} else {
|
||||
prefix = fmt.Sprintf("%s ", sd.DifferenceLocation.URL)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if hasURL {
|
||||
if hasMethod {
|
||||
direction = " Request"
|
||||
prefix = fmt.Sprintf("%s:%s", sd.DifferenceLocation.URL, sd.DifferenceLocation.Method)
|
||||
} else {
|
||||
prefix = fmt.Sprintf("%s ", sd.DifferenceLocation.URL)
|
||||
}
|
||||
} else {
|
||||
prefix = " Metadata"
|
||||
}
|
||||
}
|
||||
|
||||
paramOrPropertyLocation := ""
|
||||
if sd.DifferenceLocation.Node != nil {
|
||||
paramOrPropertyLocation = " - " + sd.DifferenceLocation.Node.String() + " "
|
||||
}
|
||||
optionalInfo := ""
|
||||
if sd.DiffInfo != "" {
|
||||
optionalInfo = fmt.Sprintf(" <%s>", sd.DiffInfo)
|
||||
}
|
||||
return fmt.Sprintf("%s%s%s- %s%s", prefix, direction, paramOrPropertyLocation, sd.Code.Description(), optionalInfo)
|
||||
}
|
||||
|
||||
func (sd SpecDifferences) addDiff(diff SpecDifference) SpecDifferences {
|
||||
context := Request
|
||||
if diff.DifferenceLocation.Response > 0 {
|
||||
context = Response
|
||||
}
|
||||
diff.Compatibility = getCompatibilityForChange(diff.Code, context)
|
||||
|
||||
return append(sd, diff)
|
||||
}
|
||||
|
||||
// ReportCompatibility lists and spec
|
||||
func (sd *SpecDifferences) ReportCompatibility() error {
|
||||
breakingCount := sd.BreakingChangeCount()
|
||||
if breakingCount > 0 {
|
||||
fmt.Printf("\nBREAKING CHANGES:\n=================\n")
|
||||
sd.reportChanges(Breaking)
|
||||
return fmt.Errorf("compatibility Test FAILED: %d Breaking changes detected", breakingCount)
|
||||
}
|
||||
log.Printf("Compatibility test OK. No breaking changes identified.")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sd SpecDifferences) reportChanges(compat Compatibility) {
|
||||
toReportList := []string{}
|
||||
|
||||
for _, diff := range sd {
|
||||
if diff.Compatibility == compat {
|
||||
toReportList = append(toReportList, diff.String())
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(toReportList, func(i, j int) bool {
|
||||
return toReportList[i] < toReportList[j]
|
||||
})
|
||||
|
||||
for _, eachDiff := range toReportList {
|
||||
fmt.Println(eachDiff)
|
||||
}
|
||||
}
|
||||
|
||||
// ReportAllDiffs lists all the diffs between two specs
|
||||
func (sd SpecDifferences) ReportAllDiffs(fmtJSON bool) error {
|
||||
if fmtJSON {
|
||||
|
||||
b, err := JSONMarshal(sd)
|
||||
if err != nil {
|
||||
log.Fatalf("Couldn't print results: %v", err)
|
||||
}
|
||||
pretty, err := prettyprint(b)
|
||||
if err != nil {
|
||||
log.Fatalf("Couldn't print results: %v", err)
|
||||
}
|
||||
fmt.Println(string(pretty))
|
||||
return nil
|
||||
}
|
||||
numDiffs := len(sd)
|
||||
if numDiffs == 0 {
|
||||
fmt.Println("No changes identified")
|
||||
return nil
|
||||
}
|
||||
|
||||
if numDiffs != sd.BreakingChangeCount() {
|
||||
fmt.Println("NON-BREAKING CHANGES:\n=====================")
|
||||
sd.reportChanges(NonBreaking)
|
||||
}
|
||||
|
||||
return sd.ReportCompatibility()
|
||||
}
|
170
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go
generated
vendored
Normal file
170
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go
generated
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
func forItems(items *spec.Items) *spec.Schema {
|
||||
if items == nil {
|
||||
return nil
|
||||
}
|
||||
valids := items.CommonValidations
|
||||
schema := spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{items.SimpleSchema.Type},
|
||||
Format: items.SimpleSchema.Format,
|
||||
Maximum: valids.Maximum,
|
||||
ExclusiveMaximum: valids.ExclusiveMaximum,
|
||||
Minimum: valids.Minimum,
|
||||
ExclusiveMinimum: valids.ExclusiveMinimum,
|
||||
MaxLength: valids.MaxLength,
|
||||
MinLength: valids.MinLength,
|
||||
Pattern: valids.Pattern,
|
||||
MaxItems: valids.MaxItems,
|
||||
MinItems: valids.MinItems,
|
||||
UniqueItems: valids.UniqueItems,
|
||||
MultipleOf: valids.MultipleOf,
|
||||
Enum: valids.Enum,
|
||||
},
|
||||
}
|
||||
return &schema
|
||||
}
|
||||
|
||||
func forParam(param spec.Parameter) spec.SchemaProps {
|
||||
return spec.SchemaProps{
|
||||
Type: []string{param.Type},
|
||||
Format: param.Format,
|
||||
Items: &spec.SchemaOrArray{Schema: forItems(param.Items)},
|
||||
Maximum: param.Maximum,
|
||||
ExclusiveMaximum: param.ExclusiveMaximum,
|
||||
Minimum: param.Minimum,
|
||||
ExclusiveMinimum: param.ExclusiveMinimum,
|
||||
MaxLength: param.MaxLength,
|
||||
MinLength: param.MinLength,
|
||||
Pattern: param.Pattern,
|
||||
MaxItems: param.MaxItems,
|
||||
MinItems: param.MinItems,
|
||||
UniqueItems: param.UniqueItems,
|
||||
MultipleOf: param.MultipleOf,
|
||||
Enum: param.Enum,
|
||||
}
|
||||
}
|
||||
|
||||
// OperationMap saves indexing operations in PathItems individually
|
||||
type OperationMap map[string]*spec.Operation
|
||||
|
||||
func toMap(item *spec.PathItem) OperationMap {
|
||||
m := make(OperationMap)
|
||||
|
||||
if item.Post != nil {
|
||||
m["post"] = item.Post
|
||||
}
|
||||
if item.Get != nil {
|
||||
m["get"] = item.Get
|
||||
}
|
||||
if item.Put != nil {
|
||||
m["put"] = item.Put
|
||||
}
|
||||
if item.Patch != nil {
|
||||
m["patch"] = item.Patch
|
||||
}
|
||||
if item.Head != nil {
|
||||
m["head"] = item.Head
|
||||
}
|
||||
if item.Options != nil {
|
||||
m["options"] = item.Options
|
||||
}
|
||||
if item.Delete != nil {
|
||||
m["delete"] = item.Delete
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func getURLMethodsFor(spec *spec.Swagger) URLMethods {
|
||||
returnURLMethods := URLMethods{}
|
||||
|
||||
for url, eachPath := range spec.Paths.Paths {
|
||||
eachPath := eachPath
|
||||
opsMap := toMap(&eachPath)
|
||||
for method, op := range opsMap {
|
||||
returnURLMethods[URLMethod{url, method}] = &PathItemOp{&eachPath, op}
|
||||
}
|
||||
}
|
||||
return returnURLMethods
|
||||
}
|
||||
|
||||
func sliceToStrMap(elements []string) map[string]bool {
|
||||
elementMap := make(map[string]bool)
|
||||
for _, s := range elements {
|
||||
elementMap[s] = true
|
||||
}
|
||||
return elementMap
|
||||
}
|
||||
|
||||
func isStringType(typeName string) bool {
|
||||
return typeName == "string" || typeName == "password"
|
||||
}
|
||||
|
||||
const objType = "obj"
|
||||
|
||||
func getTypeHierarchyChange(type1, type2 string) TypeDiff {
|
||||
if type1 == type2 {
|
||||
return TypeDiff{Change: NoChangeDetected, Description: ""}
|
||||
}
|
||||
fromType := type1
|
||||
if fromType == "" {
|
||||
fromType = objType
|
||||
}
|
||||
toType := type2
|
||||
if toType == "" {
|
||||
toType = objType
|
||||
}
|
||||
diffDescription := fmt.Sprintf("%s -> %s", fromType, toType)
|
||||
if isStringType(type1) && !isStringType(type2) {
|
||||
return TypeDiff{Change: NarrowedType, Description: diffDescription}
|
||||
}
|
||||
if !isStringType(type1) && isStringType(type2) {
|
||||
return TypeDiff{Change: WidenedType, Description: diffDescription}
|
||||
}
|
||||
type1Wideness, type1IsNumeric := numberWideness[type1]
|
||||
type2Wideness, type2IsNumeric := numberWideness[type2]
|
||||
if type1IsNumeric && type2IsNumeric {
|
||||
if type1Wideness == type2Wideness {
|
||||
return TypeDiff{Change: ChangedToCompatibleType, Description: diffDescription}
|
||||
}
|
||||
if type1Wideness > type2Wideness {
|
||||
return TypeDiff{Change: NarrowedType, Description: diffDescription}
|
||||
}
|
||||
if type1Wideness < type2Wideness {
|
||||
return TypeDiff{Change: WidenedType, Description: diffDescription}
|
||||
}
|
||||
}
|
||||
return TypeDiff{Change: ChangedType, Description: diffDescription}
|
||||
}
|
||||
|
||||
func compareFloatValues(fieldName string, val1 *float64, val2 *float64, ifGreaterCode SpecChangeCode, ifLessCode SpecChangeCode) TypeDiff {
|
||||
if val1 != nil && val2 != nil {
|
||||
if *val2 > *val1 {
|
||||
return TypeDiff{Change: ifGreaterCode, Description: fmt.Sprintf("%s %f->%f", fieldName, *val1, *val2)}
|
||||
}
|
||||
if *val2 < *val1 {
|
||||
return TypeDiff{Change: ifLessCode, Description: fmt.Sprintf("%s %f->%f", fieldName, *val1, *val2)}
|
||||
}
|
||||
}
|
||||
return TypeDiff{Change: NoChangeDetected, Description: ""}
|
||||
}
|
||||
|
||||
func compareIntValues(fieldName string, val1 *int64, val2 *int64, ifGreaterCode SpecChangeCode, ifLessCode SpecChangeCode) TypeDiff {
|
||||
if val1 != nil && val2 != nil {
|
||||
if *val2 > *val1 {
|
||||
return TypeDiff{Change: ifGreaterCode, Description: fmt.Sprintf("%s %d->%d", fieldName, *val1, *val2)}
|
||||
}
|
||||
if *val2 < *val1 {
|
||||
return TypeDiff{Change: ifLessCode, Description: fmt.Sprintf("%s %d->%d", fieldName, *val1, *val2)}
|
||||
}
|
||||
|
||||
}
|
||||
return TypeDiff{Change: NoChangeDetected, Description: ""}
|
||||
}
|
73
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go
generated
vendored
Normal file
73
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// ExpandSpec is a command that expands the $refs in a swagger document.
|
||||
//
|
||||
// There are no specific options for this expansion.
|
||||
type ExpandSpec struct {
|
||||
Compact bool `long:"compact" description:"applies to JSON formatted specs. When present, doesn't prettify the json"`
|
||||
Output flags.Filename `long:"output" short:"o" description:"the file to write to"`
|
||||
Format string `long:"format" description:"the format for the spec document" default:"json" choice:"yaml" choice:"json"`
|
||||
}
|
||||
|
||||
// Execute expands the spec
|
||||
func (c *ExpandSpec) Execute(args []string) error {
|
||||
if len(args) != 1 {
|
||||
return errors.New("expand command requires the single swagger document url to be specified")
|
||||
}
|
||||
|
||||
swaggerDoc := args[0]
|
||||
specDoc, err := loads.Spec(swaggerDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
exp, err := specDoc.Expanded()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeToFile(exp.Spec(), !c.Compact, c.Format, string(c.Output))
|
||||
}
|
||||
|
||||
func writeToFile(swspec *spec.Swagger, pretty bool, format string, output string) error {
|
||||
var b []byte
|
||||
var err error
|
||||
asJSON := format == "json"
|
||||
|
||||
if pretty && asJSON {
|
||||
b, err = json.MarshalIndent(swspec, "", " ")
|
||||
} else if asJSON {
|
||||
b, err = json.Marshal(swspec)
|
||||
} else {
|
||||
// marshals as YAML
|
||||
b, err = json.Marshal(swspec)
|
||||
if err == nil {
|
||||
d, ery := swag.BytesToYAMLDoc(b)
|
||||
if ery != nil {
|
||||
return ery
|
||||
}
|
||||
b, err = yaml.Marshal(d)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if output == "" {
|
||||
fmt.Println(string(b))
|
||||
return nil
|
||||
}
|
||||
return ioutil.WriteFile(output, b, 0644)
|
||||
}
|
48
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/flatten.go
generated
vendored
Normal file
48
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/flatten.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/go-openapi/analysis"
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-swagger/go-swagger/cmd/swagger/commands/generate"
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
)
|
||||
|
||||
// FlattenSpec is a command that flattens a swagger document
|
||||
// which will expand the remote references in a spec and move inline schemas to definitions
|
||||
// after flattening there are no complex inlined anymore
|
||||
type FlattenSpec struct {
|
||||
Compact bool `long:"compact" description:"applies to JSON formatted specs. When present, doesn't prettify the json"`
|
||||
Output flags.Filename `long:"output" short:"o" description:"the file to write to"`
|
||||
Format string `long:"format" description:"the format for the spec document" default:"json" choice:"yaml" choice:"json"`
|
||||
generate.FlattenCmdOptions
|
||||
}
|
||||
|
||||
// Execute flattens the spec
|
||||
func (c *FlattenSpec) Execute(args []string) error {
|
||||
if len(args) != 1 {
|
||||
return errors.New("flatten command requires the single swagger document url to be specified")
|
||||
}
|
||||
|
||||
swaggerDoc := args[0]
|
||||
specDoc, err := loads.Spec(swaggerDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
flattenOpts := c.FlattenCmdOptions.SetFlattenOptions(&analysis.FlattenOpts{
|
||||
// defaults
|
||||
Minimal: true,
|
||||
Verbose: true,
|
||||
Expand: false,
|
||||
RemoveUnused: false,
|
||||
})
|
||||
flattenOpts.BasePath = specDoc.SpecFilePath()
|
||||
flattenOpts.Spec = analysis.New(specDoc.Spec())
|
||||
if err := analysis.Flatten(*flattenOpts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeToFile(specDoc.Spec(), !c.Compact, c.Format, string(c.Output))
|
||||
}
|
27
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate.go
generated
vendored
Normal file
27
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import "github.com/go-swagger/go-swagger/cmd/swagger/commands/generate"
|
||||
|
||||
// Generate command to group all generator commands together
|
||||
type Generate struct {
|
||||
Model *generate.Model `command:"model"`
|
||||
Operation *generate.Operation `command:"operation"`
|
||||
Support *generate.Support `command:"support"`
|
||||
Server *generate.Server `command:"server"`
|
||||
Spec *generate.SpecFile `command:"spec"`
|
||||
Client *generate.Client `command:"client"`
|
||||
}
|
92
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/client.go
generated
vendored
Normal file
92
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/client.go
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package generate
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/go-swagger/go-swagger/generator"
|
||||
)
|
||||
|
||||
// Client the command to generate a swagger client
|
||||
type Client struct {
|
||||
shared
|
||||
Name string `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"`
|
||||
Operations []string `long:"operation" short:"O" description:"specify an operation to include, repeat for multiple"`
|
||||
Tags []string `long:"tags" description:"the tags to include, if not specified defaults to all"`
|
||||
Principal string `long:"principal" short:"P" description:"the model to use for the security principal"`
|
||||
Models []string `long:"model" short:"M" description:"specify a model to include, repeat for multiple"`
|
||||
DefaultScheme string `long:"default-scheme" description:"the default scheme for this client" default:"http"`
|
||||
DefaultProduces string `long:"default-produces" description:"the default mime type that API operations produce" default:"application/json"`
|
||||
SkipModels bool `long:"skip-models" description:"no models will be generated when this flag is specified"`
|
||||
SkipOperations bool `long:"skip-operations" description:"no operations will be generated when this flag is specified"`
|
||||
DumpData bool `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
|
||||
SkipValidation bool `long:"skip-validation" description:"skips validation of spec prior to generation"`
|
||||
}
|
||||
|
||||
func (c *Client) getOpts() (*generator.GenOpts, error) {
|
||||
return &generator.GenOpts{
|
||||
Spec: string(c.Spec),
|
||||
|
||||
Target: string(c.Target),
|
||||
APIPackage: c.APIPackage,
|
||||
ModelPackage: c.ModelPackage,
|
||||
ServerPackage: c.ServerPackage,
|
||||
ClientPackage: c.ClientPackage,
|
||||
Principal: c.Principal,
|
||||
DefaultScheme: c.DefaultScheme,
|
||||
DefaultProduces: c.DefaultProduces,
|
||||
IncludeModel: !c.SkipModels,
|
||||
IncludeValidator: !c.SkipModels,
|
||||
IncludeHandler: !c.SkipOperations,
|
||||
IncludeParameters: !c.SkipOperations,
|
||||
IncludeResponses: !c.SkipOperations,
|
||||
ValidateSpec: !c.SkipValidation,
|
||||
Tags: c.Tags,
|
||||
IncludeSupport: true,
|
||||
Template: c.Template,
|
||||
TemplateDir: string(c.TemplateDir),
|
||||
DumpData: c.DumpData,
|
||||
ExistingModels: c.ExistingModels,
|
||||
IsClient: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Client) getShared() *shared {
|
||||
return &c.shared
|
||||
}
|
||||
|
||||
func (c *Client) generate(opts *generator.GenOpts) error {
|
||||
return generator.GenerateClient(c.Name, c.Models, c.Operations, opts)
|
||||
}
|
||||
|
||||
func (c *Client) log(rp string) {
|
||||
log.Printf(`Generation completed!
|
||||
|
||||
For this generation to compile you need to have some packages in your GOPATH:
|
||||
|
||||
* github.com/go-openapi/errors
|
||||
* github.com/go-openapi/runtime
|
||||
* github.com/go-openapi/runtime/client
|
||||
* github.com/go-openapi/strfmt
|
||||
|
||||
You can get these now with: go get -u -f %s/...
|
||||
`, rp)
|
||||
}
|
||||
|
||||
// Execute runs this command
|
||||
func (c *Client) Execute(args []string) error {
|
||||
return createSwagger(c)
|
||||
}
|
16
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/contrib.go
generated
vendored
Normal file
16
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/contrib.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"github.com/go-swagger/go-swagger/generator"
|
||||
)
|
||||
|
||||
// contribOptionsOverride gives contributed templates the ability to override the options if they need
|
||||
func contribOptionsOverride(opts *generator.GenOpts) {
|
||||
switch opts.Template {
|
||||
case "stratoscale":
|
||||
// Stratoscale template needs to regenerate the configureapi on every run.
|
||||
opts.RegenerateConfigureAPI = true
|
||||
// It also does not use the main.go
|
||||
opts.IncludeMain = false
|
||||
}
|
||||
}
|
53
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/model.go
generated
vendored
Normal file
53
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/model.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package generate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Model the generate model file command
|
||||
type Model struct {
|
||||
shared
|
||||
Name []string `long:"name" short:"n" description:"the model to generate"`
|
||||
NoStruct bool `long:"skip-struct" description:"when present will not generate the model struct"`
|
||||
DumpData bool `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
|
||||
SkipValidation bool `long:"skip-validation" description:"skips validation of spec prior to generation"`
|
||||
}
|
||||
|
||||
// Execute generates a model file
|
||||
func (m *Model) Execute(args []string) error {
|
||||
|
||||
if m.DumpData && len(m.Name) > 1 {
|
||||
return errors.New("only 1 model at a time is supported for dumping data")
|
||||
}
|
||||
|
||||
if m.ExistingModels != "" {
|
||||
log.Println("warning: Ignoring existing-models flag when generating models.")
|
||||
}
|
||||
s := &Server{
|
||||
shared: m.shared,
|
||||
Models: m.Name,
|
||||
DumpData: m.DumpData,
|
||||
ExcludeMain: true,
|
||||
ExcludeSpec: true,
|
||||
SkipSupport: true,
|
||||
SkipOperations: true,
|
||||
SkipModels: m.NoStruct,
|
||||
SkipValidation: m.SkipValidation,
|
||||
}
|
||||
return s.Execute(args)
|
||||
}
|
87
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/operation.go
generated
vendored
Normal file
87
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/operation.go
generated
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package generate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"github.com/go-swagger/go-swagger/generator"
|
||||
)
|
||||
|
||||
// Operation the generate operation files command
|
||||
type Operation struct {
|
||||
shared
|
||||
Name []string `long:"name" short:"n" required:"true" description:"the operations to generate, repeat for multiple"`
|
||||
Tags []string `long:"tags" description:"the tags to include, if not specified defaults to all"`
|
||||
Principal string `short:"P" long:"principal" description:"the model to use for the security principal"`
|
||||
DefaultScheme string `long:"default-scheme" description:"the default scheme for this API" default:"http"`
|
||||
NoHandler bool `long:"skip-handler" description:"when present will not generate an operation handler"`
|
||||
NoStruct bool `long:"skip-parameters" description:"when present will not generate the parameter model struct"`
|
||||
NoResponses bool `long:"skip-responses" description:"when present will not generate the response model struct"`
|
||||
NoURLBuilder bool `long:"skip-url-builder" description:"when present will not generate a URL builder"`
|
||||
DumpData bool `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
|
||||
SkipValidation bool `long:"skip-validation" description:"skips validation of spec prior to generation"`
|
||||
}
|
||||
|
||||
func (o *Operation) getOpts() (*generator.GenOpts, error) {
|
||||
return &generator.GenOpts{
|
||||
Spec: string(o.Spec),
|
||||
Target: string(o.Target),
|
||||
APIPackage: o.APIPackage,
|
||||
ModelPackage: o.ModelPackage,
|
||||
ServerPackage: o.ServerPackage,
|
||||
ClientPackage: o.ClientPackage,
|
||||
Principal: o.Principal,
|
||||
DumpData: o.DumpData,
|
||||
DefaultScheme: o.DefaultScheme,
|
||||
TemplateDir: string(o.TemplateDir),
|
||||
IncludeHandler: !o.NoHandler,
|
||||
IncludeResponses: !o.NoResponses,
|
||||
IncludeParameters: !o.NoStruct,
|
||||
IncludeURLBuilder: !o.NoURLBuilder,
|
||||
Tags: o.Tags,
|
||||
ValidateSpec: !o.SkipValidation,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (o *Operation) getShared() *shared {
|
||||
return &o.shared
|
||||
}
|
||||
|
||||
func (o *Operation) generate(opts *generator.GenOpts) error {
|
||||
return generator.GenerateServerOperation(o.Name, opts)
|
||||
}
|
||||
|
||||
func (o *Operation) log(rp string) {
|
||||
|
||||
log.Printf(`Generation completed!
|
||||
|
||||
For this generation to compile you need to have some packages in your GOPATH:
|
||||
|
||||
* github.com/go-openapi/runtime
|
||||
|
||||
You can get these now with: go get -u -f %s/...
|
||||
`, rp)
|
||||
}
|
||||
|
||||
// Execute generates a model file
|
||||
func (o *Operation) Execute(args []string) error {
|
||||
if o.DumpData && len(o.Name) > 1 {
|
||||
return errors.New("only 1 operation at a time is supported for dumping data")
|
||||
}
|
||||
|
||||
return createSwagger(o)
|
||||
}
|
119
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go
generated
vendored
Normal file
119
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package generate
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/go-swagger/go-swagger/generator"
|
||||
)
|
||||
|
||||
// Server the command to generate an entire server application
|
||||
type Server struct {
|
||||
shared
|
||||
Name string `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"`
|
||||
Operations []string `long:"operation" short:"O" description:"specify an operation to include, repeat for multiple"`
|
||||
Tags []string `long:"tags" description:"the tags to include, if not specified defaults to all"`
|
||||
Principal string `long:"principal" short:"P" description:"the model to use for the security principal"`
|
||||
DefaultScheme string `long:"default-scheme" description:"the default scheme for this API" default:"http"`
|
||||
Models []string `long:"model" short:"M" description:"specify a model to include, repeat for multiple"`
|
||||
SkipModels bool `long:"skip-models" description:"no models will be generated when this flag is specified"`
|
||||
SkipOperations bool `long:"skip-operations" description:"no operations will be generated when this flag is specified"`
|
||||
SkipSupport bool `long:"skip-support" description:"no supporting files will be generated when this flag is specified"`
|
||||
ExcludeMain bool `long:"exclude-main" description:"exclude main function, so just generate the library"`
|
||||
ExcludeSpec bool `long:"exclude-spec" description:"don't embed the swagger specification"`
|
||||
WithContext bool `long:"with-context" description:"handlers get a context as first arg (deprecated)"`
|
||||
DumpData bool `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
|
||||
FlagStrategy string `long:"flag-strategy" description:"the strategy to provide flags for the server" default:"go-flags" choice:"go-flags" choice:"pflag"`
|
||||
CompatibilityMode string `long:"compatibility-mode" description:"the compatibility mode for the tls server" default:"modern" choice:"modern" choice:"intermediate"`
|
||||
SkipValidation bool `long:"skip-validation" description:"skips validation of spec prior to generation"`
|
||||
RegenerateConfigureAPI bool `long:"regenerate-configureapi" description:"Force regeneration of configureapi.go"`
|
||||
KeepSpecOrder bool `long:"keep-spec-order" description:"Keep schema properties order identical to spec file"`
|
||||
StrictAdditionalProperties bool `long:"strict-additional-properties" description:"disallow extra properties when additionalProperties is set to false"`
|
||||
}
|
||||
|
||||
func (s *Server) getOpts() (*generator.GenOpts, error) {
|
||||
// warning: deprecation
|
||||
if s.WithContext {
|
||||
log.Printf("warning: deprecated option --with-context is ignored")
|
||||
}
|
||||
|
||||
return &generator.GenOpts{
|
||||
Spec: string(s.Spec),
|
||||
Target: string(s.Target),
|
||||
APIPackage: s.APIPackage,
|
||||
ModelPackage: s.ModelPackage,
|
||||
ServerPackage: s.ServerPackage,
|
||||
ClientPackage: s.ClientPackage,
|
||||
Principal: s.Principal,
|
||||
DefaultScheme: s.DefaultScheme,
|
||||
IncludeModel: !s.SkipModels,
|
||||
IncludeValidator: !s.SkipModels,
|
||||
IncludeHandler: !s.SkipOperations,
|
||||
IncludeParameters: !s.SkipOperations,
|
||||
IncludeResponses: !s.SkipOperations,
|
||||
IncludeURLBuilder: !s.SkipOperations,
|
||||
IncludeMain: !s.ExcludeMain,
|
||||
IncludeSupport: !s.SkipSupport,
|
||||
PropertiesSpecOrder: s.KeepSpecOrder,
|
||||
ValidateSpec: !s.SkipValidation,
|
||||
ExcludeSpec: s.ExcludeSpec,
|
||||
StrictAdditionalProperties: s.StrictAdditionalProperties,
|
||||
Template: s.Template,
|
||||
RegenerateConfigureAPI: s.RegenerateConfigureAPI,
|
||||
TemplateDir: string(s.TemplateDir),
|
||||
DumpData: s.DumpData,
|
||||
Models: s.Models,
|
||||
Operations: s.Operations,
|
||||
Tags: s.Tags,
|
||||
Name: s.Name,
|
||||
FlagStrategy: s.FlagStrategy,
|
||||
CompatibilityMode: s.CompatibilityMode,
|
||||
ExistingModels: s.ExistingModels,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) getShared() *shared {
|
||||
return &s.shared
|
||||
}
|
||||
|
||||
func (s *Server) generate(opts *generator.GenOpts) error {
|
||||
return generator.GenerateServer(s.Name, s.Models, s.Operations, opts)
|
||||
}
|
||||
|
||||
func (s *Server) log(rp string) {
|
||||
var flagsPackage string
|
||||
if strings.HasPrefix(s.FlagStrategy, "pflag") {
|
||||
flagsPackage = "github.com/spf13/pflag"
|
||||
} else {
|
||||
flagsPackage = "github.com/jessevdk/go-flags"
|
||||
}
|
||||
|
||||
log.Printf(`Generation completed!
|
||||
|
||||
For this generation to compile you need to have some packages in your GOPATH:
|
||||
|
||||
* github.com/go-openapi/runtime
|
||||
* `+flagsPackage+`
|
||||
|
||||
You can get these now with: go get -u -f %s/...
|
||||
`, rp)
|
||||
}
|
||||
|
||||
// Execute runs this command
|
||||
func (s *Server) Execute(args []string) error {
|
||||
return createSwagger(s)
|
||||
}
|
213
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go
generated
vendored
Normal file
213
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go
generated
vendored
Normal file
@ -0,0 +1,213 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/go-openapi/analysis"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-swagger/go-swagger/generator"
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// FlattenCmdOptions determines options to the flatten spec preprocessing
|
||||
type FlattenCmdOptions struct {
|
||||
WithExpand bool `long:"with-expand" description:"expands all $ref's in spec prior to generation (shorthand to --with-flatten=expand)"`
|
||||
WithFlatten []string `long:"with-flatten" description:"flattens all $ref's in spec prior to generation" choice:"minimal" choice:"full" choice:"expand" choice:"verbose" choice:"noverbose" choice:"remove-unused" default:"minimal" default:"verbose"`
|
||||
}
|
||||
|
||||
// SetFlattenOptions builds flatten options from command line args
|
||||
func (f *FlattenCmdOptions) SetFlattenOptions(dflt *analysis.FlattenOpts) (res *analysis.FlattenOpts) {
|
||||
res = &analysis.FlattenOpts{}
|
||||
if dflt != nil {
|
||||
*res = *dflt
|
||||
}
|
||||
if f == nil {
|
||||
return
|
||||
}
|
||||
verboseIsSet := false
|
||||
minimalIsSet := false
|
||||
//removeUnusedIsSet := false
|
||||
expandIsSet := false
|
||||
if f.WithExpand {
|
||||
res.Expand = true
|
||||
expandIsSet = true
|
||||
}
|
||||
for _, opt := range f.WithFlatten {
|
||||
if opt == "verbose" {
|
||||
res.Verbose = true
|
||||
verboseIsSet = true
|
||||
}
|
||||
if opt == "noverbose" && !verboseIsSet {
|
||||
// verbose flag takes precedence
|
||||
res.Verbose = false
|
||||
verboseIsSet = true
|
||||
}
|
||||
if opt == "remove-unused" {
|
||||
res.RemoveUnused = true
|
||||
//removeUnusedIsSet = true
|
||||
}
|
||||
if opt == "expand" {
|
||||
res.Expand = true
|
||||
expandIsSet = true
|
||||
}
|
||||
if opt == "full" && !minimalIsSet && !expandIsSet {
|
||||
// minimal flag takes precedence
|
||||
res.Minimal = false
|
||||
minimalIsSet = true
|
||||
}
|
||||
if opt == "minimal" && !expandIsSet {
|
||||
// expand flag takes precedence
|
||||
res.Minimal = true
|
||||
minimalIsSet = true
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type shared struct {
|
||||
Spec flags.Filename `long:"spec" short:"f" description:"the spec file to use (default swagger.{json,yml,yaml})"`
|
||||
APIPackage string `long:"api-package" short:"a" description:"the package to save the operations" default:"operations"`
|
||||
ModelPackage string `long:"model-package" short:"m" description:"the package to save the models" default:"models"`
|
||||
ServerPackage string `long:"server-package" short:"s" description:"the package to save the server specific code" default:"restapi"`
|
||||
ClientPackage string `long:"client-package" short:"c" description:"the package to save the client specific code" default:"client"`
|
||||
Target flags.Filename `long:"target" short:"t" default:"./" description:"the base directory for generating the files"`
|
||||
Template string `long:"template" description:"Load contributed templates" choice:"stratoscale"`
|
||||
TemplateDir flags.Filename `long:"template-dir" short:"T" description:"alternative template override directory"`
|
||||
ConfigFile flags.Filename `long:"config-file" short:"C" description:"configuration file to use for overriding template options"`
|
||||
CopyrightFile flags.Filename `long:"copyright-file" short:"r" description:"copyright file used to add copyright header"`
|
||||
ExistingModels string `long:"existing-models" description:"use pre-generated models e.g. github.com/foobar/model"`
|
||||
AdditionalInitialisms []string `long:"additional-initialism" description:"consecutive capitals that should be considered intialisms"`
|
||||
FlattenCmdOptions
|
||||
}
|
||||
|
||||
type sharedCommand interface {
|
||||
getOpts() (*generator.GenOpts, error)
|
||||
getShared() *shared
|
||||
getConfigFile() flags.Filename
|
||||
getAdditionalInitialisms() []string
|
||||
generate(*generator.GenOpts) error
|
||||
log(string)
|
||||
}
|
||||
|
||||
func (s *shared) getConfigFile() flags.Filename {
|
||||
return s.ConfigFile
|
||||
}
|
||||
|
||||
func (s *shared) getAdditionalInitialisms() []string {
|
||||
return s.AdditionalInitialisms
|
||||
}
|
||||
|
||||
func (s *shared) setCopyright() (string, error) {
|
||||
var copyrightstr string
|
||||
copyrightfile := string(s.CopyrightFile)
|
||||
if copyrightfile != "" {
|
||||
//Read the Copyright from file path in opts
|
||||
bytebuffer, err := ioutil.ReadFile(copyrightfile)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
copyrightstr = string(bytebuffer)
|
||||
} else {
|
||||
copyrightstr = ""
|
||||
}
|
||||
return copyrightstr, nil
|
||||
}
|
||||
|
||||
func createSwagger(s sharedCommand) error {
|
||||
cfg, erc := readConfig(string(s.getConfigFile()))
|
||||
if erc != nil {
|
||||
return erc
|
||||
}
|
||||
setDebug(cfg)
|
||||
|
||||
opts, ero := s.getOpts()
|
||||
if ero != nil {
|
||||
return ero
|
||||
}
|
||||
|
||||
if opts.Template != "" {
|
||||
contribOptionsOverride(opts)
|
||||
}
|
||||
|
||||
if err := opts.EnsureDefaults(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := configureOptsFromConfig(cfg, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
swag.AddInitialisms(s.getAdditionalInitialisms()...)
|
||||
|
||||
if sharedOpts := s.getShared(); sharedOpts != nil {
|
||||
// process shared options
|
||||
opts.FlattenOpts = sharedOpts.FlattenCmdOptions.SetFlattenOptions(opts.FlattenOpts)
|
||||
|
||||
copyrightStr, erc := sharedOpts.setCopyright()
|
||||
if erc != nil {
|
||||
return erc
|
||||
}
|
||||
opts.Copyright = copyrightStr
|
||||
}
|
||||
|
||||
if err := s.generate(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
basepath, era := filepath.Abs(".")
|
||||
if era != nil {
|
||||
return era
|
||||
}
|
||||
|
||||
targetAbs, err := filepath.Abs(opts.Target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rp, err := filepath.Rel(basepath, targetAbs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.log(rp)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readConfig(filename string) (*viper.Viper, error) {
|
||||
if filename == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
abspath, err := filepath.Abs(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Println("trying to read config from", abspath)
|
||||
return generator.ReadConfig(abspath)
|
||||
}
|
||||
|
||||
func configureOptsFromConfig(cfg *viper.Viper, opts *generator.GenOpts) error {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var def generator.LanguageDefinition
|
||||
if err := cfg.Unmarshal(&def); err != nil {
|
||||
return err
|
||||
}
|
||||
return def.ConfigureOpts(opts)
|
||||
}
|
||||
|
||||
func setDebug(cfg *viper.Viper) {
|
||||
if os.Getenv("DEBUG") != "" || os.Getenv("SWAGGER_DEBUG") != "" {
|
||||
if cfg != nil {
|
||||
cfg.Debug()
|
||||
} else {
|
||||
log.Println("NO config read")
|
||||
}
|
||||
}
|
||||
}
|
125
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/spec.go
generated
vendored
Normal file
125
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/spec.go
generated
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
//+build !go1.11
|
||||
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package generate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-swagger/go-swagger/scan"
|
||||
"github.com/jessevdk/go-flags"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// SpecFile command to generate a swagger spec from a go application
|
||||
type SpecFile struct {
|
||||
BasePath string `long:"base-path" short:"b" description:"the base path to use" default:"."`
|
||||
BuildTags string `long:"tags" short:"t" description:"build tags" default:""`
|
||||
ScanModels bool `long:"scan-models" short:"m" description:"includes models that were annotated with 'swagger:model'"`
|
||||
Compact bool `long:"compact" description:"when present, doesn't prettify the json"`
|
||||
Output flags.Filename `long:"output" short:"o" description:"the file to write to"`
|
||||
Input flags.Filename `long:"input" short:"i" description:"the file to use as input"`
|
||||
Include []string `long:"include" short:"c" description:"include packages matching pattern"`
|
||||
Exclude []string `long:"exclude" short:"x" description:"exclude packages matching pattern"`
|
||||
IncludeTags []string `long:"include-tag" short:"" description:"include routes having specified tags (can be specified many times)"`
|
||||
ExcludeTags []string `long:"exclude-tag" short:"" description:"exclude routes having specified tags (can be specified many times)"`
|
||||
}
|
||||
|
||||
// Execute runs this command
|
||||
func (s *SpecFile) Execute(args []string) error {
|
||||
input, err := loadSpec(string(s.Input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var opts scan.Opts
|
||||
opts.BasePath = s.BasePath
|
||||
opts.Input = input
|
||||
opts.ScanModels = s.ScanModels
|
||||
opts.BuildTags = s.BuildTags
|
||||
opts.Include = s.Include
|
||||
opts.Exclude = s.Exclude
|
||||
opts.IncludeTags = s.IncludeTags
|
||||
opts.ExcludeTags = s.ExcludeTags
|
||||
swspec, err := scan.Application(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeToFile(swspec, !s.Compact, string(s.Output))
|
||||
}
|
||||
|
||||
func loadSpec(input string) (*spec.Swagger, error) {
|
||||
if fi, err := os.Stat(input); err == nil {
|
||||
if fi.IsDir() {
|
||||
return nil, fmt.Errorf("expected %q to be a file not a directory", input)
|
||||
}
|
||||
sp, err := loads.Spec(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sp.Spec(), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func writeToFile(swspec *spec.Swagger, pretty bool, output string) error {
|
||||
var b []byte
|
||||
var err error
|
||||
|
||||
if strings.HasSuffix(output, "yml") || strings.HasSuffix(output, "yaml") {
|
||||
b, err = marshalToYAMLFormat(swspec)
|
||||
} else {
|
||||
b, err = marshalToJSONFormat(swspec, pretty)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if output == "" {
|
||||
fmt.Println(string(b))
|
||||
return nil
|
||||
}
|
||||
return ioutil.WriteFile(output, b, 0644)
|
||||
}
|
||||
|
||||
func marshalToJSONFormat(swspec *spec.Swagger, pretty bool) ([]byte, error) {
|
||||
if pretty {
|
||||
return json.MarshalIndent(swspec, "", " ")
|
||||
}
|
||||
return json.Marshal(swspec)
|
||||
}
|
||||
|
||||
func marshalToYAMLFormat(swspec *spec.Swagger) ([]byte, error) {
|
||||
b, err := json.Marshal(swspec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var jsonObj interface{}
|
||||
if err := yaml.Unmarshal(b, &jsonObj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return yaml.Marshal(jsonObj)
|
||||
}
|
119
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/spec_go111.go
generated
vendored
Normal file
119
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/spec_go111.go
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
// +build go1.11
|
||||
|
||||
package generate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-swagger/go-swagger/codescan"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/jessevdk/go-flags"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// SpecFile command to generate a swagger spec from a go application
|
||||
type SpecFile struct {
|
||||
WorkDir string `long:"work-dir" short:"w" description:"the base path to use" default:"."`
|
||||
BuildTags string `long:"tags" short:"t" description:"build tags" default:""`
|
||||
ScanModels bool `long:"scan-models" short:"m" description:"includes models that were annotated with 'swagger:model'"`
|
||||
Compact bool `long:"compact" description:"when present, doesn't prettify the json"`
|
||||
Output flags.Filename `long:"output" short:"o" description:"the file to write to"`
|
||||
Input flags.Filename `long:"input" short:"i" description:"the file to use as input"`
|
||||
Include []string `long:"include" short:"c" description:"include packages matching pattern"`
|
||||
Exclude []string `long:"exclude" short:"x" description:"exclude packages matching pattern"`
|
||||
IncludeTags []string `long:"include-tag" short:"" description:"include routes having specified tags (can be specified many times)"`
|
||||
ExcludeTags []string `long:"exclude-tag" short:"" description:"exclude routes having specified tags (can be specified many times)"`
|
||||
ExcludeDeps bool `long:"exclude-deps" short:"" description:"exclude all dependencies of project"`
|
||||
}
|
||||
|
||||
// Execute runs this command
|
||||
func (s *SpecFile) Execute(args []string) error {
|
||||
if len(args) == 0 { // by default consider all the paths under the working directory
|
||||
args = []string{"./..."}
|
||||
}
|
||||
|
||||
input, err := loadSpec(string(s.Input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var opts codescan.Options
|
||||
opts.Packages = args
|
||||
opts.WorkDir = s.WorkDir
|
||||
opts.InputSpec = input
|
||||
opts.ScanModels = s.ScanModels
|
||||
opts.BuildTags = s.BuildTags
|
||||
opts.Include = s.Include
|
||||
opts.Exclude = s.Exclude
|
||||
opts.IncludeTags = s.IncludeTags
|
||||
opts.ExcludeTags = s.ExcludeTags
|
||||
opts.ExcludeDeps = s.ExcludeDeps
|
||||
swspec, err := codescan.Run(&opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeToFile(swspec, !s.Compact, string(s.Output))
|
||||
}
|
||||
|
||||
func loadSpec(input string) (*spec.Swagger, error) {
|
||||
if fi, err := os.Stat(input); err == nil {
|
||||
if fi.IsDir() {
|
||||
return nil, fmt.Errorf("expected %q to be a file not a directory", input)
|
||||
}
|
||||
sp, err := loads.Spec(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sp.Spec(), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func writeToFile(swspec *spec.Swagger, pretty bool, output string) error {
|
||||
var b []byte
|
||||
var err error
|
||||
|
||||
if strings.HasSuffix(output, "yml") || strings.HasSuffix(output, "yaml") {
|
||||
b, err = marshalToYAMLFormat(swspec)
|
||||
} else {
|
||||
b, err = marshalToJSONFormat(swspec, pretty)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if output == "" {
|
||||
fmt.Println(string(b))
|
||||
return nil
|
||||
}
|
||||
return ioutil.WriteFile(output, b, 0644)
|
||||
}
|
||||
|
||||
func marshalToJSONFormat(swspec *spec.Swagger, pretty bool) ([]byte, error) {
|
||||
if pretty {
|
||||
return json.MarshalIndent(swspec, "", " ")
|
||||
}
|
||||
return json.Marshal(swspec)
|
||||
}
|
||||
|
||||
func marshalToYAMLFormat(swspec *spec.Swagger) ([]byte, error) {
|
||||
b, err := json.Marshal(swspec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var jsonObj interface{}
|
||||
if err := yaml.Unmarshal(b, &jsonObj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return yaml.Marshal(jsonObj)
|
||||
}
|
76
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/support.go
generated
vendored
Normal file
76
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/support.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package generate
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/go-swagger/go-swagger/generator"
|
||||
)
|
||||
|
||||
// Support generates the supporting files
|
||||
type Support struct {
|
||||
shared
|
||||
Name string `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"`
|
||||
Operations []string `long:"operation" short:"O" description:"specify an operation to include, repeat for multiple"`
|
||||
Principal string `long:"principal" description:"the model to use for the security principal"`
|
||||
Models []string `long:"model" short:"M" description:"specify a model to include, repeat for multiple"`
|
||||
DumpData bool `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
|
||||
DefaultScheme string `long:"default-scheme" description:"the default scheme for this API" default:"http"`
|
||||
}
|
||||
|
||||
func (s *Support) getOpts() (*generator.GenOpts, error) {
|
||||
return &generator.GenOpts{
|
||||
Spec: string(s.Spec),
|
||||
Target: string(s.Target),
|
||||
APIPackage: s.APIPackage,
|
||||
ModelPackage: s.ModelPackage,
|
||||
ServerPackage: s.ServerPackage,
|
||||
ClientPackage: s.ClientPackage,
|
||||
Principal: s.Principal,
|
||||
DumpData: s.DumpData,
|
||||
DefaultScheme: s.DefaultScheme,
|
||||
Template: s.Template,
|
||||
TemplateDir: string(s.TemplateDir),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Support) getShared() *shared {
|
||||
return &s.shared
|
||||
}
|
||||
|
||||
func (s *Support) generate(opts *generator.GenOpts) error {
|
||||
return generator.GenerateSupport(s.Name, nil, nil, opts)
|
||||
}
|
||||
|
||||
func (s *Support) log(rp string) {
|
||||
|
||||
log.Printf(`Generation completed!
|
||||
|
||||
For this generation to compile you need to have some packages in your vendor or GOPATH:
|
||||
|
||||
* github.com/go-openapi/runtime
|
||||
* github.com/asaskevich/govalidator
|
||||
* github.com/jessevdk/go-flags
|
||||
* golang.org/x/net/context/ctxhttp
|
||||
|
||||
You can get these now with: go get -u -f %s/...
|
||||
`, rp)
|
||||
}
|
||||
|
||||
// Execute generates the supporting files file
|
||||
func (s *Support) Execute(args []string) error {
|
||||
return createSwagger(s)
|
||||
}
|
13
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd.go
generated
vendored
Normal file
13
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package commands
|
||||
|
||||
import "github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd"
|
||||
|
||||
// InitCmd is a command namespace for initializing things like a swagger spec.
|
||||
type InitCmd struct {
|
||||
Model *initcmd.Spec `command:"spec"`
|
||||
}
|
||||
|
||||
// Execute provides default empty implementation
|
||||
func (i *InitCmd) Execute(args []string) error {
|
||||
return nil
|
||||
}
|
111
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd/spec.go
generated
vendored
Normal file
111
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd/spec.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
package initcmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// Spec a command struct for initializing a new swagger application.
|
||||
type Spec struct {
|
||||
Format string `long:"format" description:"the format for the spec document" default:"yaml" choice:"yaml" choice:"json"`
|
||||
Title string `long:"title" description:"the title of the API"`
|
||||
Description string `long:"description" description:"the description of the API"`
|
||||
Version string `long:"version" description:"the version of the API" default:"0.1.0"`
|
||||
Terms string `long:"terms" description:"the terms of services"`
|
||||
Consumes []string `long:"consumes" description:"add a content type to the global consumes definitions, can repeat" default:"application/json"`
|
||||
Produces []string `long:"produces" description:"add a content type to the global produces definitions, can repeat" default:"application/json"`
|
||||
Schemes []string `long:"scheme" description:"add a scheme to the global schemes definition, can repeat" default:"http"`
|
||||
Contact struct {
|
||||
Name string `long:"contact.name" description:"name of the primary contact for the API"`
|
||||
URL string `long:"contact.url" description:"url of the primary contact for the API"`
|
||||
Email string `long:"contact.email" description:"email of the primary contact for the API"`
|
||||
}
|
||||
License struct {
|
||||
Name string `long:"license.name" description:"name of the license for the API"`
|
||||
URL string `long:"license.url" description:"url of the license for the API"`
|
||||
}
|
||||
}
|
||||
|
||||
// Execute this command
|
||||
func (s *Spec) Execute(args []string) error {
|
||||
targetPath := "."
|
||||
if len(args) > 0 {
|
||||
targetPath = args[0]
|
||||
}
|
||||
realPath, err := filepath.Abs(targetPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var file *os.File
|
||||
switch s.Format {
|
||||
case "json":
|
||||
file, err = os.Create(filepath.Join(realPath, "swagger.json"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "yaml", "yml":
|
||||
file, err = os.Create(filepath.Join(realPath, "swagger.yml"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid format: %s", s.Format)
|
||||
}
|
||||
defer file.Close()
|
||||
log.Println("creating specification document in", filepath.Join(targetPath, file.Name()))
|
||||
|
||||
var doc spec.Swagger
|
||||
info := new(spec.Info)
|
||||
doc.Info = info
|
||||
|
||||
doc.Swagger = "2.0"
|
||||
doc.Paths = new(spec.Paths)
|
||||
doc.Definitions = make(spec.Definitions)
|
||||
|
||||
info.Title = s.Title
|
||||
if info.Title == "" {
|
||||
info.Title = swag.ToHumanNameTitle(filepath.Base(realPath))
|
||||
}
|
||||
info.Description = s.Description
|
||||
info.Version = s.Version
|
||||
info.TermsOfService = s.Terms
|
||||
if s.Contact.Name != "" || s.Contact.Email != "" || s.Contact.URL != "" {
|
||||
var contact spec.ContactInfo
|
||||
contact.Name = s.Contact.Name
|
||||
contact.Email = s.Contact.Email
|
||||
contact.URL = s.Contact.URL
|
||||
info.Contact = &contact
|
||||
}
|
||||
if s.License.Name != "" || s.License.URL != "" {
|
||||
var license spec.License
|
||||
license.Name = s.License.Name
|
||||
license.URL = s.License.URL
|
||||
info.License = &license
|
||||
}
|
||||
|
||||
doc.Consumes = append(doc.Consumes, s.Consumes...)
|
||||
doc.Produces = append(doc.Produces, s.Produces...)
|
||||
doc.Schemes = append(doc.Schemes, s.Schemes...)
|
||||
|
||||
if s.Format == "json" {
|
||||
enc := json.NewEncoder(file)
|
||||
return enc.Encode(doc)
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(swag.ToDynamicJSON(doc))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := file.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
103
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go
generated
vendored
Normal file
103
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/go-openapi/analysis"
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-openapi/spec"
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
)
|
||||
|
||||
const (
|
||||
// Output messages
|
||||
nothingToDo = "Nothing to do. Need some swagger files to merge.\nUSAGE: swagger mixin [-c <expected#Collisions>] <primary-swagger-file> <mixin-swagger-file>..."
|
||||
)
|
||||
|
||||
// MixinSpec holds command line flag definitions specific to the mixin
|
||||
// command. The flags are defined using struct field tags with the
|
||||
// "github.com/jessevdk/go-flags" format.
|
||||
type MixinSpec struct {
|
||||
ExpectedCollisionCount uint `short:"c" description:"expected # of rejected mixin paths, defs, etc due to existing key. Non-zero exit if does not match actual."`
|
||||
Compact bool `long:"compact" description:"applies to JSON formatted specs. When present, doesn't prettify the json"`
|
||||
Output flags.Filename `long:"output" short:"o" description:"the file to write to"`
|
||||
Format string `long:"format" description:"the format for the spec document" default:"json" choice:"yaml" choice:"json"`
|
||||
}
|
||||
|
||||
// Execute runs the mixin command which merges Swagger 2.0 specs into
|
||||
// one spec
|
||||
//
|
||||
// Use cases include adding independently versioned metadata APIs to
|
||||
// application APIs for microservices.
|
||||
//
|
||||
// Typically, multiple APIs to the same service instance is not a
|
||||
// problem for client generation as you can create more than one
|
||||
// client to the service from the same calling process (one for each
|
||||
// API). However, merging clients can improve clarity of client code
|
||||
// by having a single client to given service vs several.
|
||||
//
|
||||
// Server skeleton generation, ie generating the model & marshaling
|
||||
// code, http server instance etc. from Swagger, becomes easier with a
|
||||
// merged spec for some tools & target-languages. Server code
|
||||
// generation tools that natively support hosting multiple specs in
|
||||
// one server process will not need this tool.
|
||||
func (c *MixinSpec) Execute(args []string) error {
|
||||
|
||||
if len(args) < 2 {
|
||||
return errors.New(nothingToDo)
|
||||
}
|
||||
|
||||
log.Printf("args[0] = %v\n", args[0])
|
||||
log.Printf("args[1:] = %v\n", args[1:])
|
||||
collisions, err := c.MixinFiles(args[0], args[1:], os.Stdout)
|
||||
|
||||
for _, warn := range collisions {
|
||||
log.Println(warn)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(collisions) != int(c.ExpectedCollisionCount) {
|
||||
if len(collisions) != 0 {
|
||||
// use bash $? to get actual # collisions
|
||||
// (but has to be non-zero)
|
||||
os.Exit(len(collisions))
|
||||
}
|
||||
os.Exit(254)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MixinFiles is a convenience function for Mixin that reads the given
|
||||
// swagger files, adds the mixins to primary, calls
|
||||
// FixEmptyResponseDescriptions on the primary, and writes the primary
|
||||
// with mixins to the given writer in JSON. Returns the warning
|
||||
// messages for collisions that occurred during mixin process and any
|
||||
// error.
|
||||
func (c *MixinSpec) MixinFiles(primaryFile string, mixinFiles []string, w io.Writer) ([]string, error) {
|
||||
|
||||
primaryDoc, err := loads.Spec(primaryFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
primary := primaryDoc.Spec()
|
||||
|
||||
var mixins []*spec.Swagger
|
||||
for _, mixinFile := range mixinFiles {
|
||||
mixin, lerr := loads.Spec(mixinFile)
|
||||
if lerr != nil {
|
||||
return nil, lerr
|
||||
}
|
||||
mixins = append(mixins, mixin.Spec())
|
||||
}
|
||||
|
||||
collisions := analysis.Mixin(primary, mixins...)
|
||||
analysis.FixEmptyResponseDescriptions(primary)
|
||||
|
||||
return collisions, writeToFile(primary, !c.Compact, c.Format, string(c.Output))
|
||||
}
|
107
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go
generated
vendored
Normal file
107
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/toqueteos/webbrowser"
|
||||
)
|
||||
|
||||
// ServeCmd to serve a swagger spec with docs ui
|
||||
type ServeCmd struct {
|
||||
BasePath string `long:"base-path" description:"the base path to serve the spec and UI at"`
|
||||
Flavor string `short:"F" long:"flavor" description:"the flavor of docs, can be swagger or redoc" default:"redoc" choice:"redoc" choice:"swagger"`
|
||||
DocURL string `long:"doc-url" description:"override the url which takes a url query param to render the doc ui"`
|
||||
NoOpen bool `long:"no-open" description:"when present won't open the the browser to show the url"`
|
||||
NoUI bool `long:"no-ui" description:"when present, only the swagger spec will be served"`
|
||||
Port int `long:"port" short:"p" description:"the port to serve this site" env:"PORT"`
|
||||
Host string `long:"host" description:"the interface to serve this site, defaults to 0.0.0.0" env:"HOST"`
|
||||
}
|
||||
|
||||
// Execute the serve command
|
||||
func (s *ServeCmd) Execute(args []string) error {
|
||||
if len(args) == 0 {
|
||||
return errors.New("specify the spec to serve as argument to the serve command")
|
||||
}
|
||||
|
||||
specDoc, err := loads.Spec(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := json.MarshalIndent(specDoc.Spec(), "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
basePath := s.BasePath
|
||||
if basePath == "" {
|
||||
basePath = "/"
|
||||
}
|
||||
|
||||
listener, err := net.Listen("tcp4", net.JoinHostPort(s.Host, strconv.Itoa(s.Port)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sh, sp, err := swag.SplitHostPort(listener.Addr().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sh == "0.0.0.0" {
|
||||
sh = "localhost"
|
||||
}
|
||||
|
||||
visit := s.DocURL
|
||||
handler := http.NotFoundHandler()
|
||||
if !s.NoUI {
|
||||
if s.Flavor == "redoc" {
|
||||
handler = middleware.Redoc(middleware.RedocOpts{
|
||||
BasePath: basePath,
|
||||
SpecURL: path.Join(basePath, "swagger.json"),
|
||||
Path: "docs",
|
||||
}, handler)
|
||||
visit = fmt.Sprintf("http://%s:%d%s", sh, sp, path.Join(basePath, "docs"))
|
||||
} else if visit != "" || s.Flavor == "swagger" {
|
||||
if visit == "" {
|
||||
visit = "http://petstore.swagger.io/"
|
||||
}
|
||||
u, err := url.Parse(visit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
q := u.Query()
|
||||
q.Add("url", fmt.Sprintf("http://%s:%d%s", sh, sp, path.Join(basePath, "swagger.json")))
|
||||
u.RawQuery = q.Encode()
|
||||
visit = u.String()
|
||||
}
|
||||
}
|
||||
|
||||
handler = handlers.CORS()(middleware.Spec(basePath, b, handler))
|
||||
errFuture := make(chan error)
|
||||
go func() {
|
||||
docServer := new(http.Server)
|
||||
docServer.SetKeepAlivesEnabled(true)
|
||||
docServer.Handler = handler
|
||||
|
||||
errFuture <- docServer.Serve(listener)
|
||||
}()
|
||||
|
||||
if !s.NoOpen && !s.NoUI {
|
||||
err := webbrowser.Open(visit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
log.Println("serving docs at", visit)
|
||||
return <-errFuture
|
||||
}
|
83
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/validate.go
generated
vendored
Normal file
83
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/validate.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
const (
|
||||
// Output messages
|
||||
missingArgMsg = "The validate command requires the swagger document url to be specified"
|
||||
validSpecMsg = "\nThe swagger spec at %q is valid against swagger specification %s\n"
|
||||
invalidSpecMsg = "\nThe swagger spec at %q is invalid against swagger specification %s.\nSee errors below:\n"
|
||||
warningSpecMsg = "\nThe swagger spec at %q showed up some valid but possibly unwanted constructs."
|
||||
)
|
||||
|
||||
// ValidateSpec is a command that validates a swagger document
|
||||
// against the swagger specification
|
||||
type ValidateSpec struct {
|
||||
// SchemaURL string `long:"schema" description:"The schema url to use" default:"http://swagger.io/v2/schema.json"`
|
||||
SkipWarnings bool `long:"skip-warnings" description:"when present will not show up warnings upon validation"`
|
||||
StopOnError bool `long:"stop-on-error" description:"when present will not continue validation after critical errors are found"`
|
||||
}
|
||||
|
||||
// Execute validates the spec
|
||||
func (c *ValidateSpec) Execute(args []string) error {
|
||||
if len(args) == 0 {
|
||||
return errors.New(missingArgMsg)
|
||||
}
|
||||
|
||||
swaggerDoc := args[0]
|
||||
|
||||
specDoc, err := loads.Spec(swaggerDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Attempts to report about all errors
|
||||
validate.SetContinueOnErrors(!c.StopOnError)
|
||||
|
||||
v := validate.NewSpecValidator(specDoc.Schema(), strfmt.Default)
|
||||
result, _ := v.Validate(specDoc) // returns fully detailed result with errors and warnings
|
||||
|
||||
if result.IsValid() {
|
||||
log.Printf(validSpecMsg, swaggerDoc, specDoc.Version())
|
||||
}
|
||||
if result.HasWarnings() {
|
||||
log.Printf(warningSpecMsg, swaggerDoc)
|
||||
if !c.SkipWarnings {
|
||||
log.Printf("See warnings below:\n")
|
||||
for _, desc := range result.Warnings {
|
||||
log.Printf("- WARNING: %s\n", desc.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
if result.HasErrors() {
|
||||
str := fmt.Sprintf(invalidSpecMsg, swaggerDoc, specDoc.Version())
|
||||
for _, desc := range result.Errors {
|
||||
str += fmt.Sprintf("- %s\n", desc.Error())
|
||||
}
|
||||
return errors.New(str)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
26
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go
generated
vendored
Normal file
26
vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
package commands
|
||||
|
||||
import "fmt"
|
||||
|
||||
var (
|
||||
// Version for the swagger command
|
||||
Version string
|
||||
// Commit for the swagger command
|
||||
Commit string
|
||||
)
|
||||
|
||||
// PrintVersion the command
|
||||
type PrintVersion struct {
|
||||
}
|
||||
|
||||
// Execute this command
|
||||
func (p *PrintVersion) Execute(args []string) error {
|
||||
if Version == "" {
|
||||
fmt.Println("dev")
|
||||
return nil
|
||||
}
|
||||
fmt.Println("version:", Version)
|
||||
fmt.Println("commit:", Commit)
|
||||
|
||||
return nil
|
||||
}
|
148
vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go
generated
vendored
Normal file
148
vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go
generated
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/go-openapi/loads/fmts"
|
||||
"github.com/go-swagger/go-swagger/cmd/swagger/commands"
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
)
|
||||
|
||||
func init() {
|
||||
loads.AddLoader(fmts.YAMLMatcher, fmts.YAMLDoc)
|
||||
}
|
||||
|
||||
var (
|
||||
// Debug is true when the SWAGGER_DEBUG env var is not empty
|
||||
Debug = os.Getenv("SWAGGER_DEBUG") != ""
|
||||
)
|
||||
|
||||
var opts struct {
|
||||
// General options applicable to all commands
|
||||
Quiet func() `long:"quiet" short:"q" description:"silence logs"`
|
||||
LogFile func(string) `long:"log-output" description:"redirect logs to file" value-name:"LOG-FILE"`
|
||||
// Version bool `long:"version" short:"v" description:"print the version of the command"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
// TODO: reactivate 'defer catch all' once product is stable
|
||||
// Recovering from internal panics
|
||||
// Stack may be printed in Debug mode
|
||||
// Need import "runtime/debug".
|
||||
//defer func() {
|
||||
// r := recover()
|
||||
// if r != nil {
|
||||
// log.Printf("Fatal error:", r)
|
||||
// if Debug {
|
||||
// debug.PrintStack()
|
||||
// }
|
||||
// os.Exit(1)
|
||||
// }
|
||||
//}()
|
||||
|
||||
parser := flags.NewParser(&opts, flags.Default)
|
||||
parser.ShortDescription = "helps you keep your API well described"
|
||||
parser.LongDescription = `
|
||||
Swagger tries to support you as best as possible when building APIs.
|
||||
|
||||
It aims to represent the contract of your API with a language agnostic description of your application in json or yaml.
|
||||
`
|
||||
_, err := parser.AddCommand("validate", "validate the swagger document", "validate the provided swagger document against a swagger spec", &commands.ValidateSpec{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = parser.AddCommand("init", "initialize a spec document", "initialize a swagger spec document", &commands.InitCmd{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = parser.AddCommand("version", "print the version", "print the version of the swagger command", &commands.PrintVersion{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = parser.AddCommand("serve", "serve spec and docs", "serve a spec and swagger or redoc documentation ui", &commands.ServeCmd{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = parser.AddCommand("expand", "expand $ref fields in a swagger spec", "expands the $refs in a swagger document to inline schemas", &commands.ExpandSpec{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = parser.AddCommand("flatten", "flattens a swagger document", "expand the remote references in a spec and move inline schemas to definitions, after flattening there are no complex inlined anymore", &commands.FlattenSpec{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = parser.AddCommand("mixin", "merge swagger documents", "merge additional specs into first/primary spec by copying their paths and definitions", &commands.MixinSpec{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = parser.AddCommand("diff", "diff swagger documents", "diff specs showing which changes will break existing clients", &commands.DiffCommand{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
genpar, err := parser.AddCommand("generate", "generate go code", "generate go code for the swagger spec file", &commands.Generate{})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
for _, cmd := range genpar.Commands() {
|
||||
switch cmd.Name {
|
||||
case "spec":
|
||||
cmd.ShortDescription = "generate a swagger spec document from a go application"
|
||||
cmd.LongDescription = cmd.ShortDescription
|
||||
case "client":
|
||||
cmd.ShortDescription = "generate all the files for a client library"
|
||||
cmd.LongDescription = cmd.ShortDescription
|
||||
case "server":
|
||||
cmd.ShortDescription = "generate all the files for a server application"
|
||||
cmd.LongDescription = cmd.ShortDescription
|
||||
case "model":
|
||||
cmd.ShortDescription = "generate one or more models from the swagger spec"
|
||||
cmd.LongDescription = cmd.ShortDescription
|
||||
case "support":
|
||||
cmd.ShortDescription = "generate supporting files like the main function and the api builder"
|
||||
cmd.LongDescription = cmd.ShortDescription
|
||||
case "operation":
|
||||
cmd.ShortDescription = "generate one or more server operations from the swagger spec"
|
||||
cmd.LongDescription = cmd.ShortDescription
|
||||
}
|
||||
}
|
||||
|
||||
opts.Quiet = func() {
|
||||
log.SetOutput(ioutil.Discard)
|
||||
}
|
||||
opts.LogFile = func(logfile string) {
|
||||
f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
log.Fatalf("cannot write to file %s: %v", logfile, err)
|
||||
}
|
||||
log.SetOutput(f)
|
||||
}
|
||||
|
||||
if _, err := parser.Parse(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user