history: don't import build package

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2026-02-11 10:29:47 +01:00
parent 06f438a4c8
commit 7899695fa6
8 changed files with 156 additions and 35 deletions
+9 -8
View File
@@ -24,6 +24,7 @@ import (
"github.com/docker/buildx/util/buildflags" "github.com/docker/buildx/util/buildflags"
"github.com/docker/buildx/util/platformutil" "github.com/docker/buildx/util/platformutil"
"github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/progress"
"github.com/docker/buildx/util/urlutil"
dockeropts "github.com/docker/cli/opts" dockeropts "github.com/docker/cli/opts"
hcl "github.com/hashicorp/hcl/v2" hcl "github.com/hashicorp/hcl/v2"
"github.com/moby/buildkit/client" "github.com/moby/buildkit/client"
@@ -1302,7 +1303,7 @@ func updateContext(t *build.Inputs, inp *Input) {
if strings.HasPrefix(v.Path, "cwd://") || strings.HasPrefix(v.Path, "target:") || strings.HasPrefix(v.Path, "docker-image:") { if strings.HasPrefix(v.Path, "cwd://") || strings.HasPrefix(v.Path, "target:") || strings.HasPrefix(v.Path, "docker-image:") {
continue continue
} }
if build.IsRemoteURL(v.Path) { if urlutil.IsRemoteURL(v.Path) {
continue continue
} }
st := llb.Scratch().File(llb.Copy(*inp.State, v.Path, "/"), llb.WithCustomNamef("set context %s to %s", k, v.Path)) st := llb.Scratch().File(llb.Copy(*inp.State, v.Path, "/"), llb.WithCustomNamef("set context %s to %s", k, v.Path))
@@ -1316,7 +1317,7 @@ func updateContext(t *build.Inputs, inp *Input) {
if strings.HasPrefix(t.ContextPath, "cwd://") { if strings.HasPrefix(t.ContextPath, "cwd://") {
return return
} }
if build.IsRemoteURL(t.ContextPath) { if urlutil.IsRemoteURL(t.ContextPath) {
return return
} }
st := llb.Scratch().File( st := llb.Scratch().File(
@@ -1329,10 +1330,10 @@ func updateContext(t *build.Inputs, inp *Input) {
} }
func isRemoteContext(t build.Inputs, inp *Input) bool { func isRemoteContext(t build.Inputs, inp *Input) bool {
if build.IsRemoteURL(t.ContextPath) { if urlutil.IsRemoteURL(t.ContextPath) {
return true return true
} }
if inp != nil && build.IsRemoteURL(inp.URL) && !strings.HasPrefix(t.ContextPath, "cwd://") { if inp != nil && urlutil.IsRemoteURL(inp.URL) && !strings.HasPrefix(t.ContextPath, "cwd://") {
return true return true
} }
return false return false
@@ -1362,7 +1363,7 @@ func collectLocalPaths(t build.Inputs) []string {
} }
func isLocalPath(p string) (string, bool) { func isLocalPath(p string) (string, bool) {
if build.IsRemoteURL(p) || strings.HasPrefix(p, "target:") || strings.HasPrefix(p, "docker-image:") { if urlutil.IsRemoteURL(p) || strings.HasPrefix(p, "target:") || strings.HasPrefix(p, "docker-image:") {
return "", false return "", false
} }
return strings.TrimPrefix(p, "cwd://"), true return strings.TrimPrefix(p, "cwd://"), true
@@ -1380,7 +1381,7 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
if t.Context != nil { if t.Context != nil {
contextPath = *t.Context contextPath = *t.Context
} }
if !strings.HasPrefix(contextPath, "cwd://") && !build.IsRemoteURL(contextPath) { if !strings.HasPrefix(contextPath, "cwd://") && !urlutil.IsRemoteURL(contextPath) {
contextPath = path.Clean(contextPath) contextPath = path.Clean(contextPath)
} }
dockerfilePath := "Dockerfile" dockerfilePath := "Dockerfile"
@@ -1410,7 +1411,7 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else if !build.IsRemoteURL(bi.DockerfilePath) && strings.HasPrefix(bi.ContextPath, "cwd://") && (inp != nil && build.IsRemoteURL(inp.URL)) { } else if !urlutil.IsRemoteURL(bi.DockerfilePath) && strings.HasPrefix(bi.ContextPath, "cwd://") && (inp != nil && urlutil.IsRemoteURL(inp.URL)) {
// We don't currently support reading a remote Dockerfile with a local // We don't currently support reading a remote Dockerfile with a local
// context when doing a remote invocation because we automatically // context when doing a remote invocation because we automatically
// derive the dockerfile from the context atm: // derive the dockerfile from the context atm:
@@ -1432,7 +1433,7 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
if v, ok := strings.CutPrefix(bi.ContextPath, "cwd://"); ok { if v, ok := strings.CutPrefix(bi.ContextPath, "cwd://"); ok {
bi.ContextPath = path.Clean(v) bi.ContextPath = path.Clean(v)
} }
if !build.IsRemoteURL(bi.ContextPath) && bi.ContextState == nil && !filepath.IsAbs(bi.DockerfilePath) { if !urlutil.IsRemoteURL(bi.ContextPath) && bi.ContextState == nil && !filepath.IsAbs(bi.DockerfilePath) {
bi.DockerfilePath = filepath.Join(bi.ContextPath, bi.DockerfilePath) bi.DockerfilePath = filepath.Join(bi.ContextPath, bi.DockerfilePath)
} }
for k, v := range bi.NamedContexts { for k, v := range bi.NamedContexts {
+3 -2
View File
@@ -6,6 +6,7 @@ import (
"github.com/docker/buildx/builder" "github.com/docker/buildx/builder"
"github.com/docker/buildx/localstate" "github.com/docker/buildx/localstate"
"github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/confutil"
"github.com/docker/buildx/util/urlutil"
"github.com/moby/buildkit/client" "github.com/moby/buildkit/client"
) )
@@ -16,13 +17,13 @@ func saveLocalState(so *client.SolveOpt, target string, opts Options, node build
} }
lp := opts.Inputs.ContextPath lp := opts.Inputs.ContextPath
dp := opts.Inputs.DockerfilePath dp := opts.Inputs.DockerfilePath
if dp != "" && !IsRemoteURL(lp) && lp != "-" && dp != "-" { if dp != "" && !urlutil.IsRemoteURL(lp) && lp != "-" && dp != "-" {
dp, err = filepath.Abs(dp) dp, err = filepath.Abs(dp)
if err != nil { if err != nil {
return err return err
} }
} }
if lp != "" && !IsRemoteURL(lp) && lp != "-" { if lp != "" && !urlutil.IsRemoteURL(lp) && lp != "-" {
lp, err = filepath.Abs(lp) lp, err = filepath.Abs(lp)
if err != nil { if err != nil {
return err return err
+4 -3
View File
@@ -31,6 +31,7 @@ import (
"github.com/docker/buildx/util/dockerutil" "github.com/docker/buildx/util/dockerutil"
"github.com/docker/buildx/util/osutil" "github.com/docker/buildx/util/osutil"
"github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/progress"
"github.com/docker/buildx/util/urlutil"
"github.com/moby/buildkit/client" "github.com/moby/buildkit/client"
"github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/client/ociindex" "github.com/moby/buildkit/client/ociindex"
@@ -700,7 +701,7 @@ func loadInputs(ctx context.Context, d *driver.DriverHandle, inp *Inputs, pw pro
dockerfileDir = filepath.Dir(inp.DockerfilePath) dockerfileDir = filepath.Dir(inp.DockerfilePath)
dockerfileName = filepath.Base(inp.DockerfilePath) dockerfileName = filepath.Base(inp.DockerfilePath)
} }
case IsRemoteURL(inp.ContextPath): case urlutil.IsRemoteURL(inp.ContextPath):
if inp.DockerfilePath == "-" { if inp.DockerfilePath == "-" {
dockerfileReader = inp.InStream.NewReadCloser() dockerfileReader = inp.InStream.NewReadCloser()
} else if filepath.IsAbs(inp.DockerfilePath) { } else if filepath.IsAbs(inp.DockerfilePath) {
@@ -741,7 +742,7 @@ func loadInputs(ctx context.Context, d *driver.DriverHandle, inp *Inputs, pw pro
dockerfileName = "Dockerfile" dockerfileName = "Dockerfile"
target.FrontendAttrs["dockerfilekey"] = "dockerfile" target.FrontendAttrs["dockerfilekey"] = "dockerfile"
} }
if isHTTPURL(inp.DockerfilePath) { if urlutil.IsHTTPURL(inp.DockerfilePath) {
dockerfileDir, err = createTempDockerfileFromURL(ctx, d, inp.DockerfilePath, pw) dockerfileDir, err = createTempDockerfileFromURL(ctx, d, inp.DockerfilePath, pw)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -811,7 +812,7 @@ func loadInputs(ctx context.Context, d *driver.DriverHandle, inp *Inputs, pw pro
continue continue
} }
if IsRemoteURL(v.Path) || strings.HasPrefix(v.Path, "docker-image://") || strings.HasPrefix(v.Path, "target:") { if urlutil.IsRemoteURL(v.Path) || strings.HasPrefix(v.Path, "docker-image://") || strings.HasPrefix(v.Path, "target:") {
target.FrontendAttrs["context:"+k] = v.Path target.FrontendAttrs["context:"+k] = v.Path
processGitURL(v.Path, "context:"+k, target, caps) processGitURL(v.Path, "context:"+k, target, caps)
continue continue
-18
View File
@@ -11,7 +11,6 @@ import (
"github.com/docker/buildx/driver" "github.com/docker/buildx/driver"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
"github.com/moby/buildkit/frontend/dockerfile/dfgitutil"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@@ -25,23 +24,6 @@ const (
mobyHostGatewayName = "host-gateway" mobyHostGatewayName = "host-gateway"
) )
// isHTTPURL returns true if the provided str is an HTTP(S) URL by checking if it
// has a http:// or https:// scheme. No validation is performed to verify if the
// URL is well-formed.
func isHTTPURL(str string) bool {
return strings.HasPrefix(str, "https://") || strings.HasPrefix(str, "http://")
}
func IsRemoteURL(c string) bool {
if isHTTPURL(c) {
return true
}
if _, ok, _ := dfgitutil.ParseGitRef(c); ok {
return true
}
return false
}
func isArchive(header []byte) bool { func isArchive(header []byte) bool {
for _, m := range [][]byte{ for _, m := range [][]byte{
{0x42, 0x5A, 0x68}, // bzip2 {0x42, 0x5A, 0x68}, // bzip2
+3 -2
View File
@@ -33,6 +33,7 @@ import (
"github.com/docker/buildx/util/osutil" "github.com/docker/buildx/util/osutil"
"github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/progress"
"github.com/docker/buildx/util/tracing" "github.com/docker/buildx/util/tracing"
"github.com/docker/buildx/util/urlutil"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/moby/buildkit/identity" "github.com/moby/buildkit/identity"
"github.com/moby/buildkit/session/auth/authprovider" "github.com/moby/buildkit/session/auth/authprovider"
@@ -613,11 +614,11 @@ func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string
// from the command line arguments. // from the command line arguments.
func bakeArgs(args []string) (url, cmdContext string, targets []string) { func bakeArgs(args []string) (url, cmdContext string, targets []string) {
cmdContext, targets = "cwd://", args cmdContext, targets = "cwd://", args
if len(targets) == 0 || !build.IsRemoteURL(targets[0]) { if len(targets) == 0 || !urlutil.IsRemoteURL(targets[0]) {
return url, cmdContext, targets return url, cmdContext, targets
} }
url, targets = targets[0], targets[1:] url, targets = targets[0], targets[1:]
if len(targets) == 0 || !build.IsRemoteURL(targets[0]) { if len(targets) == 0 || !urlutil.IsRemoteURL(targets[0]) {
return url, cmdContext, targets return url, cmdContext, targets
} }
cmdContext, targets = targets[0], targets[1:] cmdContext, targets = targets[0], targets[1:]
+2 -2
View File
@@ -13,9 +13,9 @@ import (
"sync" "sync"
"time" "time"
"github.com/docker/buildx/build"
"github.com/docker/buildx/builder" "github.com/docker/buildx/builder"
"github.com/docker/buildx/localstate" "github.com/docker/buildx/localstate"
"github.com/docker/buildx/util/urlutil"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
controlapi "github.com/moby/buildkit/api/services/control" controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/frontend/dockerfile/dfgitutil" "github.com/moby/buildkit/frontend/dockerfile/dfgitutil"
@@ -56,7 +56,7 @@ func BuildName(fattrs map[string]string, ls *localstate.State) string {
} }
var localPath string var localPath string
if ls != nil && !build.IsRemoteURL(ls.LocalPath) { if ls != nil && !urlutil.IsRemoteURL(ls.LocalPath) {
if ls.LocalPath != "" && ls.LocalPath != "-" { if ls.LocalPath != "" && ls.LocalPath != "-" {
localPath = filepath.ToSlash(ls.LocalPath) localPath = filepath.ToSlash(ls.LocalPath)
} }
+25
View File
@@ -0,0 +1,25 @@
package urlutil
import (
"strings"
"github.com/moby/buildkit/frontend/dockerfile/dfgitutil"
)
// IsHTTPURL returns true if the provided str is an HTTP(S) URL by checking if
// it has a http:// or https:// scheme. No validation is performed to verify if
// the URL is well-formed.
func IsHTTPURL(str string) bool {
return strings.HasPrefix(str, "https://") || strings.HasPrefix(str, "http://")
}
// IsRemoteURL returns true for HTTP(S) URLs and Git references.
func IsRemoteURL(c string) bool {
if IsHTTPURL(c) {
return true
}
if _, ok, _ := dfgitutil.ParseGitRef(c); ok {
return true
}
return false
}
+110
View File
@@ -0,0 +1,110 @@
package urlutil
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestIsHTTPURL(t *testing.T) {
tests := []struct {
name string
input string
want bool
}{
{
name: "https url",
input: "https://example.com/repo.git",
want: true,
},
{
name: "http url",
input: "http://example.com/repo.git",
want: true,
},
{
name: "http prefix only",
input: "http://",
want: true,
},
{
name: "non-http protocol",
input: "git://example.com/repo.git",
want: false,
},
{
name: "no protocol",
input: "example.com/repo.git",
want: false,
},
{
name: "uppercase protocol is not matched",
input: "HTTPS://example.com/repo.git",
want: false,
},
{
name: "leading whitespace does not match",
input: " https://example.com/repo.git",
want: false,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
require.Equal(t, tc.want, IsHTTPURL(tc.input))
})
}
}
func TestIsRemoteURL(t *testing.T) {
tests := []struct {
name string
input string
want bool
}{
{
name: "https url is remote",
input: "https://example.com/not-a-git-url",
want: true,
},
{
name: "http url is remote",
input: "http://example.com/path",
want: true,
},
{
name: "scp style git remote",
input: "git@github.com:moby/buildkit.git",
want: true,
},
{
name: "github shorthand git remote",
input: "github.com/moby/buildkit",
want: true,
},
{
name: "relative local path is not remote",
input: "./hack",
want: false,
},
{
name: "plain local path is not remote",
input: "hack/dockerfiles",
want: false,
},
{
name: "unknown protocol is not remote",
input: "docker-image://alpine",
want: false,
},
{
name: "empty is not remote",
input: "",
want: false,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
require.Equal(t, tc.want, IsRemoteURL(tc.input))
})
}
}