github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/cmd/helpers.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package cmd
     5  
     6  import (
     7  	"bufio"
     8  	"fmt"
     9  	"io"
    10  	"strings"
    11  
    12  	"github.com/juju/cmd/v3"
    13  	"github.com/juju/errors"
    14  )
    15  
    16  // This file contains helper functions for generic operations commonly needed
    17  // when implementing a command.
    18  
    19  const yesNoMsg = "\nContinue [y/N]? "
    20  
    21  var nameVerificationMsg = "\nTo continue, enter the name of the %s to be destroyed: "
    22  
    23  type userAbortedError string
    24  
    25  func (e userAbortedError) Error() string {
    26  	return string(e)
    27  }
    28  
    29  // IsUserAbortedError returns true if err is of type userAbortedError.
    30  func IsUserAbortedError(err error) bool {
    31  	_, ok := errors.Cause(err).(userAbortedError)
    32  	return ok
    33  }
    34  
    35  // UserConfirmYes returns an error if we do not read a "y" or "yes" from user
    36  // input.
    37  func UserConfirmYes(ctx *cmd.Context) error {
    38  	fmt.Fprint(ctx.Stderr, yesNoMsg)
    39  	scanner := bufio.NewScanner(ctx.Stdin)
    40  	scanner.Scan()
    41  	err := scanner.Err()
    42  	if err != nil && err != io.EOF {
    43  		return errors.Trace(err)
    44  	}
    45  	answer := strings.ToLower(scanner.Text())
    46  	if answer != "y" && answer != "yes" {
    47  		return errors.Trace(userAbortedError("aborted"))
    48  	}
    49  	return nil
    50  }
    51  
    52  // UserConfirmName returns an error if we do not read a "name" of the model/controller/etc from user
    53  // input.
    54  func UserConfirmName(verificationName string, objectType string, ctx *cmd.Context) error {
    55  	fmt.Fprintf(ctx.Stderr, nameVerificationMsg, objectType)
    56  	scanner := bufio.NewScanner(ctx.Stdin)
    57  	scanner.Scan()
    58  	err := scanner.Err()
    59  	if err != nil && err != io.EOF {
    60  		return errors.Trace(err)
    61  	}
    62  	answer := strings.ToLower(scanner.Text())
    63  	if answer != verificationName {
    64  		return errors.Trace(userAbortedError("aborted"))
    65  	}
    66  	return nil
    67  }