github.com/ManabuSeki/goa-v1@v1.4.3/goagen/gen_swagger/generator.go (about)

     1  package genswagger
     2  
     3  import (
     4  	"encoding/json"
     5  	"flag"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	yaml "gopkg.in/yaml.v2"
    12  
    13  	"github.com/goadesign/goa/design"
    14  	"github.com/goadesign/goa/goagen/codegen"
    15  	"github.com/goadesign/goa/goagen/utils"
    16  )
    17  
    18  //NewGenerator returns an initialized instance of a JavaScript Client Generator
    19  func NewGenerator(options ...Option) *Generator {
    20  	g := &Generator{}
    21  
    22  	for _, option := range options {
    23  		option(g)
    24  	}
    25  
    26  	return g
    27  }
    28  
    29  // Generator is the swagger code generator.
    30  type Generator struct {
    31  	API      *design.APIDefinition // The API definition
    32  	OutDir   string                // Path to output directory
    33  	genfiles []string              // Generated files
    34  }
    35  
    36  // Generate is the generator entry point called by the meta generator.
    37  func Generate() (files []string, err error) {
    38  	var (
    39  		outDir, toolDir, target, ver string
    40  		notool, regen                bool
    41  	)
    42  
    43  	set := flag.NewFlagSet("swagger", flag.PanicOnError)
    44  	set.StringVar(&outDir, "out", "", "")
    45  	set.StringVar(&ver, "version", "", "")
    46  	set.String("design", "", "")
    47  	set.StringVar(&toolDir, "tooldir", "tool", "")
    48  	set.BoolVar(&notool, "notool", false, "")
    49  	set.StringVar(&target, "pkg", "app", "")
    50  	set.BoolVar(&regen, "regen", false, "")
    51  	set.Bool("force", false, "")
    52  	set.Bool("notest", false, "")
    53  	set.Parse(os.Args[1:])
    54  
    55  	if err := codegen.CheckVersion(ver); err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	g := &Generator{OutDir: outDir, API: design.Design}
    60  
    61  	return g.Generate()
    62  }
    63  
    64  // Generate produces the skeleton main.
    65  func (g *Generator) Generate() (_ []string, err error) {
    66  	if g.API == nil {
    67  		return nil, fmt.Errorf("missing API definition, make sure design is properly initialized")
    68  	}
    69  
    70  	go utils.Catch(nil, func() { g.Cleanup() })
    71  
    72  	defer func() {
    73  		if err != nil {
    74  			g.Cleanup()
    75  		}
    76  	}()
    77  
    78  	s, err := New(g.API)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	swaggerDir := filepath.Join(g.OutDir, "swagger")
    84  	os.RemoveAll(swaggerDir)
    85  	if err = os.MkdirAll(swaggerDir, 0755); err != nil {
    86  		return nil, err
    87  	}
    88  	g.genfiles = append(g.genfiles, swaggerDir)
    89  
    90  	// JSON
    91  	rawJSON, err := json.Marshal(s)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  	swaggerFile := filepath.Join(swaggerDir, "swagger.json")
    96  	if err := ioutil.WriteFile(swaggerFile, rawJSON, 0644); err != nil {
    97  		return nil, err
    98  	}
    99  	g.genfiles = append(g.genfiles, swaggerFile)
   100  
   101  	// YAML
   102  	rawYAML, err := jsonToYAML(rawJSON)
   103  	if err != nil {
   104  		return nil, err
   105  	}
   106  	swaggerFile = filepath.Join(swaggerDir, "swagger.yaml")
   107  	if err := ioutil.WriteFile(swaggerFile, rawYAML, 0644); err != nil {
   108  		return nil, err
   109  	}
   110  	g.genfiles = append(g.genfiles, swaggerFile)
   111  
   112  	return g.genfiles, nil
   113  }
   114  
   115  // Cleanup removes all the files generated by this generator during the last invokation of Generate.
   116  func (g *Generator) Cleanup() {
   117  	for _, f := range g.genfiles {
   118  		os.Remove(f)
   119  	}
   120  	g.genfiles = nil
   121  }
   122  
   123  func jsonToYAML(rawJSON []byte) ([]byte, error) {
   124  	var yamlSource interface{}
   125  	if err := yaml.Unmarshal(rawJSON, &yamlSource); err != nil {
   126  		return nil, err
   127  	}
   128  
   129  	return yaml.Marshal(yamlSource)
   130  }