urlutil.go 3.9 KB

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