Beispiel #1
0
func Init(srcdir string, include []string) {

	srcroot = srcdir
	includes = include

	if global.GetString("-lib") != "" {
		libroot = global.GetString("-lib")
	} else {
		libroot = srcroot
	}

	InitBackend()
}
Beispiel #2
0
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"))
	}
}
Beispiel #3
0
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)
		}
	}
}
Beispiel #4
0
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
	}
}
Beispiel #5
0
Datei: main.go Projekt: ssrl/mgd
// ignore GOROOT for gccgo and express
func gotRoot() {
	if global.GetString("-backend") == "gc" {
		if os.Getenv("GOROOT") == "" {
			log.Fatal("[ERROR] missing GOROOT\n")
		}
	}
}
Beispiel #6
0
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
}
Beispiel #7
0
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"))
	}
}
Beispiel #8
0
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)
}
Beispiel #9
0
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
			}
		}
	}
}
Beispiel #10
0
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
}
Beispiel #11
0
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)
	}
}
Beispiel #12
0
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
}
Beispiel #13
0
Datei: main.go Projekt: ssrl/mgd
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"))
}
Beispiel #14
0
Datei: main.go Projekt: ssrl/mgd
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)
	}

}
Beispiel #15
0
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)
	}

}
Beispiel #16
0
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
}