1 package analysis 2 3 import ( 4 "log" 5 6 "github.com/go-openapi/spec" 7 ) 8 9 // FlattenOpts configuration for flattening a swagger specification. 10 // 11 // The BasePath parameter is used to locate remote relative $ref found in the specification. 12 // This path is a file: it points to the location of the root document and may be either a local 13 // file path or a URL. 14 // 15 // If none specified, relative references (e.g. "$ref": "folder/schema.yaml#/definitions/...") 16 // found in the spec are searched from the current working directory. 17 type FlattenOpts struct { 18 Spec *Spec // The analyzed spec to work with 19 flattenContext *context // Internal context to track flattening activity 20 21 BasePath string // The location of the root document for this spec to resolve relative $ref 22 23 // Flattening options 24 Expand bool // When true, skip flattening the spec and expand it instead (if Minimal is false) 25 Minimal bool // When true, do not decompose complex structures such as allOf 26 Verbose bool // enable some reporting on possible name conflicts detected 27 RemoveUnused bool // When true, remove unused parameters, responses and definitions after expansion/flattening 28 ContinueOnError bool // Continue when spec expansion issues are found 29 KeepNames bool // Do not attempt to jsonify names from references when flattening 30 31 /* Extra keys */ 32 _ struct{} // require keys 33 } 34 35 // ExpandOpts creates a spec.ExpandOptions to configure expanding a specification document. 36 func (f *FlattenOpts) ExpandOpts(skipSchemas bool) *spec.ExpandOptions { 37 return &spec.ExpandOptions{ 38 RelativeBase: f.BasePath, 39 SkipSchemas: skipSchemas, 40 ContinueOnError: f.ContinueOnError, 41 } 42 } 43 44 // Swagger gets the swagger specification for this flatten operation 45 func (f *FlattenOpts) Swagger() *spec.Swagger { 46 return f.Spec.spec 47 } 48 49 // croak logs notifications and warnings about valid, but possibly unwanted constructs resulting 50 // from flattening a spec 51 func (f *FlattenOpts) croak() { 52 if !f.Verbose { 53 return 54 } 55 56 reported := make(map[string]bool, len(f.flattenContext.newRefs)) 57 for _, v := range f.Spec.references.allRefs { 58 // warns about duplicate handling 59 for _, r := range f.flattenContext.newRefs { 60 if r.isOAIGen && r.path == v.String() { 61 reported[r.newName] = true 62 } 63 } 64 } 65 66 for k := range reported { 67 log.Printf("warning: duplicate flattened definition name resolved as %s", k) 68 } 69 70 // warns about possible type mismatches 71 uniqueMsg := make(map[string]bool) 72 for _, msg := range f.flattenContext.warnings { 73 if _, ok := uniqueMsg[msg]; ok { 74 continue 75 } 76 log.Printf("warning: %s", msg) 77 uniqueMsg[msg] = true 78 } 79 } 80