9 // SourceDirSubdir takes a source URL and returns a tuple of the URL without
10 // the subdir and the subdir.
13 // dom.com/path/?q=p => dom.com/path/?q=p, ""
14 // proto://dom.com/path//*?q=p => proto://dom.com/path?q=p, "*"
15 // proto://dom.com/path//path2?q=p => proto://dom.com/path?q=p, "path2"
17 func SourceDirSubdir(src string) (string, string) {
19 // URL might contains another url in query parameters
21 if idx := strings.Index(src, "?"); idx > -1 {
25 // Calculate an offset to avoid accidentally marking the scheme
28 if idx := strings.Index(src[:stop], "://"); idx > -1 {
32 // First see if we even have an explicit subdir
33 idx := strings.Index(src[offset:stop], "//")
42 // Next, check if we have query parameters and push them onto the
44 if idx = strings.Index(subdir, "?"); idx > -1 {
53 // SubdirGlob returns the actual subdir with globbing processed.
55 // dst should be a destination directory that is already populated (the
56 // download is complete) and subDir should be the set subDir. If subDir
57 // is an empty string, this returns an empty string.
59 // The returned path is the full absolute path.
60 func SubdirGlob(dst, subDir string) (string, error) {
61 matches, err := filepath.Glob(filepath.Join(dst, subDir))
66 if len(matches) == 0 {
67 return "", fmt.Errorf("subdir %q not found", subDir)
71 return "", fmt.Errorf("subdir %q matches multiple paths", subDir)
74 return matches[0], nil