func parseArgv(argv []string) (args []string) { args = getopt.Parse(argv) for _, bkey := range bools { if getopt.IsSet(bkey) { global.SetBool(bkey, true) } } for _, skey := range strs { if getopt.IsSet(skey) { global.SetString(skey, getopt.Get(skey)) } } if getopt.IsSet("-test") || getopt.IsSet("-fmt") || getopt.IsSet("-clean") { // override IncludeFile to make walker pick _test.go files walker.IncludeFile = allGoFilesFilter } if getopt.IsSet("-gdmk") { global.SetString("-lib", "_obj") // gdmk does not support testing walker.IncludeFile = noTestFilesFilter } if getopt.IsSet("-I") { includes = append(includes, getopt.GetMultiple("-I")...) } getopt.Reset() return args }
//TODO rewrite the whole link stuff, make i run in parallel func ForkLinkAll(pkgs []*dag.Package, up2date bool) { mainPkgs := make([]*dag.Package, 0) for i := 0; i < len(pkgs); i++ { if pkgs[i].ShortName == "main" { mainPkgs = append(mainPkgs, pkgs[i]) } } if len(mainPkgs) == 0 { log.Fatal("[ERROR] (linking) no main package found\n") } handy.DirOrMkdir("bin") for i := 0; i < len(mainPkgs); i++ { toks := strings.Split(mainPkgs[i].Name, "/") // do this for main packages which are placed in directories // if toks < 2 this cannot be true, i.e. then the main package // lives under the src-root and cannot be filtered if len(toks) >= 2 { nameOfBinary := toks[len(toks)-2] pathToBinary := filepath.Join("bin", nameOfBinary) global.SetString("-main", nameOfBinary) ForkLink(pathToBinary, pkgs, nil, up2date) } } }
func parseArgv(argv []string) (args []string) { args = getopt.Parse(argv) for _, bkey := range bools { if getopt.IsSet(bkey) { global.SetBool(bkey, true) } } for _, skey := range strs { if getopt.IsSet(skey) { global.SetString(skey, getopt.Get(skey)) } } if getopt.IsSet("-test") || getopt.IsSet("-fmt") { // override IncludeFile to make walker pick _test.go files walker.IncludeFile = func(s string) bool { return strings.HasSuffix(s, ".go") // && // !strings.HasPrefix(filepath.Base(s), "_") } } if getopt.IsSet("-I") { if includes == nil { includes = getopt.GetMultiple("-I") } else { includes = append(includes, getopt.GetMultiple("-I")...) } } getopt.Reset() return args }
func init() { // initialize option parser getopt = gopt.New() // add all options (bool/string) getopt.BoolOption("-h -help --help help") getopt.BoolOption("-c -clean --clean clean") getopt.BoolOption("-S -static --static") getopt.BoolOption("-v -version --version version") getopt.BoolOption("-s -sort --sort sort") getopt.BoolOption("-p -print --print") getopt.BoolOption("-d -dryrun --dryrun") getopt.BoolOption("-t -test --test test") getopt.BoolOption("-l -list --list") getopt.BoolOption("-q -quiet --quiet") getopt.BoolOption("-V -verbose --verbose") getopt.BoolOption("-f -fmt --fmt") getopt.BoolOption("-tab --tab") getopt.BoolOption("-e -external --external") getopt.StringOption("-a -a= -arch --arch -arch= --arch=") getopt.StringOption("-dot -dot= --dot --dot=") getopt.StringOption("-L -L= -lib -lib= --lib --lib=") getopt.StringOption("-I -I=") getopt.StringOption("-tabwidth --tabwidth -tabwidth= --tabwidth=") getopt.StringOption("-rew-rule --rew-rule -rew-rule= --rew-rule=") getopt.StringOption("-o -o= -output --output -output= --output=") getopt.StringOption("-M -M= -main --main -main= --main=") getopt.StringOption("-b -b= -bench --bench -bench= --bench=") getopt.StringOption("-m -m= -match --match -match= --match=") getopt.StringOption("-test-bin --test-bin -test-bin= --test-bin=") getopt.StringOption("-B -B= -backend --backend -backend= --backend=") getopt.StringOption("-x -x= -exclude --exclude --exclude=") // override IncludeFile to make walker pick up only .go files walker.IncludeFile = func(s string) bool { return strings.HasSuffix(s, ".go") && !strings.HasSuffix(s, "_test.go") // && // !strings.HasPrefix(filepath.Base(s), "_") } // override IncludeDir to make walker ignore 'hidden' directories walker.IncludeDir = func(s string) bool { _, dirname := filepath.Split(s) return dirname[0] != '.' } for _, bkey := range bools { global.SetBool(bkey, false) } for _, skey := range strs { global.SetString(skey, "") } if os.Getenv("GOOS") == "windows" { global.SetString("-test-bin", "gdtest.exe") } else { global.SetString("-test-bin", "gdtest") } global.SetString("-backend", "gc") global.SetString("-lib", "build") global.SetString("-I", "") }
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 init() { // initialize option parser getopt = gopt.New() // add all options (bool/string) getopt.BoolOption("-h -help --help help") getopt.BoolOption("-c -clean --clean clean") getopt.BoolOption("-S -static --static") getopt.BoolOption("-v -version --version version") getopt.BoolOption("-s -sort --sort sort") getopt.BoolOption("-p -print --print") getopt.BoolOption("-d -dryrun --dryrun") getopt.BoolOption("-t -test --test test") getopt.BoolOption("-l -list --list") getopt.BoolOption("-q -quiet --quiet") getopt.BoolOption("-V -verbose --verbose") getopt.BoolOption("-f -fmt --fmt") getopt.BoolOption("-T -tab --tab") getopt.BoolOption("-e -external --external") getopt.StringOptionFancy("-a --arch") getopt.StringOptionFancy("-D --dot") getopt.StringOptionFancy("-L --lib") getopt.StringOption("-I -I=") getopt.StringOptionFancy("-g --gdmk") getopt.StringOptionFancy("-w --tabwidth") getopt.StringOptionFancy("-r --rewrite") getopt.StringOptionFancy("-o --output") getopt.StringOptionFancy("-M --main") getopt.StringOptionFancy("-b --bench") getopt.StringOptionFancy("-m --match") getopt.StringOptionFancy("--test-bin") getopt.StringOptionFancy("-B --backend") // new test options and aliases getopt.BoolOption("-test.short --test.short") getopt.BoolOption("-test.v --test.v") getopt.StringOptionFancy("--test.bench") getopt.StringOptionFancy("--test.benchtime") getopt.StringOptionFancy("--test.cpu") getopt.StringOptionFancy("--test.cpuprofile") getopt.StringOptionFancy("--test.memprofile") getopt.StringOptionFancy("--test.memprofilerate") getopt.StringOptionFancy("--test.timeout") // override IncludeFile to make walker pick up only .go files walker.IncludeFile = noTestFilesFilter // override IncludeDir to make walker ignore 'hidden' directories walker.IncludeDir = func(s string) bool { _, dirname := filepath.Split(s) return dirname[0] != '.' } for _, bkey := range bools { global.SetBool(bkey, false) } for _, skey := range strs { global.SetString(skey, "") } // Testing on Windows requires .exe ending if os.Getenv("GOOS") == "windows" { global.SetString("-test-bin", "gdtest.exe") } else { global.SetString("-test-bin", "gdtest") } global.SetString("-backend", "gc") global.SetString("-I", "") }
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) } }