// Generate the application code, implement codegen.Generator. func (g *Generator) Generate(api *design.APIDefinition) (_ []string, err error) { if api == nil { return nil, fmt.Errorf("missing API definition, make sure design.Design is properly initialized") } go utils.Catch(nil, func() { g.Cleanup() }) defer func() { if err != nil { g.Cleanup() } }() outdir := AppOutputDir() err = api.IterateVersions(func(v *design.APIVersionDefinition) error { verdir := outdir if v.Version != "" { verdir = filepath.Join(verdir, codegen.VersionPackage(v.Version)) } if err := os.MkdirAll(verdir, 0755); err != nil { return err } if err := g.generateContexts(verdir, api, v); err != nil { return err } if err := g.generateControllers(verdir, v); err != nil { return err } if err := g.generateHrefs(verdir, v); err != nil { return err } if err := g.generateMediaTypes(verdir, v); err != nil { return err } if err := g.generateUserTypes(verdir, v); err != nil { return err } return nil }) if err != nil { return nil, err } return g.genfiles, nil }
// 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() } }() mainFile := filepath.Join(codegen.OutputDir, "main.go") if Force { os.Remove(mainFile) } g.genfiles = append(g.genfiles, mainFile) _, err = os.Stat(mainFile) funcs := template.FuncMap{ "tempvar": tempvar, "generateSwagger": generateSwagger, "okResp": okResp, "newControllerVersion": newControllerVersion, "targetPkg": func() string { return TargetPackage }, } if err != nil { file, err := codegen.SourceFileFor(mainFile) if err != nil { return nil, err } var outPkg string outPkg, err = codegen.PackagePath(codegen.OutputDir) if err != nil { return nil, err } outPkg = strings.TrimPrefix(filepath.ToSlash(outPkg), "src/") appPkg := path.Join(outPkg, "app") swaggerPkg := path.Join(outPkg, "swagger") imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("github.com/goadesign/middleware"), codegen.SimpleImport(appPkg), codegen.SimpleImport(swaggerPkg), } if generateSwagger() { jsonSchemaPkg := path.Join(outPkg, "schema") imports = append(imports, codegen.SimpleImport(jsonSchemaPkg)) } file.WriteHeader("", "main", imports) data := map[string]interface{}{ "Name": AppName, "API": api, } if err = file.ExecuteTemplate("main", mainT, funcs, data); err != nil { return nil, err } if err = file.FormatCode(); err != nil { return nil, err } } imp, err := codegen.PackagePath(codegen.OutputDir) if err != nil { return } imp = path.Join(filepath.ToSlash(imp), "app") imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport(imp), } api.IterateVersions(func(v *design.APIVersionDefinition) error { if v.IsDefault() { return nil } imports = append(imports, codegen.SimpleImport(imp+"/"+codegen.VersionPackage(v.Version))) return nil }) err = api.IterateResources(func(r *design.ResourceDefinition) error { filename := filepath.Join(codegen.OutputDir, snakeCase(r.Name)+".go") if Force { if err := os.Remove(filename); err != nil { return err } } g.genfiles = append(g.genfiles, filename) if _, err := os.Stat(filename); err != nil { file, err := codegen.SourceFileFor(filename) if err != nil { return err } file.WriteHeader("", "main", imports) err = file.ExecuteTemplate("controller", ctrlT, funcs, r) if err != nil { return err } if err := file.FormatCode(); err != nil { return err } } return nil }) if err != nil { return } return g.genfiles, nil }
// generateUserTypes iterates through the user types and generates the data structures and // marshaling code. func (g *Generator) generateUserTypes(outdir string, api *design.APIDefinition) error { err := api.IterateVersions(func(version *design.APIVersionDefinition) error { if version.Version != "" { return nil } var modelname, filename string err := GormaDesign.IterateStores(func(store *RelationalStoreDefinition) error { err := store.IterateModels(func(model *RelationalModelDefinition) error { modelname = strings.ToLower(codegen.Goify(model.Name, false)) filename = fmt.Sprintf("%s_gen.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", version.Context()) ap, err := AppPackagePath() if err != nil { panic(err) } imports := []*codegen.ImportSpec{ codegen.SimpleImport(ap), codegen.SimpleImport("github.com/jinzhu/gorm"), codegen.SimpleImport("golang.org/x/net/context"), } needDate := false for _, field := range model.RelationalFields { if field.Datatype == Timestamp || field.Datatype == NullableTimestamp { needDate = true } } if needDate { imp := codegen.SimpleImport("time") imports = append(imports, imp) } utWr.WriteHeader(title, "genmodels", imports) data := &UserTypeTemplateData{ APIDefinition: api, UserType: model, DefaultPkg: TargetPackage, AppPkg: AppPackage, } 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 }) return err }