2018-11-12 16:46:35 +01:00
|
|
|
package gen
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2019-05-07 21:42:24 +02:00
|
|
|
"fmt"
|
2018-11-12 16:46:35 +01:00
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"text/template"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/ghodss/yaml"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/swaggo/swag"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Gen presents a generate tool for swag.
|
|
|
|
type Gen struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
// New creates a new Gen.
|
|
|
|
func New() *Gen {
|
|
|
|
return &Gen{}
|
|
|
|
}
|
|
|
|
|
2019-05-07 21:42:24 +02:00
|
|
|
// Config presents Gen configurations.
|
|
|
|
type Config struct {
|
|
|
|
// SearchDir the swag would be parse
|
|
|
|
SearchDir string
|
|
|
|
|
|
|
|
//OutputDir represents the output directory for al the generated files
|
|
|
|
OutputDir string
|
|
|
|
|
|
|
|
//MainAPIFile the Go file path in which 'swagger general API Info' is written
|
|
|
|
MainAPIFile string
|
|
|
|
|
|
|
|
//PropNamingStrategy represents property naming strategy like snakecase,camelcase,pascalcase
|
|
|
|
PropNamingStrategy string
|
|
|
|
|
|
|
|
//ParseVendor whether swag should be parse vendor folder
|
|
|
|
ParseVendor bool
|
|
|
|
}
|
|
|
|
|
2018-11-12 16:46:35 +01:00
|
|
|
// Build builds swagger json file for gived searchDir and mainAPIFile. Returns json
|
2019-05-07 21:42:24 +02:00
|
|
|
func (g *Gen) Build(config *Config) error {
|
|
|
|
if _, err := os.Stat(config.SearchDir); os.IsNotExist(err) {
|
|
|
|
return fmt.Errorf("dir: %s is not exist", config.SearchDir)
|
|
|
|
}
|
|
|
|
|
2018-11-12 16:46:35 +01:00
|
|
|
log.Println("Generate swagger docs....")
|
|
|
|
p := swag.New()
|
2019-05-07 21:42:24 +02:00
|
|
|
p.PropNamingStrategy = config.PropNamingStrategy
|
|
|
|
p.ParseVendor = config.ParseVendor
|
|
|
|
|
|
|
|
if err := p.ParseAPI(config.SearchDir, config.MainAPIFile); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-11-12 16:46:35 +01:00
|
|
|
swagger := p.GetSwagger()
|
|
|
|
|
|
|
|
b, err := json.MarshalIndent(swagger, "", " ")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-05-07 21:42:24 +02:00
|
|
|
os.MkdirAll(config.OutputDir, os.ModePerm)
|
|
|
|
docs, err := os.Create(path.Join(config.OutputDir, "docs.go"))
|
2018-11-12 16:46:35 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer docs.Close()
|
|
|
|
|
2019-05-07 21:42:24 +02:00
|
|
|
swaggerJSON, err := os.Create(path.Join(config.OutputDir, "swagger.json"))
|
2018-11-12 16:46:35 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer swaggerJSON.Close()
|
|
|
|
swaggerJSON.Write(b)
|
|
|
|
|
2019-05-07 21:42:24 +02:00
|
|
|
swaggerYAML, err := os.Create(path.Join(config.OutputDir, "swagger.yaml"))
|
2018-11-12 16:46:35 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer swaggerYAML.Close()
|
|
|
|
y, err := yaml.JSONToYAML(b)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "cannot covert json to yaml")
|
|
|
|
}
|
|
|
|
|
|
|
|
swaggerYAML.Write(y)
|
|
|
|
|
|
|
|
if err := packageTemplate.Execute(docs, struct {
|
|
|
|
Timestamp time.Time
|
|
|
|
Doc string
|
|
|
|
}{
|
|
|
|
Timestamp: time.Now(),
|
|
|
|
Doc: "`" + string(b) + "`",
|
|
|
|
}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("create docs.go at %+v", docs.Name())
|
2019-05-07 21:42:24 +02:00
|
|
|
log.Printf("create swagger.json at %+v", swaggerJSON.Name())
|
|
|
|
log.Printf("create swagger.yaml at %+v", swaggerYAML.Name())
|
|
|
|
|
2018-11-12 16:46:35 +01:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var packageTemplate = template.Must(template.New("").Parse(`// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
|
|
|
// This file was generated by swaggo/swag at
|
|
|
|
// {{ .Timestamp }}
|
|
|
|
|
|
|
|
package docs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
|
|
|
|
"github.com/alecthomas/template"
|
|
|
|
"github.com/swaggo/swag"
|
|
|
|
)
|
|
|
|
|
|
|
|
var doc = {{.Doc}}
|
|
|
|
|
|
|
|
type swaggerInfo struct {
|
|
|
|
Version string
|
|
|
|
Host string
|
|
|
|
BasePath string
|
|
|
|
Title string
|
|
|
|
Description string
|
|
|
|
}
|
|
|
|
|
|
|
|
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
|
|
|
var SwaggerInfo swaggerInfo
|
|
|
|
|
|
|
|
type s struct{}
|
|
|
|
|
|
|
|
func (s *s) ReadDoc() string {
|
|
|
|
t, err := template.New("swagger_info").Parse(doc)
|
|
|
|
if err != nil {
|
|
|
|
return doc
|
|
|
|
}
|
|
|
|
|
|
|
|
var tpl bytes.Buffer
|
|
|
|
if err := t.Execute(&tpl, SwaggerInfo); err != nil {
|
|
|
|
return doc
|
|
|
|
}
|
|
|
|
|
|
|
|
return tpl.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
swag.Register(swag.Name, &s{})
|
|
|
|
}
|
|
|
|
`))
|