github.com/taubyte/tau-cli@v0.1.13-0.20240326000942-487f0d57edfc/prompts/application/select.go (about)

     1  package applicationPrompts
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	structureSpec "github.com/taubyte/go-specs/structure"
     9  	"github.com/taubyte/tau-cli/env"
    10  	"github.com/taubyte/tau-cli/flags"
    11  	applicationI18n "github.com/taubyte/tau-cli/i18n/application"
    12  	applicationLib "github.com/taubyte/tau-cli/lib/application"
    13  	"github.com/taubyte/tau-cli/prompts"
    14  
    15  	"github.com/urfave/cli/v2"
    16  )
    17  
    18  /*
    19  GetOrSelect will try to get the application from a name flag
    20  if it is not set in the flag it will offer a selection menu
    21  */
    22  func GetOrSelect(ctx *cli.Context, checkEnv bool) (*structureSpec.App, error) {
    23  	name := ctx.String(flags.Name.Name)
    24  
    25  	// Try to get selected application
    26  	if len(name) == 0 && checkEnv {
    27  		name, _ = env.GetSelectedApplication()
    28  	}
    29  
    30  	resources, err := applicationLib.ListResources()
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  
    35  	// Try to select a application
    36  	if len(name) == 0 && len(resources) > 0 {
    37  		// TODO currentlySelected should be an option surrounded by ()
    38  		// acting as a deselect
    39  
    40  		options := make([]string, len(resources))
    41  		for idx, p := range resources {
    42  			options[idx] = p.Name
    43  		}
    44  
    45  		name, err = prompts.SelectInterface(options, SelectPrompt, options[0])
    46  		if err != nil {
    47  			return nil, applicationI18n.SelectPromptFailed(err)
    48  		}
    49  	}
    50  
    51  	if len(name) != 0 {
    52  		app, err := matchLowercase(name, resources)
    53  		if err != nil {
    54  			return nil, err
    55  		}
    56  
    57  		return app, nil
    58  	}
    59  
    60  	return nil, errors.New(NoneFound)
    61  }
    62  
    63  func GetSelectOrDeselect(ctx *cli.Context) (app *structureSpec.App, deselect bool, err error) {
    64  	currentlySelected, _ := env.GetSelectedApplication()
    65  	if len(currentlySelected) == 0 {
    66  		app, err = GetOrSelect(ctx, false)
    67  		if err != nil {
    68  			return
    69  		}
    70  
    71  		return app, false, nil
    72  	}
    73  
    74  	name := ctx.String(flags.Name.Name)
    75  	resources, err := applicationLib.ListResources()
    76  	if err != nil {
    77  		return nil, false, err
    78  	}
    79  
    80  	options := make([]string, len(resources)+1 /*accounting for (none)*/)
    81  	for idx, _app := range resources {
    82  		options[idx] = _app.Name
    83  	}
    84  
    85  	options[len(options)-1] = prompts.SelectionNone
    86  
    87  	// Try to select a application
    88  	if len(name) == 0 && len(options) > 0 {
    89  		name, err = prompts.SelectInterface(options, SelectPrompt, currentlySelected)
    90  		if err != nil {
    91  			return nil, false, applicationI18n.SelectPromptFailed(err)
    92  		}
    93  	}
    94  
    95  	if len(name) > 0 {
    96  		var deselect bool
    97  		if name == prompts.SelectionNone {
    98  			deselect = true
    99  			name = currentlySelected
   100  		}
   101  
   102  		app, err := matchLowercase(name, resources)
   103  		if err != nil {
   104  			return nil, false, err
   105  		}
   106  
   107  		return app, deselect, nil
   108  	}
   109  
   110  	return nil, false, errors.New(NoneFound)
   111  }
   112  
   113  func matchLowercase(name string, apps []*structureSpec.App) (*structureSpec.App, error) {
   114  	nameLC := strings.ToLower(name)
   115  
   116  	for _, app := range apps {
   117  		if nameLC == strings.ToLower(app.Name) {
   118  			return app, nil
   119  		}
   120  	}
   121  
   122  	return nil, fmt.Errorf(NotFound, name)
   123  }