func (r *RemoteCache) Root(importPath string) (root, name string, err error) {
	// Try prefixes of the import path in the cache, but don't actually go out
	// to vcs yet. We do this before handling known special cases because
	// the cache is pre-populated with repository rules, and we want to use their
	// names if we can.
	prefix := importPath
	for {
		v, ok, err := r.root.get(prefix)
		if ok {
			if err != nil {
				return "", "", err
			}
			value := v.(rootValue)
			return value.root, value.name, nil
		}

		prefix = path.Dir(prefix)
		if prefix == "." || prefix == "/" {
			break
		}
	}

	// Try known prefixes.
	for _, p := range knownPrefixes {
		if pathtools.HasPrefix(importPath, p.prefix) {
			rest := pathtools.TrimPrefix(importPath, p.prefix)
			var components []string
			if rest != "" {
				components = strings.Split(rest, "/")
			}
			if len(components) < p.missing {
				return "", "", fmt.Errorf("import path %q is shorter than the known prefix %q", importPath, p.prefix)
			}
			root = p.prefix
			for _, c := range components[:p.missing] {
				root = path.Join(root, c)
			}
			name = label.ImportPathToBazelRepoName(root)
			return root, name, nil
		}
	}

	// gopkg.in is special, and might have either one or two levels of
	// missing paths. See http://labix.org/gopkg.in for URL patterns.
	if match := gopkginPattern.FindStringSubmatch(importPath); len(match) > 0 {
		root = match[1]
		name = label.ImportPathToBazelRepoName(root)
		return root, name, nil
	}

	// Find the prefix using vcs and cache the result.
	v, err := r.root.ensure(importPath, func() (interface{}, error) {
		res, err := r.RepoRootForImportPath(importPath, false)
		if err != nil {
			return nil, err
		}
		return rootValue{res.Root, label.ImportPathToBazelRepoName(res.Root)}, nil
	})
	if err != nil {
		return "", "", err
	}
	value := v.(rootValue)
	return value.root, value.name, nil
}
func (r *RemoteCache) Root(importPath string) (root, name string, err error) {
	
	
	
	
	prefix := importPath
	for {
		v, ok, err := r.root.get(prefix)
		if ok {
			if err != nil {
				return "", "", err
			}
			value := v.(rootValue)
			return value.root, value.name, nil
		}

		prefix = path.Dir(prefix)
		if prefix == "." || prefix == "/" {
			break
		}
	}

	
	for _, p := range knownPrefixes {
		if pathtools.HasPrefix(importPath, p.prefix) {
			rest := pathtools.TrimPrefix(importPath, p.prefix)
			var components []string
			if rest != "" {
				components = strings.Split(rest, "/")
			}
			if len(components) < p.missing {
				return "", "", fmt.Errorf("import path %q is shorter than the known prefix %q", importPath, p.prefix)
			}
			root = p.prefix
			for _, c := range components[:p.missing] {
				root = path.Join(root, c)
			}
			name = label.ImportPathToBazelRepoName(root)
			return root, name, nil
		}
	}

	
	
	if match := gopkginPattern.FindStringSubmatch(importPath); len(match) > 0 {
		root = match[1]
		name = label.ImportPathToBazelRepoName(root)
		return root, name, nil
	}

	
	v, err := r.root.ensure(importPath, func() (interface{}, error) {
		res, err := r.RepoRootForImportPath(importPath, false)
		if err != nil {
			return nil, err
		}
		return rootValue{res.Root, label.ImportPathToBazelRepoName(res.Root)}, nil
	})
	if err != nil {
		return "", "", err
	}
	value := v.(rootValue)
	return value.root, value.name, nil
}
func ( r * RemoteCache ) Root ( importPath string ) ( root , name string , err error ) { // Try prefixes of the import path in the cache, but don't actually go out // to vcs yet. We do this before handling known special cases because // the cache is pre-populated with repository rules, and we want to use their // names if we can. prefix := importPath for { v , ok , err := r . root . get ( prefix ) if ok { if err != nil { return " " , " " , err } value := v . ( rootValue ) return value . root , value . name , nil } prefix = path . Dir ( prefix ) if prefix == " " || prefix == " " { break } } // Try known prefixes. for _ , p := range knownPrefixes { if pathtools . HasPrefix ( importPath , p . prefix ) { rest := pathtools . TrimPrefix ( importPath , p . prefix ) var components [ ] string if rest != " " { components = strings . Split ( rest , " " ) } if len ( components ) < p . missing { return " " , " " , fmt . Errorf ( " " , importPath , p . prefix ) } root = p . prefix for _ , c := range components [ : p . missing ] { root = path . Join ( root , c ) } name = label . ImportPathToBazelRepoName ( root ) return root , name , nil } } // gopkg.in is special, and might have either one or two levels of // missing paths. See http://labix.org/gopkg.in for URL patterns. if match := gopkginPattern . FindStringSubmatch ( importPath ) ; len ( match ) > 0 { root = match [ 1 ] name = label . ImportPathToBazelRepoName ( root ) return root , name , nil } // Find the prefix using vcs and cache the result. v , err := r . root . ensure ( importPath , func ( ) ( interface { } , error ) { res , err := r . RepoRootForImportPath ( importPath , false ) if err != nil { return nil , err } return rootValue { res . Root , label . ImportPathToBazelRepoName ( res . Root ) } , nil } ) if err != nil { return " " , " " , err } value := v . ( rootValue ) return value . root , value . name , nil }
// Root returns the portion of an import path that corresponds to the root
// directory of the repository containing the given import path. For example,
// given "golang.org/x/tools/go/loader", this will return "golang.org/x/tools".
// The workspace name of the repository is also returned. This may be a custom
// name set in WORKSPACE, or it may be a generated name based on the root path.
Root returns the portion of an import path that corresponds to the root directory of the repository containing the given import path . For example given golang . org / x / tools / go / loader this will return golang . org / x / tools . The workspace name of the repository is also returned . This may be a custom name set in WORKSPACE or it may be a generated name based on the root path .