Skip to content

Commit

Permalink
feat: adopt delete app confirmation to new prompt util (argoproj#20664)
Browse files Browse the repository at this point in the history
* feat: adopt delete app confirmation to new prompt util

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: adopt delete app confirmation to new prompt util

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: adopt delete app confirmation to new prompt util

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: adopt delete app confirmation to new prompt util

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* chore: remove type where it is not needed

Signed-off-by: pashakostohrys <pavel@codefresh.io>

---------

Signed-off-by: pashakostohrys <pavel@codefresh.io>
Signed-off-by: Adrian Aneci <aneci@adobe.com>
  • Loading branch information
pasha-codefresh authored and adriananeci committed Dec 4, 2024
1 parent 585bb71 commit a774eed
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 29 deletions.
49 changes: 20 additions & 29 deletions cmd/argocd/commands/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1443,8 +1443,6 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.
conn, appIf := acdClient.NewApplicationClientOrDie()
defer argoio.Close(conn)
var isTerminal bool = isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd())
var isConfirmAll bool = false
numOfApps := len(args)
promptFlag := c.Flag("yes")
if promptFlag.Changed && promptFlag.Value.String() == "true" {
noPrompt = true
Expand All @@ -1457,6 +1455,16 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.
appNames = args
}

numOfApps := len(appNames)

// This is for backward compatibility,
// before we showed the prompts only when condition cascade && isTerminal && !noPrompt is true
promptUtil := utils.NewPrompt(cascade && isTerminal && !noPrompt)
var (
confirmAll = false
confirm = false
)

for _, appFullName := range appNames {
appName, appNs := argo.ParseFromQualifiedName(appFullName, appNamespace)
appDeleteReq := application.ApplicationDeleteRequest{
Expand All @@ -1469,38 +1477,21 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.
if c.Flag("propagation-policy").Changed {
appDeleteReq.PropagationPolicy = &propagationPolicy
}
if cascade && isTerminal && !noPrompt {
var lowercaseAnswer string
if numOfApps == 1 {
lowercaseAnswer = cli.AskToProceedS("Are you sure you want to delete '" + appFullName + "' and all its resources? [y/n] ")
} else {
if !isConfirmAll {
lowercaseAnswer = cli.AskToProceedS("Are you sure you want to delete '" + appFullName + "' and all its resources? [y/n/A] where 'A' is to delete all specified apps and their resources without prompting ")
if lowercaseAnswer == "a" {
lowercaseAnswer = "y"
isConfirmAll = true
}
} else {
lowercaseAnswer = "y"
}
}
if lowercaseAnswer == "y" {
_, err := appIf.Delete(ctx, &appDeleteReq)
errors.CheckError(err)
if wait {
checkForDeleteEvent(ctx, acdClient, appFullName)
}
fmt.Printf("application '%s' deleted\n", appFullName)
} else {
fmt.Println("The command to delete '" + appFullName + "' was cancelled.")
}
} else {
messageForSingle := "Are you sure you want to delete '" + appFullName + "' and all its resources? [y/n] "
messageForAll := "Are you sure you want to delete '" + appFullName + "' and all its resources? [y/n/a] where 'a' is to delete all specified apps and their resources without prompting "

if !confirmAll {
confirm, confirmAll = promptUtil.ConfirmBaseOnCount(messageForSingle, messageForAll, numOfApps)
}
if confirm || confirmAll {
_, err := appIf.Delete(ctx, &appDeleteReq)
errors.CheckError(err)

if wait {
checkForDeleteEvent(ctx, acdClient, appFullName)
}
fmt.Printf("application '%s' deleted\n", appFullName)
} else {
fmt.Println("The command to delete '" + appFullName + "' was cancelled.")
}
}
},
Expand Down
37 changes: 37 additions & 0 deletions cmd/argocd/commands/utils/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,40 @@ func (p *Prompt) Confirm(message string) bool {

return cli.AskToProceed(message)
}

// ConfirmAll asks the user to confirm an action. If prompts are disabled, it will return true.
// support y/n and A, which means all
// return if confirm and if all
func (p *Prompt) ConfirmAll(message string) (bool, bool) {
if !p.enabled {
return true, true
}

result := cli.AskToProceedS(message)

if result == "a" {
return true, true
}

if result == "y" {
return true, false
}

return false, false
}

func (p *Prompt) ConfirmBaseOnCount(messageForSingle string, messageForArray string, count int) (bool, bool) {
if !p.enabled {
return true, true
}

if count == 0 {
return true, true
}

if count == 1 {
return p.Confirm(messageForSingle), true
}

return p.ConfirmAll(messageForArray)
}
27 changes: 27 additions & 0 deletions cmd/argocd/commands/utils/prompt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,30 @@ func TestConfirm_PromptsEnabled_False(t *testing.T) {
prompt := NewPrompt(false)
assert.True(t, prompt.Confirm("Are you sure you want to run this command? (y/n) "))
}

// Returns true, true when prompt is disabled
func TestConfirmAllPromptDisabled(t *testing.T) {
p := &Prompt{enabled: false}
result1, result2 := p.ConfirmAll("Proceed?")
if result1 != true || result2 != true {
t.Errorf("Expected (true, true), got (%v, %v)", result1, result2)
}
}

func TestConfirmBaseOnCountPromptDisabled(t *testing.T) {
p := &Prompt{enabled: false}
result1, result2 := p.ConfirmBaseOnCount("Proceed?", "Process all?", 2)

if result1 != true || result2 != true {
t.Errorf("Expected (true, true), got (%v, %v)", result1, result2)
}
}

func TestConfirmBaseOnCountZeroApps(t *testing.T) {
p := &Prompt{enabled: true}
result1, result2 := p.ConfirmBaseOnCount("Proceed?", "Process all?", 0)

if result1 != true || result2 != true {
t.Errorf("Expected (true, true), got (%v, %v)", result1, result2)
}
}

0 comments on commit a774eed

Please sign in to comment.