func doOutput(args []string) { exitIfErr(outputFlags.Parse(args)) var conf loader.Config rest, err := conf.FromArgs(outputFlags.Args(), true) if len(rest) > 0 { fmt.Fprintf(os.Stderr, "Unrecognized arguments:\n%v\n\n", strings.Join(rest, "\n")) } if err != nil { fmt.Fprintf(os.Stderr, "Error identifying packages: %v\n\n", err) } if len(rest) > 0 || err != nil { usage() } conf.SourceImports = true prog, err := conf.Load() if err != nil { fmt.Fprintf(os.Stderr, "Error loading packages: %v\n\n", err) usage() } gen.Generate(prog, ioutil.ReadFile, func(importPath, filename string) io.WriteCloser { if *w { return createFileHook(filename, "") } return nopCloser{os.Stdout} }) }
func generateSourceFiles(conf *loader.Config, subcommand string) (tmpDirPath string) { // Make a temp directory. tmpDir := makeTmpDir() if *work { // Print the name of the directory and don't clean it up on exit. fmt.Println(tmpDir) } else { // Clean up the directory on exit. atexit.Run(func() { removeDir(tmpDir) }) } // Load the whole program from source files. This almost certainly causes more work than we need to do, // but it's an easy fix for a few problems I've encountered. Deleting this may be a good target for // future optimization work. conf.SourceImports = true // Mark the extra packages we want to instrument. var pkgs []string *instrument = strings.Trim(*instrument, ", ") if *instrument != "" { pkgs = strings.Split(*instrument, ",") } all := false for _, pkg := range pkgs { // check for the special reserved package names: "main", "all", and "std" // see 'go help packages' switch pkg { case "main": switch subcommand { case "run": // The main package is always instrumented anyway. Carry on. case "test": logFatal(`godebug test: can't pass reserved name "main" in the -instrument flag.`) } case "all": if !all { all = true fmt.Println(`godebug run: heads up: "all" means "all except std". godebug can't step into the standard library yet.` + "\n") } case "std": logFatalf("godebug %s: reserved name \"std\" cannot be passed in the -instrument flag."+ "\ngodebug cannot currently instrument packages in the standard library."+ "\nDo you wish it could? Chime in at https://github.com/mailgun/godebug/issues/12", subcommand) default: for _, path := range gotool.ImportPaths([]string{pkg}) { // wildcard "..." expansion conf.Import(path) } } } // Load the program. prog, err := conf.Load() exitIfErr(err) // If we're in "all" mode, mark all but the standard library packages and godebug itself for instrumenting. stdLib := getStdLibPkgs() if all { markAlmostAllPackages(prog, stdLib) } // Warn the user if they have breakpoints set in files that we are not instrumenting. checkForUnusedBreakpoints(subcommand, prog, stdLib) // Generate debugging-enabled source files. wd := getwd() gen.Generate(prog, ioutil.ReadFile, func(importPath, filename string) io.WriteCloser { if importPath == "main" { filename = filepath.Join(tmpDir, filepath.Base(filename)) } else { importPath, _ = findUnderGopath(wd, importPath) exitIfErr(os.MkdirAll(filepath.Join(tmpDir, "src", importPath), 0770)) filename = filepath.Join(tmpDir, "src", importPath, filepath.Base(filename)) } return createFileHook(filename, tmpDir) }) return tmpDir }