github.com/rawahars/moby@v24.0.4+incompatible/builder/remotecontext/urlutil/urlutil.go (about)

     1  // Package urlutil provides helper function to check if a given build-context
     2  // location should be considered a URL or a remote Git repository.
     3  //
     4  // This package is specifically written for use with docker build contexts, and
     5  // should not be used as a general-purpose utility.
     6  package urlutil // import "github.com/docker/docker/builder/remotecontext/urlutil"
     7  
     8  import (
     9  	"regexp"
    10  	"strings"
    11  )
    12  
    13  // urlPathWithFragmentSuffix matches fragments to use as Git reference and build
    14  // context from the Git repository. See IsGitURL for details.
    15  var urlPathWithFragmentSuffix = regexp.MustCompile(".git(?:#.+)?$")
    16  
    17  // IsURL returns true if the provided str is an HTTP(S) URL by checking if it
    18  // has a http:// or https:// scheme. No validation is performed to verify if the
    19  // URL is well-formed.
    20  func IsURL(str string) bool {
    21  	return strings.HasPrefix(str, "https://") || strings.HasPrefix(str, "http://")
    22  }
    23  
    24  // IsGitURL returns true if the provided str is a remote git repository "URL".
    25  //
    26  // This function only performs a rudimentary check (no validation is performed
    27  // to ensure the URL is well-formed), and is written specifically for use with
    28  // docker build, with some logic for backward compatibility with older versions
    29  // of docker: do not use this function as a general-purpose utility.
    30  //
    31  // The following patterns are considered to be a Git URL:
    32  //
    33  //   - https://(.*).git(?:#.+)?$  git repository URL with optional fragment, as known to be used by GitHub and GitLab.
    34  //   - http://(.*).git(?:#.+)?$   same, but non-TLS
    35  //   - git://(.*)                 URLs using git:// scheme
    36  //   - git@(.*)
    37  //   - github.com/                see description below
    38  //
    39  // The github.com/ prefix is a special case used to treat context-paths
    40  // starting with "github.com/" as a git URL if the given path does not
    41  // exist locally. The "github.com/" prefix is kept for backward compatibility,
    42  // and is a legacy feature.
    43  //
    44  // Going forward, no additional prefixes should be added, and users should
    45  // be encouraged to use explicit URLs (https://github.com/user/repo.git) instead.
    46  //
    47  // Note that IsGitURL does not check if "github.com/" prefixes exist as a local
    48  // path. Code using this function should check if the path exists locally before
    49  // using it as a URL.
    50  //
    51  // # Fragments
    52  //
    53  // Git URLs accept context configuration in their fragment section, separated by
    54  // a colon (`:`). The first part represents the reference to check out, and can
    55  // be either a branch, a tag, or a remote reference. The second part represents
    56  // a subdirectory inside the repository to use as the build context.
    57  //
    58  // For example,the following URL uses a directory named "docker" in the branch
    59  // "container" in the https://github.com/myorg/my-repo.git repository:
    60  //
    61  // https://github.com/myorg/my-repo.git#container:docker
    62  //
    63  // The following table represents all the valid suffixes with their build
    64  // contexts:
    65  //
    66  // | Build Syntax Suffix            | Git reference used   | Build Context Used |
    67  // |--------------------------------|----------------------|--------------------|
    68  // | my-repo.git                    | refs/heads/master    | /                  |
    69  // | my-repo.git#mytag              | refs/tags/my-tag     | /                  |
    70  // | my-repo.git#mybranch           | refs/heads/my-branch | /                  |
    71  // | my-repo.git#pull/42/head       | refs/pull/42/head    | /                  |
    72  // | my-repo.git#:directory         | refs/heads/master    | /directory         |
    73  // | my-repo.git#master:directory   | refs/heads/master    | /directory         |
    74  // | my-repo.git#mytag:directory    | refs/tags/my-tag     | /directory         |
    75  // | my-repo.git#mybranch:directory | refs/heads/my-branch | /directory         |
    76  func IsGitURL(str string) bool {
    77  	if IsURL(str) && urlPathWithFragmentSuffix.MatchString(str) {
    78  		return true
    79  	}
    80  	for _, prefix := range []string{"git://", "github.com/", "git@"} {
    81  		if strings.HasPrefix(str, prefix) {
    82  			return true
    83  		}
    84  	}
    85  	return false
    86  }