// generateControllers iterates through the API resources and generates the low level // controllers. func (g *Generator) generateSecurity() error { if len(g.API.SecuritySchemes) == 0 { return nil } secFile := filepath.Join(g.OutDir, "security.go") secWr, err := NewSecurityWriter(secFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Security", g.API.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("net/http"), codegen.SimpleImport("errors"), codegen.SimpleImport("golang.org/x/net/context"), codegen.SimpleImport("github.com/goadesign/goa"), } secWr.WriteHeader(title, g.Target, imports) g.genfiles = append(g.genfiles, secFile) if err = secWr.Execute(design.Design.SecuritySchemes); err != nil { return err } return secWr.FormatCode() }
// generateUserTypes iterates through the user types and generates the data structures and // marshaling code. func (g *Generator) generateUserTypes(verdir string, version *design.APIVersionDefinition) error { utFile := filepath.Join(verdir, "user_types.go") utWr, err := NewUserTypesWriter(utFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application User Types", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("fmt"), codegen.SimpleImport("time"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } utWr.WriteHeader(title, packageName(version), imports) err = version.IterateUserTypes(func(t *design.UserTypeDefinition) error { data := &UserTypeTemplateData{ UserType: t, Versioned: version.Version != "", DefaultPkg: TargetPackage, } return utWr.Execute(data) }) g.genfiles = append(g.genfiles, utFile) if err != nil { return err } return utWr.FormatCode() }
// generateMediaTypes iterates through the media types and generate the data structures and // marshaling code. func (g *Generator) generateMediaTypes(api *design.APIDefinition) error { mtFile := filepath.Join(AppOutputDir(), "media_types.go") mtWr, err := NewMediaTypesWriter(mtFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Media Types", api.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("fmt"), codegen.SimpleImport("time"), } mtWr.WriteHeader(title, TargetPackage, imports) err = api.IterateMediaTypes(func(mt *design.MediaTypeDefinition) error { if mt.IsBuiltIn() { return nil } if mt.Type.IsObject() || mt.Type.IsArray() { return mtWr.Execute(mt) } return nil }) g.genfiles = append(g.genfiles, mtFile) if err != nil { return err } return mtWr.FormatCode() }
func (g *Generator) generateClientResources(clientPkg string, funcs template.FuncMap, api *design.APIDefinition) error { clientsTmpl := template.Must(template.New("clients").Funcs(funcs).Parse(clientsTmpl)) imports := []*codegen.ImportSpec{ codegen.SimpleImport("bytes"), codegen.SimpleImport("encoding/json"), codegen.SimpleImport("fmt"), codegen.SimpleImport("net/http"), } return api.IterateResources(func(res *design.ResourceDefinition) error { filename := filepath.Join(codegen.OutputDir, snakeCase(res.Name)+".go") file, err := codegen.SourceFileFor(filename) if err != nil { return err } if err := file.WriteHeader("", "client", imports); err != nil { return err } g.genfiles = append(g.genfiles, filename) if err := res.IterateActions(func(action *design.ActionDefinition) error { return clientsTmpl.Execute(file, action) }); err != nil { return err } return file.FormatCode() }) }
// generateMediaTypes iterates through the media types and generate the data structures and // marshaling code. func (g *Generator) generateMediaTypes(verdir string, version *design.APIVersionDefinition) error { mtFile := filepath.Join(verdir, "media_types.go") mtWr, err := NewMediaTypesWriter(mtFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Media Types", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("fmt"), } mtWr.WriteHeader(title, packageName(version), imports) err = version.IterateMediaTypes(func(mt *design.MediaTypeDefinition) error { data := &MediaTypeTemplateData{ MediaType: mt, Versioned: version.Version != "", DefaultPkg: TargetPackage, } if mt.Type.IsObject() || mt.Type.IsArray() { return mtWr.Execute(data) } return nil }) g.genfiles = append(g.genfiles, mtFile) if err != nil { return err } return mtWr.FormatCode() }
func (m *Generator) generateToolSourceCode(pkg *codegen.Package) { file := pkg.CreateSourceFile("main.go") imports := append(m.Imports, codegen.SimpleImport("fmt"), codegen.SimpleImport("os"), codegen.SimpleImport("strings"), codegen.SimpleImport("github.com/goadesign/goa/dslengine"), codegen.NewImport("_", filepath.ToSlash(codegen.DesignPackagePath)), ) file.WriteHeader("Code Generator", "main", imports) tmpl, err := template.New("generator").Parse(mainTmpl) if err != nil { panic(err) // bug } pkgName, err := codegen.PackageName(pkg.Abs()) if err != nil { panic(err) } context := map[string]string{ "Genfunc": m.Genfunc, "DesignPackage": codegen.DesignPackagePath, "PkgName": pkgName, } err = tmpl.Execute(file, context) if err != nil { panic(err) // bug } }
func (g *Generator) createMainFile(mainFile string, funcs template.FuncMap) error { g.genfiles = append(g.genfiles, mainFile) file, err := codegen.SourceFileFor(mainFile) if err != nil { return err } funcs["getPort"] = func(hostport string) string { _, port, err := net.SplitHostPort(hostport) if err != nil { return "8080" } return port } outPkg, err := codegen.PackagePath(g.OutDir) if err != nil { return err } appPkg := path.Join(outPkg, "app") imports := []*codegen.ImportSpec{ codegen.SimpleImport("time"), codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("github.com/goadesign/goa/middleware"), codegen.SimpleImport(appPkg), } file.Write([]byte("//go:generate goagen bootstrap -d " + g.DesignPkg + "\n\n")) file.WriteHeader("", "main", imports) data := map[string]interface{}{ "Name": g.API.Name, "API": g.API, } if err = file.ExecuteTemplate("main", mainT, funcs, data); err != nil { return err } return file.FormatCode() }
// generateMediaTypes iterates through the media types and generate the data structures and // marshaling code. func (g *Generator) generateMediaTypes() error { mtFile := filepath.Join(g.OutDir, "media_types.go") mtWr, err := NewMediaTypesWriter(mtFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Media Types", g.API.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("fmt"), codegen.SimpleImport("time"), codegen.SimpleImport("unicode/utf8"), codegen.NewImport("uuid", "github.com/satori/go.uuid"), } mtWr.WriteHeader(title, g.Target, imports) err = g.API.IterateMediaTypes(func(mt *design.MediaTypeDefinition) error { if mt.IsError() { return nil } if mt.Type.IsObject() || mt.Type.IsArray() { return mtWr.Execute(mt) } return nil }) g.genfiles = append(g.genfiles, mtFile) if err != nil { return err } return mtWr.FormatCode() }
// generateControllers iterates through the version resources and generates the low level // controllers. func (g *Generator) generateControllers(verdir string, version *design.APIVersionDefinition) error { ctlFile := filepath.Join(verdir, "controllers.go") ctlWr, err := NewControllersWriter(ctlFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Controllers", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/julienschmidt/httprouter"), codegen.SimpleImport("github.com/goadesign/goa"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } ctlWr.WriteHeader(title, packageName(version), imports) var controllersData []*ControllerTemplateData version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } data := &ControllerTemplateData{Resource: codegen.Goify(r.Name, true)} err := r.IterateActions(func(a *design.ActionDefinition) error { context := fmt.Sprintf("%s%sContext", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) unmarshal := fmt.Sprintf("unmarshal%s%sPayload", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) action := map[string]interface{}{ "Name": codegen.Goify(a.Name, true), "Routes": a.Routes, "Context": context, "Unmarshal": unmarshal, "Payload": a.Payload, } data.Actions = append(data.Actions, action) return nil }) if err != nil { return err } if len(data.Actions) > 0 { data.Version = version controllersData = append(controllersData, data) } return nil }) g.genfiles = append(g.genfiles, ctlFile) if err = ctlWr.Execute(controllersData); err != nil { return err } return ctlWr.FormatCode() }
// generateContexts iterates through the version resources and actions and generates the action // contexts. func (g *Generator) generateContexts(verdir string, api *design.APIDefinition, version *design.APIVersionDefinition) error { ctxFile := filepath.Join(verdir, "contexts.go") ctxWr, err := NewContextsWriter(ctxFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Contexts", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("fmt"), codegen.SimpleImport("strconv"), codegen.SimpleImport("strings"), codegen.SimpleImport("github.com/goadesign/goa"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } ctxWr.WriteHeader(title, packageName(version), imports) err = version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } return r.IterateActions(func(a *design.ActionDefinition) error { ctxName := codegen.Goify(a.Name, true) + codegen.Goify(a.Parent.Name, true) + "Context" ctxData := ContextTemplateData{ Name: ctxName, ResourceName: r.Name, ActionName: a.Name, Payload: a.Payload, Params: a.AllParams(), Headers: r.Headers.Merge(a.Headers), Routes: a.Routes, Responses: MergeResponses(r.Responses, a.Responses), API: api, Version: version, DefaultPkg: TargetPackage, } return ctxWr.Execute(&ctxData) }) }) g.genfiles = append(g.genfiles, ctxFile) if err != nil { return err } return ctxWr.FormatCode() }
// generateHrefs iterates through the API resources and generates the href factory methods. func (g *Generator) generateHrefs(api *design.APIDefinition) error { hrefFile := filepath.Join(AppOutputDir(), "hrefs.go") resWr, err := NewResourcesWriter(hrefFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Resource Href Factories", api.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("fmt"), } resWr.WriteHeader(title, TargetPackage, imports) err = api.IterateResources(func(r *design.ResourceDefinition) error { m := api.MediaTypeWithIdentifier(r.MediaType) var identifier string if m != nil { identifier = m.Identifier } else { identifier = "text/plain" } data := ResourceData{ Name: codegen.Goify(r.Name, true), Identifier: identifier, Description: r.Description, Type: m, CanonicalTemplate: codegen.CanonicalTemplate(r), CanonicalParams: codegen.CanonicalParams(r), } return resWr.Execute(&data) }) g.genfiles = append(g.genfiles, hrefFile) if err != nil { return err } return resWr.FormatCode() }
func generate(pkgName, pkgPath string, c *cobra.Command) ([]string, error) { m := make(map[string]string) c.Flags().Visit(func(f *pflag.Flag) { if f.Name != "pkg-path" { m[f.Name] = f.Value.String() } }) if _, ok := m["out"]; !ok { m["out"] = c.Flag("out").DefValue } // turn "out" into an absolute path var err error m["out"], err = filepath.Abs(m["out"]) if err != nil { return nil, err } gen, err := meta.NewGenerator( pkgName+".Generate", []*codegen.ImportSpec{codegen.SimpleImport(pkgPath)}, m, ) if err != nil { return nil, err } return gen.Generate() }
func (g *Generator) generateCommands(commandsFile string, clientPkg string, funcs template.FuncMap, api *design.APIDefinition) error { file, err := codegen.SourceFileFor(commandsFile) if err != nil { return err } commandTypesTmpl := template.Must(template.New("commandTypes").Funcs(funcs).Parse(commandTypesTmpl)) commandsTmpl := template.Must(template.New("commands").Funcs(funcs).Parse(commandsTmpl)) imports := []*codegen.ImportSpec{ codegen.SimpleImport("encoding/json"), codegen.SimpleImport("fmt"), codegen.SimpleImport(clientPkg), codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("github.com/spf13/cobra"), codegen.NewImport("log", "gopkg.in/inconshreveable/log15.v2"), } if err := file.WriteHeader("", "main", imports); err != nil { return err } g.genfiles = append(g.genfiles, commandsFile) file.Write([]byte("type (\n")) if err := api.IterateResources(func(res *design.ResourceDefinition) error { return res.IterateActions(func(action *design.ActionDefinition) error { return commandTypesTmpl.Execute(file, action) }) }); err != nil { return err } file.Write([]byte(")\n\n")) if err := api.IterateResources(func(res *design.ResourceDefinition) error { return res.IterateActions(func(action *design.ActionDefinition) error { data := map[string]interface{}{ "Action": action, "Resource": action.Parent, "Version": design.Design.APIVersionDefinition, } return commandsTmpl.Execute(file, data) }) }); err != nil { return err } return file.FormatCode() }
// generateUserTypes iterates through the user types and generates the data structures and // marshaling code. func (g *Generator) generateUserTypes(outdir string, api *design.APIDefinition) error { var modelname, filename string err := GormaDesign.IterateStores(func(store *RelationalStoreDefinition) error { err := store.IterateModels(func(model *RelationalModelDefinition) error { modelname = strings.ToLower(codegen.Goify(model.ModelName, false)) filename = fmt.Sprintf("%s.go", modelname) utFile := filepath.Join(outdir, filename) err := os.RemoveAll(utFile) if err != nil { fmt.Println(err) } utWr, err := NewUserTypesWriter(utFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Models", api.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport(g.appPkgPath), codegen.SimpleImport("time"), codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("github.com/jinzhu/gorm"), codegen.SimpleImport("golang.org/x/net/context"), codegen.SimpleImport("golang.org/x/net/context"), codegen.SimpleImport("github.com/goadesign/goa/uuid"), } if model.Cached { imp := codegen.NewImport("cache", "github.com/patrickmn/go-cache") imports = append(imports, imp) imp = codegen.SimpleImport("strconv") imports = append(imports, imp) } utWr.WriteHeader(title, g.target, imports) data := &UserTypeTemplateData{ APIDefinition: api, UserType: model, DefaultPkg: g.target, AppPkg: g.appPkgPath, } err = utWr.Execute(data) g.genfiles = append(g.genfiles, utFile) if err != nil { fmt.Println(err) return err } err = utWr.FormatCode() if err != nil { fmt.Println(err) } return err }) return err }) return err }
// Run simply calls the meta generator. func (c *Command) Run() ([]string, error) { gen := meta.NewGenerator( "genjs.Generate", []*codegen.ImportSpec{codegen.SimpleImport("github.com/goadesign/goa/goagen/gen_js")}, nil, ) return gen.Generate() }
// Run simply calls the meta generator. func (c *Command) Run() ([]string, error) { flags := map[string]string{"pkg": TargetPackage} gen := meta.NewGenerator( "genapp.Generate", []*codegen.ImportSpec{codegen.SimpleImport("github.com/goadesign/goa/goagen/gen_app")}, flags, ) return gen.Generate() }
// Run simply calls the meta generator. func (c *Command) Run() ([]string, error) { flags := map[string]string{"url": ServiceURL} gen := meta.NewGenerator( "genschema.Generate", []*codegen.ImportSpec{codegen.SimpleImport("github.com/goadesign/goa/goagen/gen_schema")}, flags, ) return gen.Generate() }
// Run simply calls the meta generator. func (c *Command) Run() ([]string, error) { flags := map[string]string{"name": AppName} gen := meta.NewGenerator( "genmain.Generate", []*codegen.ImportSpec{codegen.SimpleImport("github.com/goadesign/goa/goagen/gen_main")}, flags, ) return gen.Generate() }
func (g *Generator) generateMain(mainFile string, clientPkg string, funcs template.FuncMap, api *design.APIDefinition) error { imports := []*codegen.ImportSpec{ codegen.SimpleImport("encoding/json"), codegen.SimpleImport("fmt"), codegen.SimpleImport("io/ioutil"), codegen.SimpleImport("net/http"), codegen.SimpleImport("os"), codegen.SimpleImport("time"), codegen.SimpleImport(clientPkg), codegen.SimpleImport("github.com/spf13/cobra"), } for _, pkg := range SignerPackages { imports = append(imports, codegen.SimpleImport(pkg)) } file, err := codegen.SourceFileFor(mainFile) if err != nil { return err } if err := file.WriteHeader("", "main", imports); err != nil { return err } g.genfiles = append(g.genfiles, mainFile) data := map[string]interface{}{ "API": api, "Signers": Signers, "Version": Version, } if err := file.ExecuteTemplate("main", mainTmpl, nil, data); err != nil { return err } actions := make(map[string][]*design.ActionDefinition) api.IterateResources(func(res *design.ResourceDefinition) error { return res.IterateActions(func(action *design.ActionDefinition) error { if as, ok := actions[action.Name]; ok { actions[action.Name] = append(as, action) } else { actions[action.Name] = []*design.ActionDefinition{action} } return nil }) }) if err := file.ExecuteTemplate("registerCmds", registerCmdsT, nil, actions); err != nil { return err } return file.FormatCode() }
// generateContexts iterates through the API resources and actions and generates the action // contexts. func (g *Generator) generateContexts() error { ctxFile := filepath.Join(g.OutDir, "contexts.go") ctxWr, err := NewContextsWriter(ctxFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Contexts", g.API.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("fmt"), codegen.SimpleImport("golang.org/x/net/context"), codegen.SimpleImport("strconv"), codegen.SimpleImport("strings"), codegen.SimpleImport("time"), codegen.SimpleImport("unicode/utf8"), codegen.SimpleImport("github.com/goadesign/goa"), codegen.NewImport("uuid", "github.com/satori/go.uuid"), } g.genfiles = append(g.genfiles, ctxFile) ctxWr.WriteHeader(title, g.Target, imports) err = g.API.IterateResources(func(r *design.ResourceDefinition) error { return r.IterateActions(func(a *design.ActionDefinition) error { ctxName := codegen.Goify(a.Name, true) + codegen.Goify(a.Parent.Name, true) + "Context" headers := r.Headers.Merge(a.Headers) if headers != nil && len(headers.Type.ToObject()) == 0 { headers = nil // So that {{if .Headers}} returns false in templates } params := a.AllParams() if params != nil && len(params.Type.ToObject()) == 0 { params = nil // So that {{if .Params}} returns false in templates } non101 := make(map[string]*design.ResponseDefinition) for k, v := range a.Responses { if v.Status != 101 { non101[k] = v } } ctxData := ContextTemplateData{ Name: ctxName, ResourceName: r.Name, ActionName: a.Name, Payload: a.Payload, Params: params, Headers: headers, Routes: a.Routes, Responses: non101, API: g.API, DefaultPkg: g.Target, Security: a.Security, } return ctxWr.Execute(&ctxData) }) }) if err != nil { return err } return ctxWr.FormatCode() }
// generateMediaTypes iterates through the media types and generate the data structures and // marshaling code. func (g *Generator) generateMediaTypes(pkgDir string, funcs template.FuncMap) error { funcs["decodegotyperef"] = decodeGoTypeRef funcs["decodegotypename"] = decodeGoTypeName typeDecodeTmpl := template.Must(template.New("typeDecode").Funcs(funcs).Parse(typeDecodeTmpl)) mtFile := filepath.Join(pkgDir, "media_types.go") mtWr, err := genapp.NewMediaTypesWriter(mtFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Media Types", g.API.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("fmt"), codegen.SimpleImport("net/http"), codegen.SimpleImport("time"), codegen.SimpleImport("unicode/utf8"), codegen.NewImport("uuid", "github.com/goadesign/goa/uuid"), } mtWr.WriteHeader(title, g.Target, imports) err = g.API.IterateMediaTypes(func(mt *design.MediaTypeDefinition) error { if (mt.Type.IsObject() || mt.Type.IsArray()) && !mt.IsError() { if err := mtWr.Execute(mt); err != nil { return err } } err := mt.IterateViews(func(view *design.ViewDefinition) error { p, _, err := mt.Project(view.Name) if err != nil { return err } if err := typeDecodeTmpl.Execute(mtWr.SourceFile, p); err != nil { return err } return nil }) return err }) g.genfiles = append(g.genfiles, mtFile) if err != nil { return err } return mtWr.FormatCode() }
// Generate produces the skeleton main. func (g *Generator) Generate(api *design.APIDefinition) (_ []string, err error) { go utils.Catch(nil, func() { g.Cleanup() }) defer func() { if err != nil { g.Cleanup() } }() os.RemoveAll(JSONSchemaDir()) os.MkdirAll(JSONSchemaDir(), 0755) g.genfiles = append(g.genfiles, JSONSchemaDir()) s := APISchema(api) js, err := s.JSON() if err != nil { return } schemaFile := filepath.Join(JSONSchemaDir(), "schema.json") if err = ioutil.WriteFile(schemaFile, js, 0644); err != nil { return } g.genfiles = append(g.genfiles, schemaFile) controllerFile := filepath.Join(JSONSchemaDir(), "schema.go") file, err := codegen.SourceFileFor(controllerFile) if err != nil { return } imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/julienschmidt/httprouter"), codegen.SimpleImport("github.com/goadesign/goa"), } g.genfiles = append(g.genfiles, controllerFile) file.WriteHeader(fmt.Sprintf("%s JSON Hyper-schema", api.Name), "schema", imports) file.Write([]byte(jsonSchemaCtrl)) if err = file.FormatCode(); err != nil { return } return g.genfiles, nil }
// Generate produces the skeleton main. func (g *Generator) Generate(api *design.APIDefinition) (_ []string, err error) { var genfiles []string cleanup := func() { for _, f := range genfiles { os.Remove(f) } } go utils.Catch(nil, cleanup) defer func() { if err != nil { cleanup() } }() s, err := New(api) if err != nil { return } b, err := json.Marshal(s) if err != nil { return } swaggerDir := filepath.Join(codegen.OutputDir, "swagger") os.RemoveAll(swaggerDir) if err = os.MkdirAll(swaggerDir, 0755); err != nil { return } genfiles = append(genfiles, swaggerDir) swaggerFile := filepath.Join(swaggerDir, "swagger.json") err = ioutil.WriteFile(swaggerFile, b, 0644) if err != nil { return } genfiles = append(genfiles, swaggerFile) controllerFile := filepath.Join(swaggerDir, "swagger.go") genfiles = append(genfiles, controllerFile) file, err := codegen.SourceFileFor(controllerFile) if err != nil { return } imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), } file.WriteHeader(fmt.Sprintf("%s Swagger Spec", api.Name), "swagger", imports) file.Write([]byte(swagger)) if err = file.FormatCode(); err != nil { return } return genfiles, nil }
// Run simply calls the meta generator. func (c *Command) Run() ([]string, error) { if GenPkgName == "" { GenPkgName = filepath.ToSlash(filepath.Base(GenPkgPath)) } gen := meta.NewGenerator( fmt.Sprintf("%s.Generate", GenPkgName), []*codegen.ImportSpec{codegen.SimpleImport(GenPkgPath)}, nil, ) return gen.Generate() }
// generateUserTypes iterates through the user types and generates the data structures and // marshaling code. func (g *Generator) generateUserTypes(api *design.APIDefinition) error { utFile := filepath.Join(AppOutputDir(), "user_types.go") utWr, err := NewUserTypesWriter(utFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application User Types", api.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("fmt"), codegen.SimpleImport("time"), } utWr.WriteHeader(title, TargetPackage, imports) err = api.IterateUserTypes(func(t *design.UserTypeDefinition) error { return utWr.Execute(t) }) g.genfiles = append(g.genfiles, utFile) if err != nil { return err } return utWr.FormatCode() }
// generateUserTypes iterates through the user types and generates the data structures and // marshaling code. func (g *Generator) generateUserTypes(pkgDir string) error { utFile := filepath.Join(pkgDir, "user_types.go") utWr, err := genapp.NewUserTypesWriter(utFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application User Types", g.API.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("fmt"), codegen.SimpleImport("time"), codegen.SimpleImport("unicode/utf8"), } utWr.WriteHeader(title, g.Target, imports) err = g.API.IterateUserTypes(func(t *design.UserTypeDefinition) error { return utWr.Execute(t) }) g.genfiles = append(g.genfiles, utFile) if err != nil { return err } return utWr.FormatCode() }
func (g *Generator) generateClient(clientFile string, clientPkg string, funcs template.FuncMap, api *design.APIDefinition) error { file, err := codegen.SourceFileFor(clientFile) if err != nil { return err } clientTmpl := template.Must(template.New("client").Funcs(funcs).Parse(clientTmpl)) imports := []*codegen.ImportSpec{ codegen.SimpleImport("net/http"), codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("github.com/spf13/cobra"), } if err := file.WriteHeader("", "client", imports); err != nil { return err } g.genfiles = append(g.genfiles, clientFile) if err := clientTmpl.Execute(file, api); err != nil { return err } return file.FormatCode() }
func (g *Generator) generateExample(api *design.APIDefinition) error { controllerFile := filepath.Join(codegen.OutputDir, "example.go") file, err := codegen.SourceFileFor(controllerFile) if err != nil { return err } imports := []*codegen.ImportSpec{ codegen.SimpleImport("net/http"), codegen.SimpleImport("github.com/julienschmidt/httprouter"), codegen.SimpleImport("github.com/goadesign/goa"), } if err := file.WriteHeader(fmt.Sprintf("%s JavaScript Client Example", api.Name), "js", imports); err != nil { return err } g.genfiles = append(g.genfiles, controllerFile) data := map[string]interface{}{"ServeDir": codegen.OutputDir} if err := file.ExecuteTemplate("examples", exampleCtrlT, nil, data); err != nil { return err } return file.FormatCode() }
// generateHrefs iterates through the version resources and generates the href factory methods. func (g *Generator) generateHrefs(verdir string, version *design.APIVersionDefinition) error { hrefFile := filepath.Join(verdir, "hrefs.go") resWr, err := NewResourcesWriter(hrefFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Resource Href Factories", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("fmt"), } resWr.WriteHeader(title, packageName(version), imports) err = version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } m := design.Design.MediaTypeWithIdentifier(r.MediaType) var identifier string if m != nil { identifier = m.Identifier } else { identifier = "plain/text" } canoTemplate := r.URITemplate(version) canoTemplate = design.WildcardRegex.ReplaceAllLiteralString(canoTemplate, "/%v") var canoParams []string if ca := r.CanonicalAction(); ca != nil { if len(ca.Routes) > 0 { canoParams = ca.Routes[0].Params(version) } } data := ResourceData{ Name: codegen.Goify(r.Name, true), Identifier: identifier, Description: r.Description, Type: m, CanonicalTemplate: canoTemplate, CanonicalParams: canoParams, } return resWr.Execute(&data) }) g.genfiles = append(g.genfiles, hrefFile) if err != nil { return err } return resWr.FormatCode() }
// generateContexts iterates through the API resources and actions and generates the action // contexts. func (g *Generator) generateContexts(api *design.APIDefinition) error { ctxFile := filepath.Join(AppOutputDir(), "contexts.go") ctxWr, err := NewContextsWriter(ctxFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Contexts", api.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("fmt"), codegen.SimpleImport("golang.org/x/net/context"), codegen.SimpleImport("strconv"), codegen.SimpleImport("strings"), codegen.SimpleImport("time"), codegen.SimpleImport("github.com/goadesign/goa"), codegen.NewImport("uuid", "github.com/satori/go.uuid"), } ctxWr.WriteHeader(title, TargetPackage, imports) err = api.IterateResources(func(r *design.ResourceDefinition) error { return r.IterateActions(func(a *design.ActionDefinition) error { ctxName := codegen.Goify(a.Name, true) + codegen.Goify(a.Parent.Name, true) + "Context" headers := r.Headers.Merge(a.Headers) if headers != nil && len(headers.Type.ToObject()) == 0 { headers = nil // So that {{if .Headers}} returns false in templates } params := a.AllParams() if params != nil && len(params.Type.ToObject()) == 0 { params = nil // So that {{if .Params}} returns false in templates } ctxData := ContextTemplateData{ Name: ctxName, ResourceName: r.Name, ActionName: a.Name, Payload: a.Payload, Params: params, Headers: headers, Routes: a.Routes, Responses: BuildResponses(r.Responses, a.Responses), API: api, DefaultPkg: TargetPackage, Security: a.Security, } return ctxWr.Execute(&ctxData) }) }) g.genfiles = append(g.genfiles, ctxFile) if err != nil { return err } return ctxWr.FormatCode() }