Skip to content

Commit

Permalink
ensure imports generation
Browse files Browse the repository at this point in the history
  • Loading branch information
casualjim committed Mar 2, 2015
1 parent e8a970e commit aa5d71a
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 73 deletions.
1 change: 1 addition & 0 deletions cmd/swagger/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ swagger
swagger.json
models
operations
cmd
28 changes: 14 additions & 14 deletions generator/bindata.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions generator/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ type genModel struct {
DocString string //`json:"docString,omitempty"`
HumanClassName string //`json:"humanClassname,omitempty"`
Imports map[string]string //`json:"imports,omitempty"`
DefaultImports []string //`json:"defaultImports,omitempty"`
HasValidations bool // `json:"hasValidatins,omitempty"`
}

Expand Down
12 changes: 7 additions & 5 deletions generator/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,18 @@ func (o *operationGenerator) Generate() error {
// fmt.Println(string(bb))
for _, tag := range o.Operation.Tags {
if len(o.Tags) == 0 {
operations = append(operations, makeCodegenOperation(o.Name, tag, o.ModelsPackage, o.Principal, o.Operation, authed))
operations = append(operations, makeCodegenOperation(o.Name, tag, o.ModelsPackage, o.Principal, o.Target, o.Operation, authed))
continue
}
for _, ft := range o.Tags {
if ft == tag {
operations = append(operations, makeCodegenOperation(o.Name, tag, o.ModelsPackage, o.Principal, o.Operation, authed))
operations = append(operations, makeCodegenOperation(o.Name, tag, o.ModelsPackage, o.Principal, o.Target, o.Operation, authed))
}
}

}
if len(operations) == 0 {
operations = append(operations, makeCodegenOperation(o.Name, o.APIPackage, o.ModelsPackage, o.Principal, o.Operation, authed))
operations = append(operations, makeCodegenOperation(o.Name, o.APIPackage, o.ModelsPackage, o.Principal, o.Target, o.Operation, authed))
}

for _, op := range operations {
Expand Down Expand Up @@ -175,7 +175,7 @@ func (o *operationGenerator) generateParameterModel() error {
return writeToFile(fp, o.Name+"Parameters", buf.Bytes())
}

func makeCodegenOperation(name, pkg, modelsPkg, principal string, operation spec.Operation, authorized bool) genOperation {
func makeCodegenOperation(name, pkg, modelsPkg, principal, target string, operation spec.Operation, authorized bool) genOperation {
receiver := "o"

var params, qp, pp, hp, fp []genParameter
Expand Down Expand Up @@ -229,6 +229,7 @@ func makeCodegenOperation(name, pkg, modelsPkg, principal string, operation spec
DocString: operationDocString(util.ToGoName(name), operation),
ReceiverName: receiver,
HumanClassName: util.ToHumanNameLower(util.ToGoName(name)),
DefaultImports: []string{filepath.Join(baseImport(target), modelsPkg)},
Params: params,
Summary: operation.Summary,
QueryParams: qp,
Expand Down Expand Up @@ -275,7 +276,8 @@ type genOperation struct {
DocString string //`json:"docString,omitempty"` // -
ExternalDocs string //`json:"externalDocs,omitempty"`

Imports map[string]string //`json:"imports,omitempty"` // -
Imports map[string]string //`json:"imports,omitempty"` // -
DefaultImports []string //`json:"defaultImports,omitempty"` // -

Authorized bool //`json:"authorized"` // -
Principal string //`json:"principal,omitempty"` // -
Expand Down
109 changes: 83 additions & 26 deletions generator/support.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,29 @@ type appGenerator struct {
IncludeUI bool
}

func baseImport(tgt string) string {
p, err := filepath.Abs(tgt)
if err != nil {
log.Fatalln(err)
}

var pth string
for _, gp := range filepath.SplitList(os.Getenv("GOPATH")) {
pp := filepath.Join(gp, "src")
if strings.HasPrefix(p, pp) {
pth = strings.TrimPrefix(p, pp+"/")
break
}
}

if pth == "" {
log.Fatalln("target must reside inside a location in the gopath")
}
return pth
}

func (a *appGenerator) Generate() error {
app := makeCodegenApp(a.Name, a.Package, a.Target, a.ModelsPackage, a.APIPackage, a.Principal, a.SpecDoc, a.Models, a.Operations, a.IncludeUI)
app := a.makeCodegenApp()

if a.DumpData {
bb, _ := json.MarshalIndent(util.ToDynamicJSON(app), "", " ")
Expand All @@ -129,6 +150,7 @@ func (a *appGenerator) Generate() error {
if err := a.generateAPIBuilder(&app); err != nil {
return err
}
app.DefaultImports = append(app.DefaultImports, filepath.Join(baseImport(a.Target), a.ServerPackage, a.APIPackage))

if err := a.generateConfigureAPI(&app); err != nil {
return err
Expand Down Expand Up @@ -211,20 +233,27 @@ func getSerializer(sers []genSerGroup, ext string) (*genSerGroup, bool) {
return nil, false
}

func makeCodegenApp(name, pkg, target, modelPackage, apiPackage, principal string, specDoc *spec.Document, models map[string]spec.Schema, operations map[string]spec.Operation, includeUI bool) genApp {
sw := specDoc.Spec()
receiver := strings.ToLower(name[:1])
appName := util.ToGoName(name)
// func makeCodegenApp(operations map[string]spec.Operation, includeUI bool) genApp {
func (a *appGenerator) makeCodegenApp() genApp {
sw := a.SpecDoc.Spec()
// app := makeCodegenApp(a.Operations, a.IncludeUI)
receiver := strings.ToLower(a.Name[:1])
appName := util.ToGoName(a.Name)
var defaultImports []string

jsonb, _ := json.MarshalIndent(specDoc.Spec(), "", " ")
jsonb, _ := json.MarshalIndent(a.SpecDoc.Spec(), "", " ")

consumesJSON := false
var consumes []genSerGroup
for _, cons := range specDoc.RequiredConsumes() {
for _, cons := range a.SpecDoc.RequiredConsumes() {
cn, ok := mediaTypeNames[cons]
if !ok {
continue
}
nm := util.ToJSONName(cn)
if nm == "json" {
consumesJSON = true
}

if ser, ok := getSerializer(consumes, cn); ok {
ser.AllSerializers = append(ser.AllSerializers, genSerializer{
Expand Down Expand Up @@ -261,13 +290,17 @@ func makeCodegenApp(name, pkg, target, modelPackage, apiPackage, principal strin
})
}

producesJSON := false
var produces []genSerGroup
for _, prod := range specDoc.RequiredProduces() {
for _, prod := range a.SpecDoc.RequiredProduces() {
pn, ok := mediaTypeNames[prod]
if !ok {
continue
}
nm := util.ToJSONName(pn)
if nm == "json" {
producesJSON = true
}

if ser, ok := getSerializer(produces, pn); ok {
ser.AllSerializers = append(ser.AllSerializers, genSerializer{
Expand Down Expand Up @@ -303,8 +336,8 @@ func makeCodegenApp(name, pkg, target, modelPackage, apiPackage, principal strin
}

var security []genSecurityScheme
for _, scheme := range specDoc.RequiredSchemes() {
if req, ok := specDoc.Spec().SecurityDefinitions[scheme]; ok {
for _, scheme := range a.SpecDoc.RequiredSchemes() {
if req, ok := a.SpecDoc.Spec().SecurityDefinitions[scheme]; ok {
if req.Type == "basic" || req.Type == "apiKey" {
security = append(security, genSecurityScheme{
AppName: appName,
Expand All @@ -314,60 +347,81 @@ func makeCodegenApp(name, pkg, target, modelPackage, apiPackage, principal strin
Name: util.ToJSONName(req.Name),
IsBasicAuth: strings.ToLower(req.Type) == "basic",
IsAPIKeyAuth: strings.ToLower(req.Type) == "apikey",
Principal: principal,
Principal: a.Principal,
Source: req.In,
})
}
}
}

var genMods []genModel
for mn, m := range models {
defaultImports = append(defaultImports, filepath.Join(baseImport(a.Target), a.ModelsPackage))
for mn, m := range a.Models {
mod := *makeCodegenModel(
mn,
modelPackage,
a.ModelsPackage,
m,
specDoc,
a.SpecDoc,
)
mod.ReceiverName = receiver
genMods = append(genMods, mod)
}

var genOps []genOperation
for on, o := range operations {
authed := len(specDoc.SecurityRequirementsFor(&o)) > 0
ap := apiPackage
if apiPackage == pkg {
tns := make(map[string]struct{})
for on, o := range a.Operations {
authed := len(a.SpecDoc.SecurityRequirementsFor(&o)) > 0
ap := a.APIPackage
if a.APIPackage == a.Package {
ap = ""
}
if len(o.Tags) > 0 {
for _, tag := range o.Tags {
op := makeCodegenOperation(on, tag, modelPackage, principal, o, authed)
tns[tag] = struct{}{}
op := makeCodegenOperation(on, tag, a.ModelsPackage, a.Principal, a.Target, o, authed)
op.ReceiverName = receiver
genOps = append(genOps, op)
}
} else {
op := makeCodegenOperation(on, ap, modelPackage, principal, o, authed)
op := makeCodegenOperation(on, ap, a.ModelsPackage, a.Principal, a.Target, o, authed)
op.ReceiverName = receiver
genOps = append(genOps, op)
}
}
for k := range tns {
defaultImports = append(defaultImports, filepath.Join(baseImport(a.Target), a.ServerPackage, a.APIPackage, k))
}

defaultConsumes := "application/json"
rc := a.SpecDoc.RequiredConsumes()
if !consumesJSON && len(rc) > 0 {
defaultConsumes = rc[0]
}

defaultProduces := "application/json"
rp := a.SpecDoc.RequiredProduces()
if !producesJSON && len(rp) > 0 {
defaultProduces = rp[0]
}

return genApp{
Package: pkg,
Package: a.Package,
ReceiverName: receiver,
AppName: util.ToGoName(name),
HumanAppName: util.ToHumanNameLower(name),
Name: util.ToJSONName(name),
AppName: util.ToGoName(a.Name),
HumanAppName: util.ToHumanNameLower(a.Name),
Name: util.ToJSONName(a.Name),
ExternalDocs: sw.ExternalDocs,
Info: sw.Info,
Consumes: consumes,
Produces: produces,
DefaultConsumes: defaultConsumes,
DefaultProduces: defaultProduces,
DefaultImports: defaultImports,
SecurityDefinitions: security,
Models: genMods,
Operations: genOps,
IncludeUI: includeUI,
Principal: principal,
IncludeUI: a.IncludeUI,
Principal: a.Principal,
SwaggerJSON: fmt.Sprintf("%#v", jsonb),
}
}
Expand All @@ -379,9 +433,12 @@ type genApp struct {
HumanAppName string
Name string
Principal string
DefaultConsumes string
DefaultProduces string
Info *spec.Info
ExternalDocs *spec.ExternalDocumentation
Imports map[string]string
DefaultImports []string
Consumes []genSerGroup
Produces []genSerGroup
SecurityDefinitions []genSecurityScheme
Expand Down
5 changes: 3 additions & 2 deletions generator/templates/model.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ package {{.Package}}
// Editing this file might prove futile when you re-run the swagger generate command

{{if .Imports}}imports (
{{range $key, $value := .Imports}}
{{$key}} {{ printf "%q" $value}}
{{range .DefaultImports}}{{printf "%q" .}}
{{end}}
{{range $key, $value := .Imports}}{{$key}} {{ printf "%q" $value}}
{{end}}
)
{{end}}
Expand Down
5 changes: 3 additions & 2 deletions generator/templates/modelvalidator.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ import (
"github.com/casualjim/go-swagger/strfmt"
"github.com/casualjim/go-swagger/validation"

{{range $key, $value := .Imports}}
{{$key}} {{ printf "%q" $value}}
{{range .DefaultImports}}{{printf "%q" .}}
{{end}}
{{range $key, $value := .Imports}}{{$key}} {{ printf "%q" $value}}
{{end}}
)

Expand Down
39 changes: 31 additions & 8 deletions generator/templates/server/builder.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (
"github.com/casualjim/go-swagger/middleware"
"github.com/casualjim/go-swagger/middleware/security"

{{range $key, $value := .Imports}}
{{$key}} {{ printf "%q" $value}}
{{range .DefaultImports}}{{printf "%q" .}}
{{end}}
{{range $key, $value := .Imports}}{{$key}} {{ printf "%q" $value}}
{{end}}
)

Expand All @@ -23,19 +24,21 @@ func New{{.AppName}}API(spec *spec.Document) *{{.AppName}}API {
spec: spec,
handlers: make(map[string]http.Handler),
formats: strfmt.Default,
defaultConsumes: "{{.DefaultConsumes}}",
defaultProduces: "{{.DefaultProduces}}",
}

{{.ReceiverName}}.context = middleware.NewRoutableContext(spec, {{.ReceiverName}}, nil)

return {{.ReceiverName}}
}

// {{.AppName}}API {{.Info.Description}}
type {{.AppName}}API struct {
spec *spec.Document
context *middleware.Context
handlers map[string]http.Handler
formats strfmt.Registry
spec *spec.Document
context *middleware.Context
handlers map[string]http.Handler
formats strfmt.Registry
defaultConsumes string
defaultProduces string
{{range .Consumes}}// {{.ClassName}}Consumer registers a consumer for a "{{.MediaType}}" mime type
{{.ClassName}}Consumer swagger.Consumer
{{end}}
Expand All @@ -61,6 +64,26 @@ type {{.AppName}}API struct {
ServeError func(http.ResponseWriter, *http.Request, error)
}

// SetDefaultProduces sets the default produces media type
func ({{.ReceiverName}} *{{.AppName}}API) SetDefaultProduces(mediaType string) {
{{.ReceiverName}}.defaultProduces = mediaType
}

// SetDefaultConsumes returns the default consumes media type
func ({{.ReceiverName}} *{{.AppName}}API) SetDefaultConsumes(mediaType string) {
{{.ReceiverName}}.defaultConsumes = mediaType
}

// DefaultProduces returns the default produces media type
func ({{.ReceiverName}} *{{.AppName}}API) DefaultProduces() string {
return {{.ReceiverName}}.defaultProduces
}

// DefaultConsumes returns the default consumes media type
func ({{.ReceiverName}} *{{.AppName}}API) DefaultConsumes() string {
return {{.ReceiverName}}.defaultConsumes
}

// Formats returns the registered string formats
func ({{.ReceiverName}} *{{.AppName}}API) Formats() strfmt.Registry {
return {{.ReceiverName}}.formats
Expand Down
5 changes: 5 additions & 0 deletions generator/templates/server/configureapi.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package main

import (
"github.com/casualjim/go-swagger/errors"

{{range .DefaultImports}}{{printf "%q" .}}
{{end}}
{{range $key, $value := .Imports}}{{$key}} {{ printf "%q" $value}}
{{end}}
)

// This file is safe to edit. Once it exists it won't be overwritten
Expand Down
5 changes: 5 additions & 0 deletions generator/templates/server/main.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import (
"net/http"

"github.com/casualjim/go-swagger/spec"

{{range .DefaultImports}}{{printf "%q" .}}
{{end}}
{{range $key, $value := .Imports}}{{$key}} {{ printf "%q" $value}}
{{end}}
)

// This file was generated by the swagger tool.
Expand Down
Loading

0 comments on commit aa5d71a

Please sign in to comment.