github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/client/prompter.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package client
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/keybase/client/go/libkb"
    10  )
    11  
    12  type Field struct {
    13  	Name             string
    14  	Prompt           string
    15  	FirstPrompt      string
    16  	Defval           string
    17  	Hint             string
    18  	Checker          *libkb.Checker
    19  	Thrower          func(key, value string) error
    20  	Disabled         bool
    21  	Value            *string
    22  	PromptDescriptor libkb.PromptDescriptor
    23  }
    24  
    25  func (f Field) GetValue() string {
    26  	if f.Value == nil {
    27  		return ""
    28  	}
    29  	return *f.Value
    30  }
    31  
    32  type Prompter struct {
    33  	Fields []*Field
    34  	tui    libkb.TerminalUI
    35  }
    36  
    37  func NewPrompter(f []*Field, tui libkb.TerminalUI) *Prompter {
    38  	return &Prompter{Fields: f, tui: tui}
    39  }
    40  
    41  func (p *Prompter) Run() error {
    42  	for _, f := range p.Fields {
    43  		if f.Disabled {
    44  			continue
    45  		}
    46  		if err := p.ReadField(f); err != nil {
    47  			return err
    48  		}
    49  	}
    50  	return nil
    51  }
    52  
    53  func (f *Field) Clear() string {
    54  	old := f.GetValue()
    55  	f.Value = nil
    56  	return old
    57  }
    58  
    59  func (p *Prompter) ReadField(f *Field) (err error) {
    60  
    61  	done := false
    62  	first := true
    63  
    64  	var val string
    65  
    66  	if p.tui == nil {
    67  		return NoTerminalError{}
    68  	}
    69  
    70  	for !done && err == nil {
    71  
    72  		prompt := f.Prompt
    73  		if first {
    74  			if len(f.FirstPrompt) > 0 {
    75  				prompt += f.FirstPrompt
    76  			}
    77  			first = false
    78  		} else {
    79  			hint := f.Hint
    80  			if len(hint) == 0 {
    81  				hint = f.Checker.Hint
    82  			}
    83  			prompt += " (" + hint + ")"
    84  		}
    85  
    86  		var def string
    87  		if len(f.Defval) > 0 {
    88  			def = f.Defval
    89  		} else if f.Value != nil {
    90  			def = *f.Value
    91  		}
    92  
    93  		if len(def) > 0 {
    94  			prompt += " [" + def + "]"
    95  		}
    96  		prompt += ": "
    97  
    98  		if val, err = p.tui.Prompt(f.PromptDescriptor, prompt); err != nil {
    99  			break
   100  		}
   101  
   102  		if len(val) == 0 && len(def) > 0 {
   103  			val = def
   104  		}
   105  
   106  		if f.Checker == nil || !f.Checker.PreserveSpace {
   107  			val = strings.TrimSpace(val)
   108  		}
   109  
   110  		if f.Thrower != nil {
   111  			if err = f.Thrower(f.Name, val); err != nil {
   112  				break
   113  			}
   114  		}
   115  		if f.Checker != nil {
   116  			if f.Checker.Transform != nil {
   117  				val = f.Checker.Transform(val)
   118  			}
   119  
   120  			done = f.Checker.F(val)
   121  		} else {
   122  			done = true
   123  		}
   124  		if done {
   125  			f.Value = &val
   126  		}
   127  	}
   128  
   129  	if err == nil {
   130  		f.Value = &val
   131  	}
   132  
   133  	return
   134  }