Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions cmd/buildx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"

"github.com/docker/buildx/commands"
controllererrors "github.com/docker/buildx/controller/errdefs"
Expand Down Expand Up @@ -43,6 +45,30 @@ func runStandalone(cmd *command.DockerCli) error {
defer flushMetrics(cmd)

executable := os.Args[0]
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
// Note that we're cutting some corners here. The intent here
// is for both "usage" and shell-completion scripts to use the
// name of the executable with its actual (lower, upper) case.
// However, on case-insensitive platforms, the user can invoke
// the executable using any case (e.g., "bUiLdX").
//
// Unfortunately, neither [os.Executable] nor [os.Stat] provide
// this information, and the "correct" solution would be to use
// [os.File.Readdirnames], which is a rather heavy hammer to use
// just for this.
//
// So, on macOS and Windows (usually case-insensitive platforms)
// we assume the executable is always lower-case, but it's worth
// noting that there's a corner-case to this corner-case; both
// Windows and macOS can be configured to use a case-sensitive
// filesystem (on Windows, this can be configured per-Directory).
// If that is the case, and the executable is not lowercase, the
// generated shell-completion script will be invalid.
//
// Let's assume that's not the case, and that the user did not
// rename the executable to anything uppercase.
executable = strings.ToLower(executable)
}
rootCmd := commands.NewRootCmd(filepath.Base(executable), false, cmd)
return rootCmd.Execute()
}
Expand Down