github.com/mobiledgex/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  }