func main() { var ( files []string err error terminatedByUser bool ) // Now proceed with code generation cleanup := func() { for _, f := range files { os.RemoveAll(f) } } go utils.Catch(nil, func() { terminatedByUser = true }) for _, command := range Commands { run := command.Run sub := &cobra.Command{ Use: command.Name(), Short: command.Description(), Run: func(cmd *cobra.Command, args []string) { codegen.ExtraFlags = args files, err = run() }, } command.RegisterFlags(sub) codegen.RegisterFlags(sub) RootCmd.AddCommand(sub) } codegen.RegisterFlags(RootCmd) RootCmd.Execute() if terminatedByUser { cleanup() return } if err != nil { cleanup() fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) } rels := make([]string, len(files)) cwd, err := os.Getwd() for i, f := range files { r, err := filepath.Rel(cwd, f) if err == nil { rels[i] = r } else { rels[i] = f } } fmt.Println(strings.Join(rels, "\n")) }
// NewGenerator returns the application code generator. func NewGenerator() (*Generator, error) { app := kingpin.New("Main generator", "application main generator") codegen.RegisterFlags(app) NewCommand().RegisterFlags(app) _, err := app.Parse(os.Args[1:]) if err != nil { return nil, fmt.Errorf(`invalid command line: %s. Command line was "%s"`, err, strings.Join(os.Args, " ")) } return new(Generator), nil }
// Generate is the generator entry point called by the meta generator. func Generate(api *design.APIDefinition) (files []string, err error) { g := new(Generator) root := &cobra.Command{ Use: "goagen", Short: "Main generator", Long: "application main generator", Run: func(*cobra.Command, []string) { files, err = g.Generate(api) }, } codegen.RegisterFlags(root) NewCommand().RegisterFlags(root) root.Execute() return }
// Generate is the generator entry point called by the meta generator. func Generate(roots []interface{}) (files []string, err error) { api := roots[0].(*design.APIDefinition) g := new(Generator) root := &cobra.Command{ Use: "goagen", Short: "Client generator", Long: "client tool and package generator", Run: func(*cobra.Command, []string) { files, err = g.Generate(api) }, } codegen.RegisterFlags(root) NewCommand().RegisterFlags(root) root.Execute() return }
// Generate is the generator entry point called by the meta generator. func Generate() (files []string, err error) { api := design.Design if err != nil { return nil, err } g := new(Generator) root := &cobra.Command{ Use: "goagen", Short: "Client generator", Long: "client tool and package generator", Run: func(*cobra.Command, []string) { files, err = g.Generate(api) }, } codegen.RegisterFlags(root) NewCommand().RegisterFlags(root) root.Execute() return }
// NewGenerator returns the application code generator. func NewGenerator() (*Generator, error) { app := kingpin.New("Code generator", "application code generator") codegen.RegisterFlags(app) NewCommand().RegisterFlags(app) _, err := app.Parse(os.Args[1:]) if err != nil { return nil, fmt.Errorf(`invalid command line: %s. Command line was "%s"`, err, strings.Join(os.Args, " ")) } outdir := AppOutputDir() os.RemoveAll(outdir) if err = os.MkdirAll(outdir, 0777); err != nil { return nil, err } return &Generator{ genfiles: []string{outdir}, }, nil }
// Generate is the generator entry point called by the meta generator. func Generate(api *design.APIDefinition) (files []string, err error) { g := new(Generator) root := &cobra.Command{ Use: "goagen", Short: "Code generator", Long: "application code generator", PreRunE: func(*cobra.Command, []string) error { outdir := AppOutputDir() os.RemoveAll(outdir) g.genfiles = []string{outdir} err = os.MkdirAll(outdir, 0777) return err }, Run: func(*cobra.Command, []string) { files, err = g.Generate(api) }, } codegen.RegisterFlags(root) NewCommand().RegisterFlags(root) root.Execute() return }
// command parses the command line and returns the specified sub-command. func command() codegen.Command { app := kingpin.New("goagen", "goa code generation tool") app.Version(codegen.Version) app.Help = help codegen.RegisterFlags(app) for _, c := range Commands { cmd := app.Command(c.Name(), c.Description()) c.RegisterFlags(cmd) } if os.Args[len(os.Args)-1] == "--help" { args := append([]string{os.Args[0], "help"}, os.Args[1:len(os.Args)-1]...) os.Args = args } codegen.CommandName = kingpin.MustParse(app.Parse(os.Args[1:])) for _, c := range Commands { if codegen.CommandName == c.Name() { return c } } app.Usage(os.Args[1:]) os.Exit(1) return nil }
func main() { var ( files []string err error terminatedByUser bool // RootCmd is the base command used when goagen is called with no argument. RootCmd = &cobra.Command{ Use: "goagen", Short: "goa code generation tool", Long: `The goagen tool generates various artifacts from a goa service design package. Each command supported by the tool produces a specific type of artifacts. For example the "app" command generates the code that supports the service controllers. The "bootstrap" command runs the "app", "main", "client" and "swagger" commands generating the controllers supporting code and main skeleton code (if not already present) as well as a client package and tool and the Swagger specification for the API. `} ) // Now proceed with code generation cleanup := func() { for _, f := range files { os.RemoveAll(f) } } go utils.Catch(nil, func() { terminatedByUser = true }) for _, command := range Commands { run := command.Run sub := &cobra.Command{ Use: command.Name(), Short: command.Description(), Run: func(cmd *cobra.Command, args []string) { codegen.ExtraFlags = args files, err = run() }, } command.RegisterFlags(sub) codegen.RegisterFlags(sub) RootCmd.AddCommand(sub) } codegen.RegisterFlags(RootCmd) RootCmd.Execute() if terminatedByUser { cleanup() return } if err != nil { cleanup() fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) } rels := make([]string, len(files)) cwd, err := os.Getwd() for i, f := range files { r, err := filepath.Rel(cwd, f) if err == nil { rels[i] = r } else { rels[i] = f } } fmt.Println(strings.Join(rels, "\n")) }
}) }) Context("with command line flags", func() { var kapp *kingpin.Application var cmd *kingpin.CmdClause const flagVal = "testme" var args []string var parsedCmd string BeforeEach(func() { kapp = kingpin.New("test", "test") cmd = kapp.Command("testCmd", "testCmd") args = []string{testCmd, "-o" + flagVal, "-d=design", "--pkg=dummy"} }) JustBeforeEach(func() { codegen.RegisterFlags(cmd) appCmd.RegisterFlags(cmd) var err error parsedCmd, err = kapp.Parse(args) Ω(err).ShouldNot(HaveOccurred()) }) It("parses the default flags", func() { Ω(parsedCmd).Should(Equal(testCmd)) Ω(codegen.OutputDir).Should(Equal(flagVal)) }) }) })
// Generate is the generator entry point called by the meta generator. func 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() } }() app := kingpin.New("Swagger generator", "Swagger spec generator") codegen.RegisterFlags(app) _, err = app.Parse(os.Args[1:]) if err != nil { return nil, fmt.Errorf(`invalid command line: %s. Command line was "%s"`, err, strings.Join(os.Args, " ")) } 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/julienschmidt/httprouter"), 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 }
It("registers the required flags", func() { f := root.Flags().Lookup("pkg") Ω(f).ShouldNot(BeNil()) }) }) Context("with command line flags", func() { var root *cobra.Command const flagVal = "testme" var args []string BeforeEach(func() { root = &cobra.Command{Use: "testCmd"} args = []string{os.Args[0], testCmd, "-o" + flagVal, "-d=design", "--pkg=dummy"} }) JustBeforeEach(func() { codegen.RegisterFlags(root) appCmd.RegisterFlags(root) os.Args = args }) It("parses the default flags", func() { err := root.Execute() Ω(err).ShouldNot(HaveOccurred()) Ω(codegen.OutputDir).Should(Equal(flagVal)) }) }) })