// findImportDir finds the absolute directory. If rel is empty vendor folders // are not looked in. func (ctx *Context) findImportDir(relative, importPath string) (dir, gopath string, err error) { if importPath == "builtin" || importPath == "unsafe" || importPath == "C" { return filepath.Join(ctx.Goroot, importPath), ctx.Goroot, nil } if len(relative) != 0 { rel := relative for { look := filepath.Join(rel, ctx.VendorDiscoverFolder, importPath) nextRel := filepath.Join(rel, "..") if rel == nextRel { break } rel = nextRel fi, err := os.Stat(look) if os.IsNotExist(err) { continue } if err != nil { continue } if fi.IsDir() == false { continue } for _, gopath = range ctx.GopathList { if pathos.FileHasPrefix(look, gopath) { hasGo, err := hasGoFileInFolder(look) if err != nil { return "", "", err } if hasGo { return look, gopath, nil } } } } } for _, gopath = range ctx.GopathList { dir := filepath.Join(gopath, importPath) fi, err := os.Stat(dir) if os.IsNotExist(err) { continue } if fi.IsDir() == false { continue } hasGo, err := hasGoFileInFolder(dir) if err != nil { return "", "", err } if hasGo { return dir, gopath, nil } return "", "", ErrNotInGOPATH{fmt.Sprintf("Import: %q relative: %q", importPath, relative)} } return "", "", ErrNotInGOPATH{importPath} }
func (VcsHg) Find(dir string) (*VcsInfo, error) { fi, err := os.Stat(filepath.Join(dir, ".hg")) if err != nil { if os.IsNotExist(err) { return nil, nil } return nil, err } if fi.IsDir() == false { return nil, nil } // Get info. info := &VcsInfo{} cmd := exec.Command("hg", "identify", "-i") cmd.Dir = dir output, err := cmd.CombinedOutput() if err != nil { return nil, err } rev := strings.TrimSpace(string(output)) if strings.HasSuffix(rev, "+") { info.Dirty = true rev = strings.TrimSuffix(rev, "+") } cmd = exec.Command("hg", "log", "-r", rev) cmd.Dir = dir output, err = cmd.CombinedOutput() if err != nil { return nil, err } for _, line := range strings.Split(string(output), "\n") { if strings.HasPrefix(line, "changeset:") { ss := strings.Split(line, ":") info.Revision = strings.TrimSpace(ss[len(ss)-1]) } if strings.HasPrefix(line, "date:") { line = strings.TrimPrefix(line, "date:") tm, err := time.Parse("Mon Jan 02 15:04:05 2006 -0700", strings.TrimSpace(line)) if err == nil { info.RevisionTime = &tm } } } return info, nil }
func findRoot(folder, vendorPath string) (root string, err error) { for i := 0; i <= looplimit; i++ { test := filepath.Join(folder, vendorPath) _, err := os.Stat(test) if os.IsNotExist(err) == false { return folder, nil } nextFolder := filepath.Clean(filepath.Join(folder, "..")) // Check for root folder. if nextFolder == folder { return "", ErrMissingVendorFile{vendorPath} } folder = nextFolder } panic("findRoot loop limit") }
func (VcsBzr) Find(dir string) (*VcsInfo, error) { fi, err := os.Stat(filepath.Join(dir, ".bzr")) if err != nil { if os.IsNotExist(err) { return nil, nil } return nil, err } if fi.IsDir() == false { return nil, nil } // Get info. info := &VcsInfo{} cmd := exec.Command("bzr", "status") cmd.Dir = dir output, err := cmd.CombinedOutput() if err != nil { return nil, err } if string(output) != "" { info.Dirty = true } cmd = exec.Command("bzr", "log", "-r-1") cmd.Dir = dir output, err = cmd.CombinedOutput() if err != nil { return nil, err } for _, line := range strings.Split(string(output), "\n") { if strings.HasPrefix(line, "revno:") { info.Revision = strings.Split(strings.TrimSpace(strings.TrimPrefix(line, "revno:")), " ")[0] } else if strings.HasPrefix(line, "timestamp:") { tm, err := time.Parse("Mon 2006-01-02 15:04:05 -0700", strings.TrimSpace(strings.TrimPrefix(line, "timestamp:"))) if err != nil { return nil, err } info.RevisionTime = &tm } } return info, nil }
func hasGoFileInFolder(folder string) (bool, error) { dir, err := os.Open(folder) if err != nil { if os.IsNotExist(err) { // No folder present, no need to check for files. return false, nil } return false, err } fl, err := dir.Readdir(-1) dir.Close() if err != nil { return false, err } for _, fi := range fl { if fi.IsDir() == false && filepath.Ext(fi.Name()) == ".go" { return true, nil } } return false, nil }
func (VcsGit) Find(dir string) (*VcsInfo, error) { fi, err := os.Stat(filepath.Join(dir, ".git")) if err != nil { if os.IsNotExist(err) { return nil, nil } return nil, err } if fi.IsDir() == false { return nil, nil } // Get info. info := &VcsInfo{} cmd := exec.Command("git", "diff", "--quiet") cmd.Dir = dir err = cmd.Run() if err != nil { info.Dirty = true } cmd = exec.Command("git", "show", "--pretty=format:%H@%ai", "-s") cmd.Dir = dir output, err := cmd.CombinedOutput() if err != nil { return nil, err } line := strings.TrimSpace(string(output)) ss := strings.Split(line, "@") info.Revision = ss[0] tm, err := time.Parse("2006-01-02 15:04:05 -0700", ss[1]) if err != nil { return nil, err } info.RevisionTime = &tm return info, nil }
// NewContext creates new context from a given root folder and vendor file path. // The vendorFolder is where vendor packages should be placed. func NewContext(root, vendorFilePathRel, vendorFolder string, rewriteImports bool) (*Context, error) { dprintf("CTX: %s\n", root) vendorFilePath := filepath.Join(root, vendorFilePathRel) vf, err := readVendorFile(vendorFilePath) if err != nil { if !os.IsNotExist(err) { return nil, err } vf = &vendorfile.File{} } // Get GOROOT. First check ENV, then run "go env" and find the GOROOT line. goroot := os.Getenv("GOROOT") if len(goroot) == 0 { // If GOROOT is not set, get from go cmd. cmd := exec.Command("go", "env") var goEnv []byte goEnv, err = cmd.CombinedOutput() if err != nil { return nil, err } const gorootLookFor = `GOROOT=` for _, line := range strings.Split(string(goEnv), "\n") { if strings.HasPrefix(line, gorootLookFor) == false { continue } goroot = strings.TrimPrefix(line, gorootLookFor) goroot, err = strconv.Unquote(goroot) if err != nil { return nil, err } break } } if goroot == "" { return nil, ErrMissingGOROOT } goroot = filepath.Join(goroot, "src") // Get the GOPATHs. Prepend the GOROOT to the list. all := os.Getenv("GOPATH") if len(all) == 0 { return nil, ErrMissingGOPATH } gopathList := filepath.SplitList(all) gopathGoroot := make([]string, 0, len(gopathList)+1) gopathGoroot = append(gopathGoroot, goroot) for _, gopath := range gopathList { gopathGoroot = append(gopathGoroot, filepath.Join(gopath, "src")+string(filepath.Separator)) } rootToVendorFile, _ := filepath.Split(vendorFilePathRel) vendorFileDir, _ := filepath.Split(vendorFilePath) vendorFolderRel, err := filepath.Rel(vendorFileDir, filepath.Join(root, vendorFolder)) if err != nil { return nil, err } vendorFileToFolder := pathos.SlashToImportPath(vendorFolderRel) ctx := &Context{ RootDir: root, GopathList: gopathGoroot, Goroot: goroot, VendorFile: vf, VendorFilePath: vendorFilePath, VendorFolder: vendorFolder, VendorFileToFolder: vendorFileToFolder, RootToVendorFile: pathos.SlashToImportPath(rootToVendorFile), VendorDiscoverFolder: "vendor", Package: make(map[string]*Package), RewriteRule: make(map[string]string, 3), rewriteImports: rewriteImports, } ctx.RootImportPath, ctx.RootGopath, err = ctx.findImportPath(root) if err != nil { return nil, err } ctx.IgnoreBuild(vf.Ignore) return ctx, nil }