github.com/shogo82148/goa-v1@v1.6.2/goagen/gen_swagger/generator.go (about)

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