func Init(srcdir string, include []string) { srcroot = srcdir includes = include if global.GetString("-lib") != "" { libroot = global.GetString("-lib") } else { libroot = srcroot } InitBackend() }
func InitBackend() { switch global.GetString("-backend") { case "gcc", "gccgo": gcc() case "gc": gc() case "express": express() default: log.Fatalf("[ERROR] '%s' unknown backend\n", global.GetString("-backend")) } }
func FormatFiles(files []string) { var i int var argv []string var tabWidth string = "-tabwidth=4" var useTabs string = "-tabindent=false" var rewRule string = global.GetString("-rew-rule") var fmtexec string var err os.Error fmtexec, err = exec.LookPath("gofmt") if err != nil { log.Fatal("[ERROR] could not find 'gofmt' in $PATH") } if global.GetString("-tabwidth") != "" { tabWidth = "-tabwidth=" + global.GetString("-tabwidth") } if global.GetBool("-tab") { useTabs = "-tabindent=true" } argv = make([]string, 0) argv = append(argv, fmtexec) argv = append(argv, "-w=true") argv = append(argv, tabWidth) argv = append(argv, useTabs) if rewRule != "" { argv = append(argv, fmt.Sprintf("-r='%s'", rewRule)) } argv = append(argv, "") // dummy i = len(argv) - 1 for y := 0; y < len(files); y++ { argv[i] = files[y] if global.GetBool("-dryrun") { argv[0] = filepath.Base(argv[0]) fmt.Printf(" %s\n", strings.Join(argv, " ")) } else { say.Printf("gofmt: %s\n", files[y]) _ = handy.StdExecve(argv, true) } } }
func CreateArgv(pkgs []*dag.Package) { var argv []string includeLen := len(includes) for y := 0; y < len(pkgs); y++ { argv = make([]string, 0) argv = append(argv, pathCompiler) argv = append(argv, "-I") argv = append(argv, libroot) for y := 0; y < includeLen; y++ { argv = append(argv, "-I") argv = append(argv, includes[y]) } switch global.GetString("-backend") { case "gcc", "gccgo": argv = append(argv, "-c") } argv = append(argv, "-o") argv = append(argv, filepath.Join(libroot, pkgs[y].Name)+suffix) for z := 0; z < len(pkgs[y].Files); z++ { argv = append(argv, pkgs[y].Files[z]) } pkgs[y].Argv = argv } }
// ignore GOROOT for gccgo and express func gotRoot() { if global.GetString("-backend") == "gc" { if os.Getenv("GOROOT") == "" { log.Fatal("[ERROR] missing GOROOT\n") } } }
func CreateTestArgv() []string { pwd, e := os.Getwd() if e != nil { log.Fatal("[ERROR] could not locate working directory\n") } argv := make([]string, 0) if global.GetString("-backend") == "express" { vmrun, e := exec.LookPath("vmrun") if e != nil { log.Fatalf("[ERROR] %s\n", e) } argv = append(argv, vmrun) } argv = append(argv, filepath.Join(pwd, global.GetString("-test-bin"))) if global.GetString("-bench") != "" { argv = append(argv, "-test.bench") argv = append(argv, global.GetString("-bench")) } if global.GetString("-match") != "" { argv = append(argv, "-test.run") argv = append(argv, global.GetString("-match")) } if global.GetBool("-verbose") { argv = append(argv, "-test.v") } return argv }
func Init(srcdir string, include []string) { srcroot = srcdir includes = include if global.GetString("-lib") != "" { libroot = global.GetString("-lib") } else { libroot = srcroot } switch global.GetString("-backend") { case "gcc", "gccgo": gcc() case "gc": gc() case "express": express() default: log.Fatalf("[ERROR] '%s' unknown backend\n", global.GetString("-backend")) } }
func printListing() { fmt.Println("\n Listing of options and their content:\n") defer fmt.Println("") for i := 0; i < len(bools); i++ { fmt.Printf(" %-20s => %v\n", bools[i], global.GetBool(bools[i])) } for i := 0; i < len(strs); i++ { fmt.Printf(" %-20s => %v\n", strs[i], global.GetString(strs[i])) } fmt.Printf(" %-20s => %v\n", "-lib", includes) }
func DeleteObjects(dir string, pkgs []*dag.Package) { var stub, tmp string suffixes := []string{".8", ".6", ".5", ".o", ".vmo"} libdir := global.GetString("-lib") if libdir != "" { dir = libdir } for i := 0; i < len(pkgs); i++ { stub = filepath.Join(dir, pkgs[i].Name) for j := 0; j < len(suffixes); j++ { tmp = stub + suffixes[j] if handy.IsFile(tmp) { if global.GetBool("-dryrun") { say.Printf("[dryrun] rm: %s\n", tmp) } else { say.Printf("rm: %s\n", tmp) handy.Delete(tmp, false) } } } } // remove entire dir if empty after objects are deleted. // only do this if -lib is present, there is no reason to // do this (extra treewalk) if objects are in src directory if libdir != "" && handy.IsDir(dir) { walker.IncludeFile = func(s string) bool { return true } walker.IncludeDir = func(s string) bool { return true } if len(walker.PathWalk(dir)) == 0 { if global.GetBool("-dryrun") { fmt.Printf("[dryrun] rm: %s\n", dir) } else { say.Printf("rm: %s\n", dir) handy.RmRf(dir, true) // die on error } } } }
func mainChoice(pkgs []*dag.Package) int { var cnt int var choice int for i := 0; i < len(pkgs); i++ { ok, _ := regexp.MatchString(global.GetString("-main"), pkgs[i].Name) if ok { cnt++ choice = i } } if cnt == 1 { return choice } fmt.Println("\n More than one main package found\n") for i := 0; i < len(pkgs); i++ { fmt.Printf(" type %2d for: %s\n", i, pkgs[i].Name) } fmt.Printf("\n type your choice: ") n, e := fmt.Scanf("%d", &choice) if e != nil { log.Fatalf("%s\n", e) } if n != 1 { log.Fatal("failed to read input\n") } if choice >= len(pkgs) || choice < 0 { log.Fatalf(" bad choice: %d\n", choice) } fmt.Printf(" chosen main-package: %s\n\n", pkgs[choice].Name) return choice }
func ForkLink(output string, pkgs []*dag.Package, extra []*dag.Package, up2date bool) { var mainPKG *dag.Package gotMain := make([]*dag.Package, 0) for i := 0; i < len(pkgs); i++ { if pkgs[i].ShortName == "main" { gotMain = append(gotMain, pkgs[i]) } } if len(gotMain) == 0 { log.Fatal("[ERROR] (linking) no main package found\n") } if len(gotMain) > 1 { choice := mainChoice(gotMain) mainPKG = gotMain[choice] } else { mainPKG = gotMain[0] } compiled := filepath.Join(libroot, mainPKG.Name) + suffix if up2date && !global.GetBool("-dryrun") && handy.IsFile(output) { if handy.ModifyTimestamp(compiled) < handy.ModifyTimestamp(output) { say.Printf("up 2 date: %s\n", output) return } } argv := make([]string, 0) argv = append(argv, pathLinker) switch global.GetString("-backend") { case "gc", "express": argv = append(argv, "-L") argv = append(argv, libroot) } argv = append(argv, "-o") argv = append(argv, output) // gcc get's this no matter what... if global.GetString("-backend") == "gcc" || global.GetString("-backend") == "gccgo" { argv = append(argv, "-static") } else if global.GetBool("-static") { argv = append(argv, "-d") } switch global.GetString("-backend") { case "gccgo", "gcc": walker.IncludeFile = func(s string) bool { return strings.HasSuffix(s, ".o") } walker.IncludeDir = func(s string) bool { return true } for y := 0; y < len(includes); y++ { argv = append(argv, walker.PathWalk(includes[y])...) } case "gc", "express": for y := 0; y < len(includes); y++ { argv = append(argv, "-L") argv = append(argv, includes[y]) } } argv = append(argv, compiled) if global.GetString("-backend") == "gcc" || global.GetString("-backend") == "gccgo" { ss := stringset.New() if len(extra) > 0 { for j := 0; j < len(extra); j++ { // main package untestable using GCC if extra[j].ShortName != "main" { ss.Add(filepath.Join(libroot, extra[j].Name) + suffix) } } } else { for k := 0; k < len(pkgs); k++ { ss.Add(filepath.Join(libroot, pkgs[k].Name) + suffix) } ss.Remove(compiled) } if ss.Len() > 0 { argv = append(argv, ss.Slice()...) } } if global.GetBool("-dryrun") { linker := filepath.Base(pathLinker) fmt.Printf("%s %s || exit 1\n", linker, strings.Join(argv[1:], " ")) } else { say.Println("linking :", output) handy.StdExecve(argv, true) } }
func (d Dag) MakeMainTest(root string) ([]*Package, string, string) { var max, i int var isTest bool var lname, sname, tmplib, tmpdir, tmpstub, tmpfile string sbImports := stringbuffer.NewSize(300) imprtSet := stringset.New() sbTests := stringbuffer.NewSize(1000) sbBench := stringbuffer.NewSize(1000) sbImports.Add("\n// autogenerated code\n\n") sbImports.Add("package main\n\n") imprtSet.Add("import \"regexp\"\n") imprtSet.Add("import \"testing\"\n") sbTests.Add("\n\nvar tests = []testing.InternalTest{\n") sbBench.Add("\n\nvar benchmarks = []testing.InternalBenchmark{\n") for _, v := range d { isTest = false sname = v.ShortName lname = v.ShortName max = len(v.ShortName) if max > 5 && sname[max-5:] == "_test" { collector := newTestCollector() for i = 0; i < len(v.Files); i++ { tree := getSyntaxTreeOrDie(v.Files[i], 0) ast.Walk(collector, tree) } if len(collector.Names) > 0 { isTest = true if hasSlash(v.Name) { lname = removeSlashAndDot(v.Name) imprtSet.Add(fmt.Sprintf("import %s \"%s\"\n", lname, v.Name)) } else { imprtSet.Add(fmt.Sprintf("import \"%s\"\n", v.Name)) } for i = 0; i < len(collector.Names); i++ { testFunc := collector.Names[i] if len(testFunc) >= 4 && testFunc[0:4] == "Test" { sbTests.Add(fmt.Sprintf("testing.InternalTest{\"%s.%s\", %s.%s },\n", sname, testFunc, lname, testFunc)) } else if len(testFunc) >= 9 && testFunc[0:9] == "Benchmark" { sbBench.Add(fmt.Sprintf("testing.InternalBenchmark{\"%s.%s\", %s.%s },\n", sname, testFunc, lname, testFunc)) } } } } if !isTest { collector := newTestCollector() for i = 0; i < len(v.Files); i++ { fname := v.Files[i] if len(fname) > 8 && fname[len(fname)-8:] == "_test.go" { tree := getSyntaxTreeOrDie(fname, 0) ast.Walk(collector, tree) } } if len(collector.Names) > 0 { if hasSlash(v.Name) { lname = removeSlashAndDot(v.Name) imprtSet.Add(fmt.Sprintf("import %s \"%s\"\n", lname, v.Name)) } else { imprtSet.Add(fmt.Sprintf("import \"%s\"\n", v.Name)) } for i = 0; i < len(collector.Names); i++ { testFunc := collector.Names[i] if len(testFunc) >= 4 && testFunc[0:4] == "Test" { sbTests.Add(fmt.Sprintf("testing.InternalTest{\"%s.%s\", %s.%s },\n", sname, testFunc, lname, testFunc)) } else if len(testFunc) >= 9 && testFunc[0:9] == "Benchmark" { sbBench.Add(fmt.Sprintf("testing.InternalBenchmark{\"%s.%s\", %s.%s },\n", sname, testFunc, lname, testFunc)) } } } } } sbTests.Add("};\n") sbBench.Add("};\n\n") for im := range imprtSet.Iter() { sbImports.Add(im) } sbTotal := stringbuffer.NewSize(sbImports.Len() + sbTests.Len() + sbBench.Len() + 100) sbTotal.Add(sbImports.String()) sbTotal.Add(sbTests.String()) sbTotal.Add(sbBench.String()) sbTotal.Add("func main(){\n") sbTotal.Add("testing.Main(regexp.MatchString, tests, benchmarks);\n}\n\n") tmpstub = fmt.Sprintf("tmp%d", time.Seconds()) tmpdir = filepath.Join(root, tmpstub) if global.GetString("-lib") != "" { tmplib = filepath.Join(global.GetString("-lib"), tmpstub) } dir, e1 := os.Stat(tmpdir) if e1 == nil && dir.IsDirectory() { log.Printf("[ERROR] directory: %s already exists\n", tmpdir) } else { e_mk := os.Mkdir(tmpdir, 0777) if e_mk != nil { log.Fatal("[ERROR] failed to create directory for testing") } } tmpfile = filepath.Join(tmpdir, "_main.go") fil, e2 := os.OpenFile(tmpfile, os.O_WRONLY|os.O_CREATE, 0777) if e2 != nil { log.Fatalf("[ERROR] %s\n", e2) } n, e3 := fil.WriteString(sbTotal.String()) if e3 != nil { log.Fatalf("[ERROR] %s\n", e3) } else if n != sbTotal.Len() { log.Fatal("[ERROR] failed to write test") } fil.Close() p := newPackage() p.Name = filepath.Join(tmpstub, "main") p.ShortName = "main" p.Files = append(p.Files, tmpfile) vec := make([]*Package, 1) vec[0] = p return vec, tmpdir, tmplib }
func printListing() { var listMSG string = ` Listing of options and their content: -h --help => %t -v --version => %t -p --print => %t -s --sort => %t -o --output => '%s' -S --static => %t -a --arch => %v -d --dryrun => %t -c --clean => %t -q --quiet => %t -L --lib => '%s' -M --main => '%s' -I => %v -dot => '%s' -t --test => %t -b --bench => '%s' -m --match => '%s' -V --verbose => %t --test-bin => '%s' -f --fmt => %t --rew-rule => '%s' --tab => %t --tabwidth => %s -e --external => %t -B --backend => '%s' ` tabRepr := "4" if global.GetString("-tabwidth") != "" { tabRepr = global.GetString("-tabwidth") } archRepr := "$GOARCH" if global.GetString("-arch") != "" { archRepr = global.GetString("-arch") } fmt.Printf(listMSG, global.GetBool("-help"), global.GetBool("-version"), global.GetBool("-print"), global.GetBool("-sort"), global.GetString("-output"), global.GetBool("-static"), archRepr, global.GetBool("-dryrun"), global.GetBool("-clean"), global.GetBool("-quiet"), global.GetString("-lib"), global.GetString("-main"), includes, global.GetString("-dot"), global.GetBool("-test"), global.GetString("-bench"), global.GetString("-match"), global.GetBool("-verbose"), global.GetString("-test-bin"), global.GetBool("-fmt"), global.GetString("-rew-rule"), global.GetBool("-tab"), tabRepr, global.GetBool("-external"), global.GetString("-backend")) }
func main() { var ok bool var e os.Error var argv, args []string var config1, config2 string timer.Start("everything") defer reportTime() // default config location 1 $HOME/.gdrc config1 = filepath.Join(os.Getenv("HOME"), ".gdrc") argv, ok = handy.ConfigToArgv(config1) if ok { args = parseArgv(argv) if len(args) > 0 { log.Print("[WARNING] non-option arguments in config file\n") } } // default config location 2 $PWD/.gdrc config2 = filepath.Join(os.Getenv("PWD"), ".gdrc") argv, ok = handy.ConfigToArgv(config2) if ok { args = parseArgv(argv) if len(args) > 0 { log.Print("[WARNING] non-option arguments in config file\n") } } // command line arguments overrides/appends config args = parseArgv(os.Args[1:]) if len(args) > 0 { if len(args) > 1 { log.Print("[WARNING] len(input directories) > 1\n") } srcdir = args[0] if srcdir == "." { srcdir, e = os.Getwd() if e != nil { log.Fatal("[ERROR] can't find working directory\n") } } } // expand variables in includes for i := 0; i < len(includes); i++ { includes[i] = os.ShellExpand(includes[i]) } // expand variables in -lib global.SetString("-lib", os.ShellExpand(global.GetString("-lib"))) // expand variables in -output global.SetString("-output", os.ShellExpand(global.GetString("-output"))) // stuff that can be done without $GOROOT if global.GetBool("-list") { printListing() os.Exit(0) } if global.GetBool("-help") { printHelp() os.Exit(0) } if global.GetBool("-version") { printVersion() os.Exit(0) } if len(args) == 0 { // give nice feedback if missing input dir cwd, e := os.Getwd() if e != nil { cwd = os.Getenv("PWD") } possibleSrc := cwd _, e = os.Stat(possibleSrc) srcdir, e = os.Getwd() if e != nil { fmt.Printf("usage: gd [OPTIONS] src-directory\n") os.Exit(1) } } if global.GetBool("-quiet") { say.Mute() } // delete all object/archive files if global.GetBool("-clean") { compiler.Remove865o(srcdir, false) // do not remove dir if global.GetString("-lib") != "" { if handy.IsDir(global.GetString("-lib")) { compiler.Remove865o(global.GetString("-lib"), true) } } os.Exit(0) } handy.DirOrExit(srcdir) files = walker.PathWalk(filepath.Clean(srcdir)) // gofmt on all files gathered if global.GetBool("-fmt") { compiler.FormatFiles(files) os.Exit(0) } // parse the source code, look for dependencies dgrph := dag.New() dgrph.Parse(srcdir, files) // print collected dependency info if global.GetBool("-print") { dgrph.PrintInfo() os.Exit(0) } // draw graphviz dot graph if global.GetString("-dot") != "" { dgrph.MakeDotGraph(global.GetString("-dot")) os.Exit(0) } gotRoot() //? (only matters to gc, gccgo and express ignores it) // build &| update all external dependencies if global.GetBool("-external") { dgrph.External() os.Exit(0) } // sort graph based on dependencies dgrph.GraphBuilder() sorted := dgrph.Topsort() // print packages sorted if global.GetBool("-sort") { for i := 0; i < len(sorted); i++ { fmt.Printf("%s\n", sorted[i].Name) } os.Exit(0) } // compile compiler.Init(srcdir, global.GetString("-arch"), includes) if global.GetString("-lib") != "" { compiler.CreateLibArgv(sorted) } else { compiler.CreateArgv(sorted) } if runtime.GOMAXPROCS(-1) > 1 && !global.GetBool("-dryrun") { compiler.ParallelCompile(sorted) } else { compiler.SerialCompile(sorted) } // test if global.GetBool("-test") { os.Setenv("SRCROOT", srcdir) testMain, testDir := dgrph.MakeMainTest(srcdir) if global.GetString("-lib") != "" { compiler.CreateLibArgv(testMain) } else { compiler.CreateArgv(testMain) } compiler.SerialCompile(testMain) switch global.GetString("-backend") { case "gc", "express": compiler.ForkLink(global.GetString("-test-bin"), testMain, nil) case "gccgo", "gcc": compiler.ForkLink(global.GetString("-test-bin"), testMain, sorted) default: log.Fatalf("[ERROR] '%s' unknown back-end\n", global.GetString("-backend")) } compiler.DeletePackages(testMain) rmError := os.Remove(testDir) if rmError != nil { log.Printf("[ERROR] failed to remove testdir: %s\n", testDir) } testArgv := compiler.CreateTestArgv() if !global.GetBool("-dryrun") { say.Printf("testing : ") if global.GetBool("-verbose") { say.Printf("\n") } ok = handy.StdExecve(testArgv, false) e = os.Remove(global.GetString("-test-bin")) if e != nil { log.Printf("[ERROR] %s\n", e) } if !ok { os.Exit(1) } } else { say.Printf("%s\n", strings.Join(testArgv, " ")) } } if global.GetString("-output") != "" { compiler.ForkLink(global.GetString("-output"), sorted, nil) } }
func main() { var ( ok, up2date bool e os.Error argv, args []string config = make([]string, 4) ) timer.Start("everything") defer reportTime() // possible config locations config[0] = filepath.Join(os.Getenv("XDG_CONFIG_HOME"), "godag", "gdrc") config[1] = filepath.Join(os.Getenv("HOME"), ".config", "godag", "gdrc") config[2] = filepath.Join(os.Getenv("HOME"), ".gdrc") config[3] = filepath.Join(os.Getenv("PWD"), ".gdrc") for _, conf := range config { argv, ok = handy.ConfigToArgv(conf) if ok { args = parseArgv(argv) if len(args) > 0 { log.Print("[WARNING] non-option arguments in config file\n") } } } // command line arguments overrides/appends config args = parseArgv(os.Args[1:]) if len(args) > 0 { if len(args) > 1 { log.Print("[WARNING] len(input directories) > 1\n") } srcdir = args[0] if srcdir == "." { srcdir, e = os.Getwd() if e != nil { log.Fatal("[ERROR] can't find working directory\n") } } } // expand variables in includes for i := 0; i < len(includes); i++ { includes[i] = os.ShellExpand(includes[i]) } // expand variables in -lib global.SetString("-lib", os.ShellExpand(global.GetString("-lib"))) // expand variables in -output global.SetString("-output", os.ShellExpand(global.GetString("-output"))) // stuff that can be done without $GOROOT if global.GetBool("-list") { printListing() os.Exit(0) } if global.GetBool("-help") { printHelp() os.Exit(0) } if global.GetBool("-version") { printVersion() os.Exit(0) } if len(args) == 0 { // give nice feedback if missing input dir if !handy.IsDir("src") { fmt.Printf("usage: gd [OPTIONS] src-directory\n") os.Exit(1) } } if global.GetBool("-quiet") { say.Mute() } handy.DirOrExit(srcdir) files = walker.PathWalk(filepath.Clean(srcdir)) // gofmt on all files gathered if global.GetBool("-fmt") { compiler.FormatFiles(files) os.Exit(0) } // parse the source code, look for dependencies dgrph := dag.New() dgrph.Parse(srcdir, files) // print collected dependency info if global.GetBool("-print") { dgrph.PrintInfo() os.Exit(0) } // draw graphviz dot graph if global.GetString("-dot") != "" { dgrph.MakeDotGraph(global.GetString("-dot")) os.Exit(0) } gotRoot() //? (only matters to gc, gccgo and express ignores it) // build &| update all external dependencies if global.GetBool("-external") { dgrph.External() os.Exit(0) } // sort graph based on dependencies dgrph.GraphBuilder() sorted := dgrph.Topsort() // clean only what we possibly could have generated… if global.GetBool("-clean") { compiler.DeleteObjects(srcdir, sorted) os.Exit(0) } // print packages sorted if global.GetBool("-sort") { for i := 0; i < len(sorted); i++ { fmt.Printf("%s\n", sorted[i].Name) } os.Exit(0) } // compile argv compiler.Init(srcdir, includes) if global.GetString("-lib") != "" { compiler.CreateLibArgv(sorted) } else { compiler.CreateArgv(sorted) } // gdmk if global.GetString("-gdmk") != "" { gdmake.Make(global.GetString("-gdmk"), sorted, dgrph.Alien().Slice()) os.Exit(0) } // compile; up2date == true => 0 packages modified if global.GetBool("-dryrun") { compiler.Dryrun(sorted) } else { up2date = compiler.Compile(sorted) // updated parallel } // test if global.GetBool("-test") { os.Setenv("SRCROOT", srcdir) testMain, testDir, testLib := dgrph.MakeMainTest(srcdir) if global.GetString("-lib") != "" { compiler.CreateLibArgv(testMain) } else { compiler.CreateArgv(testMain) } if !global.GetBool("-dryrun") { compiler.Compile(testMain) } switch global.GetString("-backend") { case "gc", "express": compiler.ForkLink(global.GetString("-test-bin"), testMain, nil, false) case "gccgo", "gcc": compiler.ForkLink(global.GetString("-test-bin"), testMain, sorted, false) default: log.Fatalf("[ERROR] '%s' unknown back-end\n", global.GetString("-backend")) } compiler.DeletePackages(testMain) handy.Delete(testDir, false) if testLib != "" { handy.Delete(testLib, false) } testArgv := compiler.CreateTestArgv() if global.GetBool("-dryrun") { testArgv[0] = filepath.Base(testArgv[0]) say.Printf("%s\n", strings.Join(testArgv, " ")) } else { say.Printf("testing : ") if global.GetBool("-verbose") || global.GetBool("-test.v") { say.Printf("\n") } ok = handy.StdExecve(testArgv, false) handy.Delete(global.GetString("-test-bin"), false) if !ok { os.Exit(1) } } // if packages contain both test-files and regular files // test-files should not be part of the objects, i.e. init // functions in test-packages can cause unexpected behaviour if compiler.ReCompile(sorted) { say.Printf("recompile: --tests\n") compiler.Compile(sorted) } } // link if ! up2date if global.GetString("-output") != "" { compiler.ForkLink(global.GetString("-output"), sorted, nil, up2date) } }
func (d Dag) MakeMainTest(root string) ([]*Package, string, string) { var ( i int lname string sname string tmplib string tmpdir string tmpstub string tmpfile string collector *TestCollector ) sbImports := stringbuffer.NewSize(300) imprtSet := stringset.New() sbTests := stringbuffer.NewSize(1000) sbBench := stringbuffer.NewSize(1000) sbExample := stringbuffer.NewSize(1000) sbImports.Add("\n// autogenerated code\n\n") sbImports.Add("package main\n\n") imprtSet.Add("import \"regexp\"\n") imprtSet.Add("import \"testing\"\n") sbTests.Add("\n\nvar tests = []testing.InternalTest{\n") sbBench.Add("\n\nvar benchmarks = []testing.InternalBenchmark{\n") sbExample.Add("\n\nvar examples = []testing.InternalExample{\n") for _, v := range d { sname = v.ShortName lname = v.ShortName collector = newTestCollector() if strings.HasSuffix(v.ShortName, "_test") { for i = 0; i < len(v.Files); i++ { tree := getSyntaxTreeOrDie(v.Files[i], parser.ParseComments) ast.Walk(collector, tree) } } else { for i = 0; i < len(v.Files); i++ { if strings.HasSuffix(v.Files[i], "_test.go") { tree := getSyntaxTreeOrDie(v.Files[i], parser.ParseComments) ast.Walk(collector, tree) } } } if collector.FoundAnything() { if hasSlash(v.Name) { lname = removeSlashAndDot(v.Name) imprtSet.Add(fmt.Sprintf("import %s \"%s\"\n", lname, v.Name)) } else { imprtSet.Add(fmt.Sprintf("import \"%s\"\n", v.Name)) } // add tests for i := 0; i < len(collector.TestFuncs); i++ { fn := collector.TestFuncs[i] sbTests.Add(fmt.Sprintf( "testing.InternalTest{\"%s.%s\", %s.%s },\n", sname, fn, lname, fn)) } // add benchmarks for i := 0; i < len(collector.BenchFuncs); i++ { fn := collector.BenchFuncs[i] sbBench.Add(fmt.Sprintf( "testing.InternalBenchmark{\"%s.%s\", %s.%s },\n", sname, fn, lname, fn)) } // add examples ( not really ) for i := 0; i < len(collector.ExampleFuncs); i++ { // fn := collector.ExampleFuncs[i] //TODO add comment which seems to be what we compare against.. // sbExample.Add(fmt.Sprintf("testing.InternalExample{\"%s.%s\", %s.%s },\n", sname, fn, lname, fn)) } } } sbTests.Add("};\n") sbBench.Add("};\n") sbExample.Add("};\n") for im := range imprtSet.Iter() { sbImports.Add(im) } sbTotal := stringbuffer.NewSize(sbImports.Len() + sbTests.Len() + sbBench.Len() + 100) sbTotal.Add(sbImports.String()) sbTotal.Add(sbTests.String()) sbTotal.Add(sbBench.String()) sbTotal.Add(sbExample.String()) sbTotal.Add("func main(){\n") sbTotal.Add("testing.Main(regexp.MatchString, tests, benchmarks, examples);\n}\n\n") tmpstub = fmt.Sprintf("tmp%d", time.Now().Unix()) tmpdir = filepath.Join(root, tmpstub) if global.GetString("-lib") != "" { tmplib = filepath.Join(global.GetString("-lib"), tmpstub) } dir, e1 := os.Stat(tmpdir) if e1 == nil && dir.IsDir() { log.Printf("[ERROR] directory: %s already exists\n", tmpdir) } else { e_mk := os.Mkdir(tmpdir, 0777) if e_mk != nil { log.Fatal("[ERROR] failed to create directory for testing") } } tmpfile = filepath.Join(tmpdir, "_main.go") fil, e2 := os.OpenFile(tmpfile, os.O_WRONLY|os.O_CREATE, 0777) if e2 != nil { log.Fatalf("[ERROR] %s\n", e2) } n, e3 := fil.WriteString(sbTotal.String()) if e3 != nil { log.Fatalf("[ERROR] %s\n", e3) } else if n != sbTotal.Len() { log.Fatal("[ERROR] failed to write test") } fil.Close() p := newPackage() p.Name = filepath.Join(tmpstub, "main") p.ShortName = "main" p.Files = append(p.Files, tmpfile) vec := make([]*Package, 1) vec[0] = p return vec, tmpdir, tmplib }