github.com/youyuanwu/go-swagger@v0.19.0/cmd/swagger/commands/generate/shared.go (about) 1 package generate 2 3 import ( 4 "io/ioutil" 5 "log" 6 "os" 7 "path/filepath" 8 9 "github.com/go-openapi/analysis" 10 "github.com/go-openapi/swag" 11 "github.com/go-swagger/go-swagger/generator" 12 flags "github.com/jessevdk/go-flags" 13 "github.com/spf13/viper" 14 ) 15 16 // FlattenCmdOptions determines options to the flatten spec preprocessing 17 type FlattenCmdOptions struct { 18 WithExpand bool `long:"with-expand" description:"expands all $ref's in spec prior to generation (shorthand to --with-flatten=expand)"` 19 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"` 20 } 21 22 // SetFlattenOptions builds flatten options from command line args 23 func (f *FlattenCmdOptions) SetFlattenOptions(dflt *analysis.FlattenOpts) (res *analysis.FlattenOpts) { 24 res = &analysis.FlattenOpts{} 25 if dflt != nil { 26 *res = *dflt 27 } 28 if f == nil { 29 return 30 } 31 verboseIsSet := false 32 minimalIsSet := false 33 //removeUnusedIsSet := false 34 expandIsSet := false 35 if f.WithExpand { 36 res.Expand = true 37 expandIsSet = true 38 } 39 for _, opt := range f.WithFlatten { 40 if opt == "verbose" { 41 res.Verbose = true 42 verboseIsSet = true 43 } 44 if opt == "noverbose" && !verboseIsSet { 45 // verbose flag takes precedence 46 res.Verbose = false 47 verboseIsSet = true 48 } 49 if opt == "remove-unused" { 50 res.RemoveUnused = true 51 //removeUnusedIsSet = true 52 } 53 if opt == "expand" { 54 res.Expand = true 55 expandIsSet = true 56 } 57 if opt == "full" && !minimalIsSet && !expandIsSet { 58 // minimal flag takes precedence 59 res.Minimal = false 60 minimalIsSet = true 61 } 62 if opt == "minimal" && !expandIsSet { 63 // expand flag takes precedence 64 res.Minimal = true 65 minimalIsSet = true 66 } 67 } 68 return 69 } 70 71 type shared struct { 72 Spec flags.Filename `long:"spec" short:"f" description:"the spec file to use (default swagger.{json,yml,yaml})"` 73 APIPackage string `long:"api-package" short:"a" description:"the package to save the operations" default:"operations"` 74 ModelPackage string `long:"model-package" short:"m" description:"the package to save the models" default:"models"` 75 ServerPackage string `long:"server-package" short:"s" description:"the package to save the server specific code" default:"restapi"` 76 ClientPackage string `long:"client-package" short:"c" description:"the package to save the client specific code" default:"client"` 77 Target flags.Filename `long:"target" short:"t" default:"./" description:"the base directory for generating the files"` 78 Template string `long:"template" description:"Load contributed templates" choice:"stratoscale"` 79 TemplateDir flags.Filename `long:"template-dir" short:"T" description:"alternative template override directory"` 80 ConfigFile flags.Filename `long:"config-file" short:"C" description:"configuration file to use for overriding template options"` 81 CopyrightFile flags.Filename `long:"copyright-file" short:"r" description:"copyright file used to add copyright header"` 82 ExistingModels string `long:"existing-models" description:"use pre-generated models e.g. github.com/foobar/model"` 83 AdditionalInitialisms []string `long:"additional-initialism" description:"consecutive capitals that should be considered intialisms"` 84 FlattenCmdOptions 85 } 86 87 type sharedCommand interface { 88 getOpts() (*generator.GenOpts, error) 89 getShared() *shared 90 getConfigFile() flags.Filename 91 getAdditionalInitialisms() []string 92 generate(*generator.GenOpts) error 93 log(string) 94 } 95 96 func (s *shared) getConfigFile() flags.Filename { 97 return s.ConfigFile 98 } 99 100 func (s *shared) getAdditionalInitialisms() []string { 101 return s.AdditionalInitialisms 102 } 103 104 func (s *shared) setCopyright() (string, error) { 105 var copyrightstr string 106 copyrightfile := string(s.CopyrightFile) 107 if copyrightfile != "" { 108 //Read the Copyright from file path in opts 109 bytebuffer, err := ioutil.ReadFile(copyrightfile) 110 if err != nil { 111 return "", err 112 } 113 copyrightstr = string(bytebuffer) 114 } else { 115 copyrightstr = "" 116 } 117 return copyrightstr, nil 118 } 119 120 func createSwagger(s sharedCommand) error { 121 cfg, erc := readConfig(string(s.getConfigFile())) 122 if erc != nil { 123 return erc 124 } 125 setDebug(cfg) 126 127 opts, ero := s.getOpts() 128 if ero != nil { 129 return ero 130 } 131 132 if opts.Template != "" { 133 contribOptionsOverride(opts) 134 } 135 136 if err := opts.EnsureDefaults(); err != nil { 137 return err 138 } 139 140 if err := configureOptsFromConfig(cfg, opts); err != nil { 141 return err 142 } 143 144 swag.AddInitialisms(s.getAdditionalInitialisms()...) 145 146 if sharedOpts := s.getShared(); sharedOpts != nil { 147 // process shared options 148 opts.FlattenOpts = sharedOpts.FlattenCmdOptions.SetFlattenOptions(opts.FlattenOpts) 149 150 copyrightStr, erc := sharedOpts.setCopyright() 151 if erc != nil { 152 return erc 153 } 154 opts.Copyright = copyrightStr 155 } 156 157 if err := s.generate(opts); err != nil { 158 return err 159 } 160 161 basepath, era := filepath.Abs(".") 162 if era != nil { 163 return era 164 } 165 166 targetAbs, err := filepath.Abs(opts.Target) 167 if err != nil { 168 return err 169 } 170 rp, err := filepath.Rel(basepath, targetAbs) 171 if err != nil { 172 return err 173 } 174 175 s.log(rp) 176 177 return nil 178 } 179 180 func readConfig(filename string) (*viper.Viper, error) { 181 if filename == "" { 182 return nil, nil 183 } 184 185 abspath, err := filepath.Abs(filename) 186 if err != nil { 187 return nil, err 188 } 189 log.Println("trying to read config from", abspath) 190 return generator.ReadConfig(abspath) 191 } 192 193 func configureOptsFromConfig(cfg *viper.Viper, opts *generator.GenOpts) error { 194 if cfg == nil { 195 return nil 196 } 197 198 var def generator.LanguageDefinition 199 if err := cfg.Unmarshal(&def); err != nil { 200 return err 201 } 202 return def.ConfigureOpts(opts) 203 } 204 205 func setDebug(cfg *viper.Viper) { 206 if os.Getenv("DEBUG") != "" || os.Getenv("SWAGGER_DEBUG") != "" { 207 if cfg != nil { 208 cfg.Debug() 209 } else { 210 log.Println("NO config read") 211 } 212 } 213 }