func copyDir(dest, src string) error {
	log.Printf("copying contents of %q to %q", src, dest)
	if !fake {
		err := os.MkdirAll(dest, 0770)
		if err != nil {
			return fmt.Errorf("couldn't make destination directory", dest)
		}
	}
	return filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			if path != src {
				return filepath.SkipDir
			}
			return nil
		}
		relPath, err := filepath.Rel(src, path)
		if err != nil {
			return err
		}
		destFile := filepath.Join(dest, relPath)
		verbosef("copying %q to %q", path, destFile)
		if fake {
			return nil
		}
		return copyFile(destFile, path, info.Mode().Perm())
	})
}
copyDir non-recursively copies the contents of the src directory to dest.
package main
import (
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/format"
	"go/parser"
	"go/token"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)
var (
	fake     bool
	rewrites map[string]string  
	visited  map[string]bool    
)
func main() {
	flag.BoolVar(&fake, "n", false, "If true, don't actually do anything")
	flag.BoolVar(&verbose, "v", false, "Provide verbose output")
	flag.Var(&ignorePrefixes, "ignore", "Package prefix to ignore. Can be given multiple times.")
	flag.Parse()
	gopaths := filepath.SplitList(os.Getenv("GOPATH"))
	if len(gopaths) == 0 {
		log.Fatal("GOPATH must be set")
	}
	pkgName := flag.Arg(0)
	if pkgName == "" {
		log.Fatal("need a package name")
	}
	dest := flag.Arg(1)
	if dest == "" {
		log.Fatal("need a destination path")
	}
	ignorePrefixes = append(ignorePrefixes, pkgName)
	ignorePrefixes = append(ignorePrefixes, dest)
	rewrites = make(map[string]string)
	visited = make(map[string]bool)
	err := vendorize(pkgName, chooseGOPATH(gopaths, dest), dest)
	if err != nil {
		log.Fatal(err)
	}
}
func chooseGOPATH(gopaths []string, dest string) string {
	for {
		dest = strings.TrimSuffix(dest, "/")
		chosen := ""
		for i := len(gopaths) - 1; i >= 0; i-- {
			dir := filepath.Join(gopaths[i], "src", dest)
			if _, err := os.Stat(dir); err == nil {
				chosen = gopaths[i]
			}
		}
		if chosen != "" {
			return chosen
		}
		dest, _ = filepath.Split(dest)
		if dest == "" {
			break
		}
	}
	for _, dir := range gopaths {
		if _, err := os.Stat(dir); err == nil {
			return dir
		}
	}
	return gopaths[0]
}
func vendorize(path, gopath, dest string) error {
	if visited[path] {
		return nil
	}
	visited[path] = true
	verbosef("vendorizing %s", path)
	rootPkg, err := buildPackage(path)
	if err != nil {
		return fmt.Errorf("couldn't import %s: %s", path, err)
	}
	if rootPkg.Goroot {
		return fmt.Errorf("can't vendorize packages from GOROOT")
	}
	allImports := getAllImports(rootPkg)
	var pkgs []*build.Package
	for _, imp := range allImports {
		if imp == "C" {
			continue
		}
		pkg, err := buildPackage(imp)
		if err != nil {
			return fmt.Errorf("%s: couldn't import %s: %s", path, imp, err)
		}
		if !pkg.Goroot {
			pkgs = append(pkgs, pkg)
		}
	}
	for _, pkg := range pkgs {
		err := vendorize(pkg.ImportPath, gopath, dest)
		if err != nil {
			return fmt.Errorf("couldn't vendorize %s: %s", pkg.ImportPath, err)
		}
	}
	pkgDir := rootPkg.Dir
	if !ignored(path) {
		newPath := dest + "/" + path
		pkgDir = filepath.Join(gopath, "src", newPath)
		err = copyDir(pkgDir, rootPkg.Dir)
		if err != nil {
			return fmt.Errorf("couldn't copy %s: %s", path, err)
		}
		rewrites[path] = newPath
	}
	for _, files := range [][]string{
		rootPkg.GoFiles, rootPkg.CgoFiles, rootPkg.TestGoFiles, rootPkg.XTestGoFiles,
	} {
		for _, file := range files {
			if len(rewrites) > 0 {
				destFile := filepath.Join(pkgDir, file)
				verbosef("rewriting imports in %q", destFile)
				err := rewriteFile(destFile, filepath.Join(rootPkg.Dir, file), rewrites)
				if err != nil {
					return fmt.Errorf("%s: couldn't rewrite file %q: %s", path, file, err)
				}
			}
		}
	}
	return nil
}
var ignorePrefixes stringSliceFlag
func ignored(path string) bool {
	_, rewritten := rewrites[path]
	if rewritten {
		return true
	}
	for _, prefix := range ignorePrefixes {
		if strings.HasPrefix(path, prefix) {
			return true
		}
	}
	return false
}
func copyFile(dest, src string, perm os.FileMode) error {
	in, err := os.Open(src)
	if err != nil {
		return err
	}
	defer in.Close()
	out, err := os.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)
	if err != nil {
		return err
	}
	defer out.Close()
	_, err = io.Copy(out, in)
	return err
}