mirror of https://github.com/databricks/cli.git
Do not allow input prompts in Git Bash terminal (#1069)
## Changes Likely due to fact that Git Bash does not correctly support ANSI escape sequences, we cannot use `promptui` package there. See known issues: - https://github.com/manifoldco/promptui/issues/208 - https://github.com/chzyer/readline/issues/191
This commit is contained in:
parent
4765493f18
commit
6dd6899b52
|
@ -131,7 +131,7 @@ See https://docs.databricks.com/en/dev-tools/bundles/templates.html for more inf
|
||||||
templatePath = args[0]
|
templatePath = args[0]
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
if !cmdio.IsOutTTY(ctx) || !cmdio.IsInTTY(ctx) {
|
if !cmdio.IsPromptSupported(ctx) {
|
||||||
return errors.New("please specify a template")
|
return errors.New("please specify a template")
|
||||||
}
|
}
|
||||||
templatePath, err = cmdio.AskSelect(ctx, "Template to use", nativeTemplateOptions())
|
templatePath, err = cmdio.AskSelect(ctx, "Template to use", nativeTemplateOptions())
|
||||||
|
|
|
@ -45,7 +45,7 @@ func newRunCommand() *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no arguments are specified, prompt the user to select something to run.
|
// If no arguments are specified, prompt the user to select something to run.
|
||||||
if len(args) == 0 && cmdio.IsInteractive(ctx) {
|
if len(args) == 0 && cmdio.IsPromptSupported(ctx) {
|
||||||
// Invert completions from KEY -> NAME, to NAME -> KEY.
|
// Invert completions from KEY -> NAME, to NAME -> KEY.
|
||||||
inv := make(map[string]string)
|
inv := make(map[string]string)
|
||||||
for k, v := range run.ResourceCompletionMap(b) {
|
for k, v := range run.ResourceCompletionMap(b) {
|
||||||
|
|
|
@ -157,7 +157,7 @@ func (i *installer) recordVersion(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *installer) login(ctx context.Context) (*databricks.WorkspaceClient, error) {
|
func (i *installer) login(ctx context.Context) (*databricks.WorkspaceClient, error) {
|
||||||
if !cmdio.IsInteractive(ctx) {
|
if !cmdio.IsPromptSupported(ctx) {
|
||||||
log.Debugf(ctx, "Skipping workspace profile prompts in non-interactive mode")
|
log.Debugf(ctx, "Skipping workspace profile prompts in non-interactive mode")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (lc *loginConfig) askWorkspaceProfile(ctx context.Context, cfg *config.Conf
|
||||||
lc.WorkspaceProfile = cfg.Profile
|
lc.WorkspaceProfile = cfg.Profile
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !cmdio.IsInteractive(ctx) {
|
if !cmdio.IsPromptSupported(ctx) {
|
||||||
return ErrNotInTTY
|
return ErrNotInTTY
|
||||||
}
|
}
|
||||||
lc.WorkspaceProfile, err = root.AskForWorkspaceProfile(ctx)
|
lc.WorkspaceProfile, err = root.AskForWorkspaceProfile(ctx)
|
||||||
|
@ -66,7 +66,7 @@ func (lc *loginConfig) askCluster(ctx context.Context, w *databricks.WorkspaceCl
|
||||||
lc.ClusterID = w.Config.ClusterID
|
lc.ClusterID = w.Config.ClusterID
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !cmdio.IsInteractive(ctx) {
|
if !cmdio.IsPromptSupported(ctx) {
|
||||||
return ErrNotInTTY
|
return ErrNotInTTY
|
||||||
}
|
}
|
||||||
clusterID, err := cfgpickers.AskForCluster(ctx, w,
|
clusterID, err := cfgpickers.AskForCluster(ctx, w,
|
||||||
|
@ -87,7 +87,7 @@ func (lc *loginConfig) askWarehouse(ctx context.Context, w *databricks.Workspace
|
||||||
lc.WarehouseID = w.Config.WarehouseID
|
lc.WarehouseID = w.Config.WarehouseID
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !cmdio.IsInteractive(ctx) {
|
if !cmdio.IsPromptSupported(ctx) {
|
||||||
return ErrNotInTTY
|
return ErrNotInTTY
|
||||||
}
|
}
|
||||||
lc.WarehouseID, err = cfgpickers.AskForWarehouse(ctx, w,
|
lc.WarehouseID, err = cfgpickers.AskForWarehouse(ctx, w,
|
||||||
|
@ -99,7 +99,7 @@ func (lc *loginConfig) askAccountProfile(ctx context.Context, cfg *config.Config
|
||||||
if !lc.HasAccountLevelCommands() {
|
if !lc.HasAccountLevelCommands() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !cmdio.IsInteractive(ctx) {
|
if !cmdio.IsPromptSupported(ctx) {
|
||||||
return ErrNotInTTY
|
return ErrNotInTTY
|
||||||
}
|
}
|
||||||
lc.AccountProfile, err = root.AskForAccountProfile(ctx)
|
lc.AccountProfile, err = root.AskForAccountProfile(ctx)
|
||||||
|
|
|
@ -41,7 +41,7 @@ func accountClientOrPrompt(ctx context.Context, cfg *config.Config, allowPrompt
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt := false
|
prompt := false
|
||||||
if allowPrompt && err != nil && cmdio.IsInteractive(ctx) {
|
if allowPrompt && err != nil && cmdio.IsPromptSupported(ctx) {
|
||||||
// Prompt to select a profile if the current configuration is not an account client.
|
// Prompt to select a profile if the current configuration is not an account client.
|
||||||
prompt = prompt || errors.Is(err, databricks.ErrNotAccountClient)
|
prompt = prompt || errors.Is(err, databricks.ErrNotAccountClient)
|
||||||
// Prompt to select a profile if the current configuration doesn't resolve to a credential provider.
|
// Prompt to select a profile if the current configuration doesn't resolve to a credential provider.
|
||||||
|
@ -109,7 +109,7 @@ func workspaceClientOrPrompt(ctx context.Context, cfg *config.Config, allowPromp
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt := false
|
prompt := false
|
||||||
if allowPrompt && err != nil && cmdio.IsInteractive(ctx) {
|
if allowPrompt && err != nil && cmdio.IsPromptSupported(ctx) {
|
||||||
// Prompt to select a profile if the current configuration is not a workspace client.
|
// Prompt to select a profile if the current configuration is not a workspace client.
|
||||||
prompt = prompt || errors.Is(err, databricks.ErrNotWorkspaceClient)
|
prompt = prompt || errors.Is(err, databricks.ErrNotWorkspaceClient)
|
||||||
// Prompt to select a profile if the current configuration doesn't resolve to a credential provider.
|
// Prompt to select a profile if the current configuration doesn't resolve to a credential provider.
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/briandowns/spinner"
|
"github.com/briandowns/spinner"
|
||||||
|
"github.com/databricks/cli/libs/env"
|
||||||
"github.com/databricks/cli/libs/flags"
|
"github.com/databricks/cli/libs/flags"
|
||||||
"github.com/manifoldco/promptui"
|
"github.com/manifoldco/promptui"
|
||||||
"github.com/mattn/go-isatty"
|
"github.com/mattn/go-isatty"
|
||||||
|
@ -88,6 +89,30 @@ func (c *cmdIO) IsTTY() bool {
|
||||||
return isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd)
|
return isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsPromptSupported(ctx context.Context) bool {
|
||||||
|
// We do not allow prompting in non-interactive mode and in Git Bash on Windows.
|
||||||
|
// Likely due to fact that Git Bash does not (correctly support ANSI escape sequences,
|
||||||
|
// we cannot use promptui package there.
|
||||||
|
// See known issues:
|
||||||
|
// - https://github.com/manifoldco/promptui/issues/208
|
||||||
|
// - https://github.com/chzyer/readline/issues/191
|
||||||
|
// We also do not allow prompting in non-interactive mode,
|
||||||
|
// because it's not possible to read from stdin in non-interactive mode.
|
||||||
|
return (IsInteractive(ctx) || (IsOutTTY(ctx) && IsInTTY(ctx))) && !IsGitBash(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsGitBash(ctx context.Context) bool {
|
||||||
|
// Check if the MSYSTEM environment variable is set to "MINGW64"
|
||||||
|
msystem := env.Get(ctx, "MSYSTEM")
|
||||||
|
if strings.EqualFold(msystem, "MINGW64") {
|
||||||
|
// Check for typical Git Bash env variable for prompts
|
||||||
|
ps1 := env.Get(ctx, "PS1")
|
||||||
|
return strings.Contains(ps1, "MINGW") || strings.Contains(ps1, "MSYSTEM")
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func Render(ctx context.Context, v any) error {
|
func Render(ctx context.Context, v any) error {
|
||||||
c := fromContext(ctx)
|
c := fromContext(ctx)
|
||||||
return RenderWithTemplate(ctx, v, c.template)
|
return RenderWithTemplate(ctx, v, c.template)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package cmdio
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/databricks/cli/libs/env"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIsPromptSupportedFalseForGitBash(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, _ = SetupTest(ctx)
|
||||||
|
|
||||||
|
assert.True(t, IsPromptSupported(ctx))
|
||||||
|
|
||||||
|
ctx = env.Set(ctx, "MSYSTEM", "MINGW64")
|
||||||
|
ctx = env.Set(ctx, "TERM", "xterm")
|
||||||
|
ctx = env.Set(ctx, "PS1", "\\[\033]0;$TITLEPREFIX:$PWD\007\\]\n\\[\033[32m\\]\\u@\\h \\[\033[35m\\]$MSYSTEM \\[\033[33m\\]\\w\\[\033[36m\\]`__git_ps1`\\[\033[0m\\]\n$")
|
||||||
|
assert.False(t, IsPromptSupported(ctx))
|
||||||
|
}
|
|
@ -212,7 +212,7 @@ func (c *config) promptForValues(r *renderer) error {
|
||||||
// Prompt user for any missing config values. Assign default values if
|
// Prompt user for any missing config values. Assign default values if
|
||||||
// terminal is not TTY
|
// terminal is not TTY
|
||||||
func (c *config) promptOrAssignDefaultValues(r *renderer) error {
|
func (c *config) promptOrAssignDefaultValues(r *renderer) error {
|
||||||
if cmdio.IsOutTTY(c.ctx) && cmdio.IsInTTY(c.ctx) {
|
if cmdio.IsPromptSupported(c.ctx) {
|
||||||
return c.promptForValues(r)
|
return c.promptForValues(r)
|
||||||
}
|
}
|
||||||
return c.assignDefaultValues(r)
|
return c.assignDefaultValues(r)
|
||||||
|
|
Loading…
Reference in New Issue