github.com/circl-dev/go-swagger@v0.31.0/cmd/swagger/commands/generate/spec_go111.go (about)

     1  // +build go1.11
     2  
     3  package generate
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"strings"
    11  
    12  	"github.com/circl-dev/go-swagger/codescan"
    13  
    14  	"github.com/circl-dev/loads"
    15  	"github.com/circl-dev/spec"
    16  	"github.com/jessevdk/go-flags"
    17  	"gopkg.in/yaml.v2"
    18  )
    19  
    20  // SpecFile command to generate a swagger spec from a go application
    21  type SpecFile struct {
    22  	WorkDir     string         `long:"work-dir" short:"w" description:"the base path to use" default:"."`
    23  	BuildTags   string         `long:"tags" short:"t" description:"build tags" default:""`
    24  	ScanModels  bool           `long:"scan-models" short:"m" description:"includes models that were annotated with 'swagger:model'"`
    25  	Compact     bool           `long:"compact" description:"when present, doesn't prettify the json"`
    26  	Output      flags.Filename `long:"output" short:"o" description:"the file to write to"`
    27  	Input       flags.Filename `long:"input" short:"i" description:"an input swagger file with which to merge"`
    28  	Include     []string       `long:"include" short:"c" description:"include packages matching pattern"`
    29  	Exclude     []string       `long:"exclude" short:"x" description:"exclude packages matching pattern"`
    30  	IncludeTags []string       `long:"include-tag" short:"" description:"include routes having specified tags (can be specified many times)"`
    31  	ExcludeTags []string       `long:"exclude-tag" short:"" description:"exclude routes having specified tags (can be specified many times)"`
    32  	ExcludeDeps bool           `long:"exclude-deps" short:"" description:"exclude all dependencies of project"`
    33  }
    34  
    35  // Execute runs this command
    36  func (s *SpecFile) Execute(args []string) error {
    37  	if len(args) == 0 { // by default consider all the paths under the working directory
    38  		args = []string{"./..."}
    39  	}
    40  
    41  	input, err := loadSpec(string(s.Input))
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	var opts codescan.Options
    47  	opts.Packages = args
    48  	opts.WorkDir = s.WorkDir
    49  	opts.InputSpec = input
    50  	opts.ScanModels = s.ScanModels
    51  	opts.BuildTags = s.BuildTags
    52  	opts.Include = s.Include
    53  	opts.Exclude = s.Exclude
    54  	opts.IncludeTags = s.IncludeTags
    55  	opts.ExcludeTags = s.ExcludeTags
    56  	opts.ExcludeDeps = s.ExcludeDeps
    57  	swspec, err := codescan.Run(&opts)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	return writeToFile(swspec, !s.Compact, string(s.Output))
    63  }
    64  
    65  func loadSpec(input string) (*spec.Swagger, error) {
    66  	if fi, err := os.Stat(input); err == nil {
    67  		if fi.IsDir() {
    68  			return nil, fmt.Errorf("expected %q to be a file not a directory", input)
    69  		}
    70  		sp, err := loads.Spec(input)
    71  		if err != nil {
    72  			return nil, err
    73  		}
    74  		return sp.Spec(), nil
    75  	}
    76  	return nil, nil
    77  }
    78  
    79  func writeToFile(swspec *spec.Swagger, pretty bool, output string) error {
    80  	var b []byte
    81  	var err error
    82  
    83  	if strings.HasSuffix(output, "yml") || strings.HasSuffix(output, "yaml") {
    84  		b, err = marshalToYAMLFormat(swspec)
    85  	} else {
    86  		b, err = marshalToJSONFormat(swspec, pretty)
    87  	}
    88  
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	if output == "" {
    94  		fmt.Println(string(b))
    95  		return nil
    96  	}
    97  	return ioutil.WriteFile(output, b, 0644) // #nosec
    98  }
    99  
   100  func marshalToJSONFormat(swspec *spec.Swagger, pretty bool) ([]byte, error) {
   101  	if pretty {
   102  		return json.MarshalIndent(swspec, "", "  ")
   103  	}
   104  	return json.Marshal(swspec)
   105  }
   106  
   107  func marshalToYAMLFormat(swspec *spec.Swagger) ([]byte, error) {
   108  	b, err := json.Marshal(swspec)
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	var jsonObj interface{}
   114  	if err := yaml.Unmarshal(b, &jsonObj); err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	return yaml.Marshal(jsonObj)
   119  }