github.com/weiwenhao/getter@v1.30.1/source.go (about)

     1  package getter
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"strings"
     7  )
     8  
     9  // SourceDirSubdir takes a source URL and returns a tuple of the URL without
    10  // the subdir and the subdir.
    11  //
    12  // ex:
    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"
    16  //
    17  func SourceDirSubdir(src string) (string, string) {
    18  
    19  	// URL might contains another url in query parameters
    20  	stop := len(src)
    21  	if idx := strings.Index(src, "?"); idx > -1 {
    22  		stop = idx
    23  	}
    24  
    25  	// Calculate an offset to avoid accidentally marking the scheme
    26  	// as the dir.
    27  	var offset int
    28  	if idx := strings.Index(src[:stop], "://"); idx > -1 {
    29  		offset = idx + 3
    30  	}
    31  
    32  	// First see if we even have an explicit subdir
    33  	idx := strings.Index(src[offset:stop], "//")
    34  	if idx == -1 {
    35  		return src, ""
    36  	}
    37  
    38  	idx += offset
    39  	subdir := src[idx+2:]
    40  	src = src[:idx]
    41  
    42  	// Next, check if we have query parameters and push them onto the
    43  	// URL.
    44  	if idx = strings.Index(subdir, "?"); idx > -1 {
    45  		query := subdir[idx:]
    46  		subdir = subdir[:idx]
    47  		src += query
    48  	}
    49  
    50  	return src, subdir
    51  }
    52  
    53  // SubdirGlob returns the actual subdir with globbing processed.
    54  //
    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.
    58  //
    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))
    62  	if err != nil {
    63  		return "", err
    64  	}
    65  
    66  	if len(matches) == 0 {
    67  		return "", fmt.Errorf("subdir %q not found", subDir)
    68  	}
    69  
    70  	if len(matches) > 1 {
    71  		return "", fmt.Errorf("subdir %q matches multiple paths", subDir)
    72  	}
    73  
    74  	return matches[0], nil
    75  }