github.com/Percona-Lab/go-swagger@v0.19.0/generator/client.go (about)

     1  // Copyright 2015 go-swagger maintainers
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package generator
    16  
    17  import (
    18  	"encoding/json"
    19  	"errors"
    20  	"fmt"
    21  	"os"
    22  	"path"
    23  	"path/filepath"
    24  	"sort"
    25  
    26  	"github.com/go-openapi/analysis"
    27  	"github.com/go-openapi/runtime"
    28  	"github.com/go-openapi/swag"
    29  )
    30  
    31  // GenerateClient generates a client library for a swagger spec document.
    32  func GenerateClient(name string, modelNames, operationIDs []string, opts *GenOpts) error {
    33  	templates.LoadDefaults()
    34  	if opts == nil {
    35  		return errors.New("gen opts are required")
    36  	}
    37  
    38  	if opts.Template != "" {
    39  		if err := templates.LoadContrib(opts.Template); err != nil {
    40  			return err
    41  		}
    42  	}
    43  
    44  	if opts.TemplateDir != "" {
    45  		if err := templates.LoadDir(opts.TemplateDir); err != nil {
    46  			return err
    47  		}
    48  	}
    49  
    50  	if err := opts.CheckOpts(); err != nil {
    51  		return err
    52  	}
    53  
    54  	// Load the spec
    55  	_, specDoc, err := loadSpec(opts.Spec)
    56  	if err != nil {
    57  		return err
    58  	}
    59  
    60  	// Validate and Expand. specDoc is in/out param.
    61  	specDoc, err = validateAndFlattenSpec(opts, specDoc)
    62  	if err != nil {
    63  		return err
    64  	}
    65  
    66  	analyzed := analysis.New(specDoc.Spec())
    67  
    68  	models, err := gatherModels(specDoc, modelNames)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	operations := gatherOperations(analyzed, operationIDs)
    74  
    75  	if len(operations) == 0 {
    76  		return errors.New("no operations were selected")
    77  	}
    78  
    79  	defaultScheme := opts.DefaultScheme
    80  	if defaultScheme == "" {
    81  		defaultScheme = sHTTP
    82  	}
    83  
    84  	defaultConsumes := opts.DefaultConsumes
    85  	if defaultConsumes == "" {
    86  		defaultConsumes = runtime.JSONMime
    87  	}
    88  
    89  	defaultProduces := opts.DefaultProduces
    90  	if defaultProduces == "" {
    91  		defaultProduces = runtime.JSONMime
    92  	}
    93  
    94  	generator := appGenerator{
    95  		Name:              appNameOrDefault(specDoc, name, "rest"),
    96  		SpecDoc:           specDoc,
    97  		Analyzed:          analyzed,
    98  		Models:            models,
    99  		Operations:        operations,
   100  		Target:            opts.Target,
   101  		DumpData:          opts.DumpData,
   102  		Package:           opts.LanguageOpts.ManglePackageName(opts.ClientPackage, "client"),
   103  		APIPackage:        opts.LanguageOpts.ManglePackagePath(opts.APIPackage, "api"),
   104  		ModelsPackage:     opts.LanguageOpts.ManglePackagePath(opts.ModelPackage, "definitions"),
   105  		ServerPackage:     opts.LanguageOpts.ManglePackagePath(opts.ServerPackage, "server"),
   106  		ClientPackage:     opts.LanguageOpts.ManglePackagePath(opts.ClientPackage, "client"),
   107  		OperationsPackage: opts.LanguageOpts.ManglePackagePath(opts.ClientPackage, "client"),
   108  		Principal:         opts.Principal,
   109  		DefaultScheme:     defaultScheme,
   110  		DefaultProduces:   defaultProduces,
   111  		DefaultConsumes:   defaultConsumes,
   112  		GenOpts:           opts,
   113  	}
   114  	generator.Receiver = "o"
   115  	return (&clientGenerator{generator}).Generate()
   116  }
   117  
   118  type clientGenerator struct {
   119  	appGenerator
   120  }
   121  
   122  func (c *clientGenerator) Generate() error {
   123  	app, err := c.makeCodegenApp()
   124  	if app.Name == "" {
   125  		app.Name = "APIClient"
   126  	}
   127  	baseImport := c.GenOpts.LanguageOpts.baseImport(c.Target)
   128  
   129  	if c.GenOpts.ExistingModels == "" {
   130  		if app.Imports == nil {
   131  			app.Imports = make(map[string]string)
   132  		}
   133  		pkgAlias := c.GenOpts.LanguageOpts.ManglePackageName(c.ModelsPackage, "models")
   134  		app.Imports[pkgAlias] = path.Join(
   135  			filepath.ToSlash(baseImport),
   136  			c.GenOpts.LanguageOpts.ManglePackagePath(c.GenOpts.ModelPackage, "models"))
   137  	} else {
   138  		app.DefaultImports = append(app.DefaultImports, c.GenOpts.LanguageOpts.ManglePackagePath(c.GenOpts.ExistingModels, ""))
   139  	}
   140  	if err != nil {
   141  		return err
   142  	}
   143  
   144  	if c.DumpData {
   145  		bb, _ := json.MarshalIndent(swag.ToDynamicJSON(app), "", "  ")
   146  		fmt.Fprintln(os.Stdout, string(bb))
   147  		return nil
   148  	}
   149  
   150  	if c.GenOpts.IncludeModel {
   151  		for _, mod := range app.Models {
   152  			modCopy := mod
   153  			modCopy.IncludeValidator = true
   154  			if !mod.IsStream {
   155  				if err := c.GenOpts.renderDefinition(&modCopy); err != nil {
   156  					return err
   157  				}
   158  			}
   159  		}
   160  	}
   161  
   162  	if c.GenOpts.IncludeHandler {
   163  		sort.Sort(app.OperationGroups)
   164  		for i := range app.OperationGroups {
   165  			opGroup := app.OperationGroups[i]
   166  			opGroup.DefaultImports = app.DefaultImports
   167  			opGroup.RootPackage = c.ClientPackage
   168  			opGroup.GenOpts = c.GenOpts
   169  			app.OperationGroups[i] = opGroup
   170  			sort.Sort(opGroup.Operations)
   171  			for _, op := range opGroup.Operations {
   172  				opCopy := op
   173  				if opCopy.Package == "" {
   174  					opCopy.Package = c.Package
   175  				}
   176  				if err := c.GenOpts.renderOperation(&opCopy); err != nil {
   177  					return err
   178  				}
   179  			}
   180  			app.DefaultImports = append(app.DefaultImports,
   181  				path.Join(
   182  					filepath.ToSlash(baseImport),
   183  					c.GenOpts.LanguageOpts.ManglePackagePath(c.ClientPackage, "client"),
   184  					opGroup.Name))
   185  
   186  			if err := c.GenOpts.renderOperationGroup(&opGroup); err != nil {
   187  				return err
   188  			}
   189  		}
   190  	}
   191  
   192  	if c.GenOpts.IncludeSupport {
   193  		if err := c.GenOpts.renderApplication(&app); err != nil {
   194  			return err
   195  		}
   196  	}
   197  
   198  	return nil
   199  }