Skip to content

Commit 67687bd

Browse files
committed
usage, completion: assume executable is always lowercase
When running on a case-insensitive platform / filesystem, the user can invoke the executable using any case (e.g., "bUiLdX"). In situations where buildx is running standalone, we use os.Args to determine the name of the executable, and this information is used by Cobra to print "Usage" output as well as generating the shell-completion scripts. Unfortunately, neither [os.Executable] nor [os.Stat] provide information about the actual name of the executable, and the "correct" solution would be to use [os.File.Readdirnames], which is a rather heavy hammer to use just for this. This patch assumes the executable to be named lowercase, regardless of how it's invoked, on macOS and Windows (usually case-insensitive platforms). 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. Before this patch: ./bin/build/bUiLdX --help | head -n 5 Extended build capabilities with BuildKit Usage: bUiLdX bUiLdX [command] ./bin/build/bUiLdX completion bash | head -n 3 # bash completion V2 for bUiLdX -*- shell-script -*- __bUiLdX_debug() With this patch applied: ./bin/build/bUiLdX --help | head -n 5 Extended build capabilities with BuildKit Usage: buildx buildx [command] ./bin/build/bUiLdX completion bash | head -n 3 # bash completion V2 for buildx -*- shell-script -*- __buildx_debug() [os.Executable]: https://pkg.go.dev/os#Executable [os.Stat]: https://pkg.go.dev/os#Stat [os.File.Readdirnames]: https://pkg.go.dev/os#File.Readdirnames Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent cf8bf9e commit 67687bd

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

cmd/buildx/main.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
"runtime"
9+
"strings"
810

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

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

0 commit comments

Comments
 (0)