Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specific docs file type write #577

Merged
merged 8 commits into from Jan 18, 2022
16 changes: 15 additions & 1 deletion cmd/swag/main.go
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"log"
"os"
"strings"

"github.com/urfave/cli/v2"

Expand All @@ -18,6 +19,7 @@ const (
generalInfoFlag = "generalInfo"
propertyStrategyFlag = "propertyStrategy"
outputFlag = "output"
outputTypesFlag = "outputTypes"
parseVendorFlag = "parseVendor"
parseDependencyFlag = "parseDependency"
markdownFilesFlag = "markdownFiles"
Expand Down Expand Up @@ -56,7 +58,13 @@ var initFlags = []cli.Flag{
Name: outputFlag,
Aliases: []string{"o"},
Value: "./docs",
Usage: "Output directory for all the generated files(swagger.json, swagger.yaml and doc.go)",
Usage: "Output directory for all the generated files(swagger.json, swagger.yaml and docs.go)",
},
&cli.StringFlag{
Name: outputTypesFlag,
Aliases: []string{"ot"},
Value: "go,json,yaml",
Usage: "Output types of generated files (docs.go, swagger.json, swagger.yaml) like go,json,yaml",
},
&cli.BoolFlag{
Name: parseVendorFlag,
Expand Down Expand Up @@ -113,12 +121,18 @@ func initAction(c *cli.Context) error {
return fmt.Errorf("not supported %s propertyStrategy", strategy)
}

outputTypes := strings.Split(c.String(outputTypesFlag), ",")
if len(outputTypes) == 0 {
return fmt.Errorf("no output types specified")
}

return gen.New().Build(&gen.Config{
SearchDir: c.String(searchDirFlag),
Excludes: c.String(excludeFlag),
MainAPIFile: c.String(generalInfoFlag),
PropNamingStrategy: strategy,
OutputDir: c.String(outputFlag),
OutputTypes: outputTypes,
ParseVendor: c.Bool(parseVendorFlag),
ParseDependency: c.Bool(parseDependencyFlag),
MarkdownFilesDir: c.String(markdownFilesFlag),
Expand Down
88 changes: 69 additions & 19 deletions gen/gen.go
Expand Up @@ -9,6 +9,7 @@ import (
"io"
"log"
"os"
"path"
"path/filepath"
"strings"
"text/template"
Expand All @@ -24,20 +25,36 @@ var open = os.Open
// DefaultOverridesFile is the location swaggo will look for type overrides.
const DefaultOverridesFile = ".swaggo"

type genTypeWriter func(*Config, *spec.Swagger) error

// Gen presents a generate tool for swag.
type Gen struct {
jsonIndent func(data interface{}) ([]byte, error)
jsonToYAML func(data []byte) ([]byte, error)
json func(data interface{}) ([]byte, error)
jsonIndent func(data interface{}) ([]byte, error)
jsonToYAML func(data []byte) ([]byte, error)
outputTypeMap map[string]genTypeWriter
}

// New creates a new Gen.
func New() *Gen {
return &Gen{
gen := &Gen{
json: func(data interface{}) ([]byte, error) {
return json.Marshal(data)
},
jsonIndent: func(data interface{}) ([]byte, error) {
return json.MarshalIndent(data, "", " ")
},
jsonToYAML: yaml.JSONToYAML,
}

gen.outputTypeMap = map[string]genTypeWriter{
"go": gen.writeDocSwagger,
"json": gen.writeJSONSwagger,
"yaml": gen.writeYAMLSwagger,
"yml": gen.writeYAMLSwagger,
}

return gen
}

// Config presents Gen configurations.
Expand All @@ -51,6 +68,9 @@ type Config struct {
// OutputDir represents the output directory for all the generated files
OutputDir string

// OutputTypes define types of files which should be generated
OutputTypes []string

// MainAPIFile the Go file path in which 'swagger general API Info' is written
MainAPIFile string

Expand Down Expand Up @@ -137,55 +157,85 @@ func (g *Gen) Build(config *Config) error {
}
swagger := p.GetSwagger()

b, err := g.jsonIndent(swagger)
if err != nil {
if err := os.MkdirAll(config.OutputDir, os.ModePerm); err != nil {
return err
}

if err := os.MkdirAll(config.OutputDir, os.ModePerm); err != nil {
return err
for _, outputType := range config.OutputTypes {
outputType = strings.ToLower(strings.TrimSpace(outputType))
if typeWriter, ok := g.outputTypeMap[outputType]; ok {
if err := typeWriter(config, swagger); err != nil {
return err
}
} else {
log.Printf("output type '%s' not supported", outputType)
}
}

return nil
}

func (g *Gen) writeDocSwagger(config *Config, swagger *spec.Swagger) error {
docFileName := path.Join(config.OutputDir, "docs.go")

absOutputDir, err := filepath.Abs(config.OutputDir)
if err != nil {
return err
}
packageName := filepath.Base(absOutputDir)
docFileName := filepath.Join(config.OutputDir, "docs.go")
jsonFileName := filepath.Join(config.OutputDir, "swagger.json")
yamlFileName := filepath.Join(config.OutputDir, "swagger.yaml")

docs, err := os.Create(docFileName)
if err != nil {
return err
}
defer docs.Close()

err = g.writeFile(b, jsonFileName)
// Write doc
err = g.writeGoDoc(packageName, docs, swagger, config)
if err != nil {
return err
}

y, err := g.jsonToYAML(b)
log.Printf("create docs.go at %+v", docFileName)
return nil
}

func (g *Gen) writeJSONSwagger(config *Config, swagger *spec.Swagger) error {
jsonFileName := path.Join(config.OutputDir, "swagger.json")

b, err := g.jsonIndent(swagger)
if err != nil {
return fmt.Errorf("cannot convert json to yaml error: %s", err)
return err
}

err = g.writeFile(y, yamlFileName)
err = g.writeFile(b, jsonFileName)
if err != nil {
return err
}

// Write doc
err = g.writeGoDoc(packageName, docs, swagger, config)
log.Printf("create swagger.json at %+v", jsonFileName)
return nil
}

func (g *Gen) writeYAMLSwagger(config *Config, swagger *spec.Swagger) error {
yamlFileName := path.Join(config.OutputDir, "swagger.yaml")

b, err := g.json(swagger)
if err != nil {
return err
}

log.Printf("create docs.go at %+v", docFileName)
log.Printf("create swagger.json at %+v", jsonFileName)
log.Printf("create swagger.yaml at %+v", yamlFileName)
y, err := g.jsonToYAML(b)
if err != nil {
return fmt.Errorf("cannot covert json to yaml error: %s", err)
}

err = g.writeFile(y, yamlFileName)
if err != nil {
return err
}

log.Printf("create swagger.yaml at %+v", yamlFileName)
return nil
}

Expand Down