Exemple #1
0
// 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)
}
Exemple #2
0
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)
		}
	}
}