// allow invocation from test func MainArgs(args []string) { //fmt.Println(os.Args) os.Args = args flag.Usage = use if len(os.Args) < 2 { use() } flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError) debug := flag.Bool("debug", false, "print lots of debug info as we process.") outdir := flag.String("o", "odir", "specify output directory") pkg := flag.String("p", "main", "specify package for generated code") privs := flag.Bool("X", false, "export private as well as public struct fields") overwrite := flag.Bool("OVERWRITE", false, "replace named .go files with capid tagged versions.") flag.Parse() if debug != nil { bam.Verbose = *debug } if outdir == nil || *outdir == "" { fmt.Fprintf(os.Stderr, "required -o option missing. Use bambam -o <dirname> myfile.go # to specify the output directory.\n") use() } if !bam.DirExists(*outdir) { err := os.MkdirAll(*outdir, 0755) if err != nil { panic(err) } } if pkg == nil || *pkg == "" { fmt.Fprintf(os.Stderr, "required -p option missing. Specify a package name for the generated go code with -p <pkgname>\n") use() } // all the rest are input .go files inputFiles := flag.Args() if len(inputFiles) == 0 { fmt.Fprintf(os.Stderr, "bambam needs at least one .go golang source file to process specified on the command line.\n") os.Exit(1) } for _, fn := range inputFiles { if !strings.HasSuffix(fn, ".go") && !strings.HasSuffix(fn, ".go.txt") { fmt.Fprintf(os.Stderr, "error: bambam input file '%s' did not end in '.go' or '.go.txt'.\n", fn) os.Exit(1) } } x := bam.NewExtractor() x.FieldPrefix = " " x.FieldSuffix = "\n" x.OutDir = *outdir if privs != nil { x.ExtractPrivate = *privs } if overwrite != nil { x.Overwrite = *overwrite } for _, inFile := range inputFiles { _, err := x.ExtractStructsFromOneFile(nil, inFile) if err != nil { panic(err) } } // get rid of default tmp dir x.CompileDir = bam.NewTempDir() x.CompileDir.Cleanup() x.CompileDir.DirPath = *outdir x.PkgName = *pkg schemaFN := x.CompileDir.DirPath + "/schema.capnp" schemaFile, err := os.Create(schemaFN) if err != nil { panic(err) } defer schemaFile.Close() by := x.GenCapnpHeader() schemaFile.Write(by.Bytes()) _, err = x.WriteToSchema(schemaFile) if err != nil { panic(err) } fmt.Fprintf(schemaFile, "\n") fmt.Fprintf(schemaFile, "##compile with:\n\n##\n##\n## capnp compile -ogo %s\n\n", schemaFN) // translator library of go functions is separate from the schema translateFn := x.CompileDir.DirPath + "/translateCapn.go" translatorFile, err := os.Create(translateFn) if err != nil { panic(err) } defer translatorFile.Close() fmt.Fprintf(translatorFile, `package %s import ( capn "github.com/glycerine/go-capnproto" "io" ) `, x.PkgName) _, err = x.WriteToTranslators(translatorFile) if err != nil { panic(err) } err = x.CopySourceFilesAddCapidTag() if err != nil { panic(err) } exec.Command("cp", "-p", "go.capnp", x.CompileDir.DirPath).Run() fmt.Printf("generated files in '%s'\n", x.CompileDir.DirPath) }
func main() { flag.Parse() flag.Usage = use if *source == "" { use() } source := *source sourceName := strings.TrimSuffix(source, ".capnp") pkg, err := build.Import(SELF_PKG_NAME, "./", build.FindOnly) if err != nil { fmt.Println("Failed to detect self package location:", err) os.Exit(1) } capsSchemaPath := fmt.Sprintf("-I%s/..", pkg.Dir) goSchemaPath := fmt.Sprintf("-I%s/vendor/github.com/glycerine/go-capnproto", pkg.Dir) capnpArgs := []string{capsSchemaPath, goSchemaPath, "compile", "-opgo"} sourceData, err := ioutil.ReadFile(source) if err != nil { fmt.Println("Failed to read schema file:", err) os.Exit(1) } sourceContent := string(sourceData) // Remove comments re := regexp.MustCompile("(?s)#.*?\n") cleanContent := re.ReplaceAllString(sourceContent, "\n") // Find codec annotations capnpGen := capnpRe.MatchString(cleanContent) msgpGen := msgpRe.MatchString(cleanContent) if capnpGen { capnpArgs = append(capnpArgs, "-ogo") } if *outdir != "." { if !bam.DirExists(*outdir) { err := os.MkdirAll(*outdir, 0755) if err != nil { fmt.Println("Failed to create output dir:", err) os.Exit(1) } } for i := 0; i < len(capnpArgs); i++ { capnpArgs[i] += *outdir } } capnpArgs = append(capnpArgs, source) // Generate plain Go code cmd := exec.Command("capnp", capnpArgs...) cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout if *verbose { fmt.Printf("Executing: %q\n", strings.Join(cmd.Args, " ")) } err = cmd.Run() if err != nil { fmt.Println("Failed to run Plain go code generator:", err) os.Exit(1) } // Generate Msgp code if msgpGen { inFilename := filepath.Join(*outdir, sourceName+".go") outFilename := filepath.Join(*outdir, sourceName+".msgp.go") cmd = exec.Command("msgp", "-o="+outFilename, "-tests=false", "-file="+inFilename) cmd.Stderr = os.Stderr if *verbose { cmd.Stdout = os.Stdout fmt.Printf("Executing: %q\n", strings.Join(cmd.Args, " ")) } err = cmd.Run() if err != nil { fmt.Println("Failed to run Msgp go code generator:", err) os.Exit(1) } } }