pkg/urlutil (despite its poorly chosen name) is not really intended as a generic
utility to handle URLs, and should only be used by the builder to handle (remote)
build contexts.
- IsURL() only does a very rudimentary check for http(s):// prefixes, without any
other validation, but due to its name may give incorrect expectations.
- IsGitURL() is written specifically with docker build remote git contexts in
mind, and has handling for backward-compatibility, where strings that are
not URLs, but start with "github.com/" are accepted.
Because of the above, this patch:
- moves the package inside builder/remotecontext, close to where it's intended
to be used (ideally this would be part of build/remotecontext itself, but this
package imports many other dependencies, which would introduce those as extra
dependencies in the CLI).
- deprecates pkg/urlutil, but adds aliases as there are some external consumers.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -16,6 +16,7 @@ import ( |
| 16 | 16 |
|
| 17 | 17 |
"github.com/docker/docker/builder" |
| 18 | 18 |
"github.com/docker/docker/builder/remotecontext" |
| 19 |
+ "github.com/docker/docker/builder/remotecontext/urlutil" |
|
| 19 | 20 |
"github.com/docker/docker/pkg/archive" |
| 20 | 21 |
"github.com/docker/docker/pkg/containerfs" |
| 21 | 22 |
"github.com/docker/docker/pkg/idtools" |
| ... | ... |
@@ -23,7 +24,6 @@ import ( |
| 23 | 23 |
"github.com/docker/docker/pkg/progress" |
| 24 | 24 |
"github.com/docker/docker/pkg/streamformatter" |
| 25 | 25 |
"github.com/docker/docker/pkg/system" |
| 26 |
- "github.com/docker/docker/pkg/urlutil" |
|
| 27 | 26 |
"github.com/moby/buildkit/frontend/dockerfile/instructions" |
| 28 | 27 |
specs "github.com/opencontainers/image-spec/specs-go/v1" |
| 29 | 28 |
"github.com/pkg/errors" |
| ... | ... |
@@ -11,9 +11,9 @@ import ( |
| 11 | 11 |
"github.com/containerd/continuity/driver" |
| 12 | 12 |
"github.com/docker/docker/api/types/backend" |
| 13 | 13 |
"github.com/docker/docker/builder" |
| 14 |
+ "github.com/docker/docker/builder/remotecontext/urlutil" |
|
| 14 | 15 |
"github.com/docker/docker/errdefs" |
| 15 | 16 |
"github.com/docker/docker/pkg/fileutils" |
| 16 |
- "github.com/docker/docker/pkg/urlutil" |
|
| 17 | 17 |
"github.com/moby/buildkit/frontend/dockerfile/dockerignore" |
| 18 | 18 |
"github.com/moby/buildkit/frontend/dockerfile/parser" |
| 19 | 19 |
"github.com/pkg/errors" |
| 20 | 20 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,46 @@ |
| 0 |
+// Package urlutil provides helper function to check urls kind. |
|
| 1 |
+// It supports http and git urls. |
|
| 2 |
+package urlutil // import "github.com/docker/docker/builder/remotecontext/urlutil" |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "regexp" |
|
| 6 |
+ "strings" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+var ( |
|
| 10 |
+ validPrefixes = map[string][]string{
|
|
| 11 |
+ "url": {"http://", "https://"},
|
|
| 12 |
+ |
|
| 13 |
+ // The github.com/ prefix is a special case used to treat context-paths |
|
| 14 |
+ // starting with `github.com` as a git URL if the given path does not |
|
| 15 |
+ // exist locally. The "github.com/" prefix is kept for backward compatibility, |
|
| 16 |
+ // and is a legacy feature. |
|
| 17 |
+ // |
|
| 18 |
+ // Going forward, no additional prefixes should be added, and users should |
|
| 19 |
+ // be encouraged to use explicit URLs (https://github.com/user/repo.git) instead. |
|
| 20 |
+ "git": {"git://", "github.com/", "git@"},
|
|
| 21 |
+ } |
|
| 22 |
+ urlPathWithFragmentSuffix = regexp.MustCompile(".git(?:#.+)?$")
|
|
| 23 |
+) |
|
| 24 |
+ |
|
| 25 |
+// IsURL returns true if the provided str is an HTTP(S) URL. |
|
| 26 |
+func IsURL(str string) bool {
|
|
| 27 |
+ return checkURL(str, "url") |
|
| 28 |
+} |
|
| 29 |
+ |
|
| 30 |
+// IsGitURL returns true if the provided str is a git repository URL. |
|
| 31 |
+func IsGitURL(str string) bool {
|
|
| 32 |
+ if IsURL(str) && urlPathWithFragmentSuffix.MatchString(str) {
|
|
| 33 |
+ return true |
|
| 34 |
+ } |
|
| 35 |
+ return checkURL(str, "git") |
|
| 36 |
+} |
|
| 37 |
+ |
|
| 38 |
+func checkURL(str, kind string) bool {
|
|
| 39 |
+ for _, prefix := range validPrefixes[kind] {
|
|
| 40 |
+ if strings.HasPrefix(str, prefix) {
|
|
| 41 |
+ return true |
|
| 42 |
+ } |
|
| 43 |
+ } |
|
| 44 |
+ return false |
|
| 45 |
+} |
| 0 | 46 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,41 @@ |
| 0 |
+package urlutil // import "github.com/docker/docker/builder/remotecontext/urlutil" |
|
| 1 |
+ |
|
| 2 |
+import "testing" |
|
| 3 |
+ |
|
| 4 |
+var ( |
|
| 5 |
+ gitUrls = []string{
|
|
| 6 |
+ "git://github.com/docker/docker", |
|
| 7 |
+ "git@github.com:docker/docker.git", |
|
| 8 |
+ "git@bitbucket.org:atlassianlabs/atlassian-docker.git", |
|
| 9 |
+ "https://github.com/docker/docker.git", |
|
| 10 |
+ "http://github.com/docker/docker.git", |
|
| 11 |
+ "http://github.com/docker/docker.git#branch", |
|
| 12 |
+ "http://github.com/docker/docker.git#:dir", |
|
| 13 |
+ } |
|
| 14 |
+ incompleteGitUrls = []string{
|
|
| 15 |
+ "github.com/docker/docker", |
|
| 16 |
+ } |
|
| 17 |
+ invalidGitUrls = []string{
|
|
| 18 |
+ "http://github.com/docker/docker.git:#branch", |
|
| 19 |
+ } |
|
| 20 |
+) |
|
| 21 |
+ |
|
| 22 |
+func TestIsGIT(t *testing.T) {
|
|
| 23 |
+ for _, url := range gitUrls {
|
|
| 24 |
+ if !IsGitURL(url) {
|
|
| 25 |
+ t.Fatalf("%q should be detected as valid Git url", url)
|
|
| 26 |
+ } |
|
| 27 |
+ } |
|
| 28 |
+ |
|
| 29 |
+ for _, url := range incompleteGitUrls {
|
|
| 30 |
+ if !IsGitURL(url) {
|
|
| 31 |
+ t.Fatalf("%q should be detected as valid Git url", url)
|
|
| 32 |
+ } |
|
| 33 |
+ } |
|
| 34 |
+ |
|
| 35 |
+ for _, url := range invalidGitUrls {
|
|
| 36 |
+ if IsGitURL(url) {
|
|
| 37 |
+ t.Fatalf("%q should not be detected as valid Git prefix", url)
|
|
| 38 |
+ } |
|
| 39 |
+ } |
|
| 40 |
+} |
| ... | ... |
@@ -251,6 +251,12 @@ Function Validate-PkgImports($headCommit, $upstreamCommit) {
|
| 251 | 251 |
$files=@(); $files = Invoke-Expression "git diff $upstreamCommit...$headCommit --diff-filter=ACMR --name-only -- `'pkg\*.go`'" |
| 252 | 252 |
$badFiles=@(); $files | ForEach-Object{
|
| 253 | 253 |
$file=$_ |
| 254 |
+ if ($file -eq "pkg\urlutil\deprecated.go") {
|
|
| 255 |
+ # pkg/urlutil is deprecated, but has a temporary alias to help migration, |
|
| 256 |
+ # see https://github.com/moby/moby/pull/43477 |
|
| 257 |
+ # TODO(thaJeztah) remove this exception once pkg/urlutil aliases are removed |
|
| 258 |
+ return |
|
| 259 |
+ } |
|
| 254 | 260 |
# For the current changed file, get its list of dependencies, sorted and uniqued. |
| 255 | 261 |
$imports = Invoke-Expression "go list -e -f `'{{ .Deps }}`' $file"
|
| 256 | 262 |
if ($LASTEXITCODE -ne 0) { Throw "Failed go list for dependencies on $file" }
|
| ... | ... |
@@ -10,6 +10,12 @@ unset IFS |
| 10 | 10 |
|
| 11 | 11 |
badFiles=() |
| 12 | 12 |
for f in "${files[@]}"; do
|
| 13 |
+ if [ "$f" = "pkg/urlutil/deprecated.go" ]; then |
|
| 14 |
+ # pkg/urlutil is deprecated, but has a temporary alias to help migration, |
|
| 15 |
+ # see https://github.com/moby/moby/pull/43477 |
|
| 16 |
+ # TODO(thaJeztah) remove this exception once pkg/urlutil aliases are removed |
|
| 17 |
+ continue |
|
| 18 |
+ fi |
|
| 13 | 19 |
IFS=$'\n' |
| 14 | 20 |
badImports=($(go list -e -f '{{ join .Deps "\n" }}' "$f" | sort -u | grep -vE '^github.com/docker/docker/pkg/' | grep -vE '^github.com/docker/docker/vendor' | grep -E '^github.com/docker/docker' || true))
|
| 15 | 21 |
unset IFS |
| 16 | 22 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 0 |
+package urlutil // import "github.com/docker/docker/pkg/urlutil" |
|
| 1 |
+ |
|
| 2 |
+import "github.com/docker/docker/builder/remotecontext/urlutil" |
|
| 3 |
+ |
|
| 4 |
+// IsURL returns true if the provided str is an HTTP(S) URL. |
|
| 5 |
+// |
|
| 6 |
+// Deprecated: use github.com/docker/docker/builder/remotecontext/urlutil.IsURL |
|
| 7 |
+// to detect build-context type, or use strings.HasPrefix() to check if the |
|
| 8 |
+// string has a https:// or http:// prefix. |
|
| 9 |
+func IsURL(str string) bool {
|
|
| 10 |
+ // TODO(thaJeztah) when removing this alias, remove the exception from hack/validate/pkg-imports and hack/make.ps1 (Validate-PkgImports) |
|
| 11 |
+ return urlutil.IsURL(str) |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 14 |
+// IsGitURL returns true if the provided str is a git repository URL. |
|
| 15 |
+// |
|
| 16 |
+// Deprecated: use github.com/docker/docker/builder/remotecontext/urlutil.IsGitURL |
|
| 17 |
+func IsGitURL(str string) bool {
|
|
| 18 |
+ // TODO(thaJeztah) when removing this alias, remove the exception from hack/validate/pkg-imports and hack/make.ps1 (Validate-PkgImports) |
|
| 19 |
+ return urlutil.IsGitURL(str) |
|
| 20 |
+} |
| 0 | 21 |
deleted file mode 100644 |
| ... | ... |
@@ -1,46 +0,0 @@ |
| 1 |
-// Package urlutil provides helper function to check urls kind. |
|
| 2 |
-// It supports http and git urls. |
|
| 3 |
-package urlutil // import "github.com/docker/docker/pkg/urlutil" |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "regexp" |
|
| 7 |
- "strings" |
|
| 8 |
-) |
|
| 9 |
- |
|
| 10 |
-var ( |
|
| 11 |
- validPrefixes = map[string][]string{
|
|
| 12 |
- "url": {"http://", "https://"},
|
|
| 13 |
- |
|
| 14 |
- // The github.com/ prefix is a special case used to treat context-paths |
|
| 15 |
- // starting with `github.com` as a git URL if the given path does not |
|
| 16 |
- // exist locally. The "github.com/" prefix is kept for backward compatibility, |
|
| 17 |
- // and is a legacy feature. |
|
| 18 |
- // |
|
| 19 |
- // Going forward, no additional prefixes should be added, and users should |
|
| 20 |
- // be encouraged to use explicit URLs (https://github.com/user/repo.git) instead. |
|
| 21 |
- "git": {"git://", "github.com/", "git@"},
|
|
| 22 |
- } |
|
| 23 |
- urlPathWithFragmentSuffix = regexp.MustCompile(".git(?:#.+)?$")
|
|
| 24 |
-) |
|
| 25 |
- |
|
| 26 |
-// IsURL returns true if the provided str is an HTTP(S) URL. |
|
| 27 |
-func IsURL(str string) bool {
|
|
| 28 |
- return checkURL(str, "url") |
|
| 29 |
-} |
|
| 30 |
- |
|
| 31 |
-// IsGitURL returns true if the provided str is a git repository URL. |
|
| 32 |
-func IsGitURL(str string) bool {
|
|
| 33 |
- if IsURL(str) && urlPathWithFragmentSuffix.MatchString(str) {
|
|
| 34 |
- return true |
|
| 35 |
- } |
|
| 36 |
- return checkURL(str, "git") |
|
| 37 |
-} |
|
| 38 |
- |
|
| 39 |
-func checkURL(str, kind string) bool {
|
|
| 40 |
- for _, prefix := range validPrefixes[kind] {
|
|
| 41 |
- if strings.HasPrefix(str, prefix) {
|
|
| 42 |
- return true |
|
| 43 |
- } |
|
| 44 |
- } |
|
| 45 |
- return false |
|
| 46 |
-} |
| 47 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,41 +0,0 @@ |
| 1 |
-package urlutil // import "github.com/docker/docker/pkg/urlutil" |
|
| 2 |
- |
|
| 3 |
-import "testing" |
|
| 4 |
- |
|
| 5 |
-var ( |
|
| 6 |
- gitUrls = []string{
|
|
| 7 |
- "git://github.com/docker/docker", |
|
| 8 |
- "git@github.com:docker/docker.git", |
|
| 9 |
- "git@bitbucket.org:atlassianlabs/atlassian-docker.git", |
|
| 10 |
- "https://github.com/docker/docker.git", |
|
| 11 |
- "http://github.com/docker/docker.git", |
|
| 12 |
- "http://github.com/docker/docker.git#branch", |
|
| 13 |
- "http://github.com/docker/docker.git#:dir", |
|
| 14 |
- } |
|
| 15 |
- incompleteGitUrls = []string{
|
|
| 16 |
- "github.com/docker/docker", |
|
| 17 |
- } |
|
| 18 |
- invalidGitUrls = []string{
|
|
| 19 |
- "http://github.com/docker/docker.git:#branch", |
|
| 20 |
- } |
|
| 21 |
-) |
|
| 22 |
- |
|
| 23 |
-func TestIsGIT(t *testing.T) {
|
|
| 24 |
- for _, url := range gitUrls {
|
|
| 25 |
- if !IsGitURL(url) {
|
|
| 26 |
- t.Fatalf("%q should be detected as valid Git url", url)
|
|
| 27 |
- } |
|
| 28 |
- } |
|
| 29 |
- |
|
| 30 |
- for _, url := range incompleteGitUrls {
|
|
| 31 |
- if !IsGitURL(url) {
|
|
| 32 |
- t.Fatalf("%q should be detected as valid Git url", url)
|
|
| 33 |
- } |
|
| 34 |
- } |
|
| 35 |
- |
|
| 36 |
- for _, url := range invalidGitUrls {
|
|
| 37 |
- if IsGitURL(url) {
|
|
| 38 |
- t.Fatalf("%q should not be detected as valid Git prefix", url)
|
|
| 39 |
- } |
|
| 40 |
- } |
|
| 41 |
-} |