github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/runbits/promptable/promptable.go (about) 1 package promptable 2 3 import ( 4 "github.com/ActiveState/cli/internal/logging" 5 "github.com/ActiveState/cli/internal/multilog" 6 "github.com/ActiveState/cli/internal/rollbar" 7 ) 8 9 // Contextualizer describes any type which can provide needed contextual info. 10 type Contextualizer interface { 11 IsInteractive() bool 12 } 13 14 // IsPromptable reports whether the output type permits prompts to be shown. 15 func IsPromptable(c Contextualizer) bool { 16 return c.IsInteractive() 17 } 18 19 // IsPromptableOnce reports whether the given context permits prompts to be 20 // shown and also whether a prompt has not been shown before. 21 func IsPromptableOnce(c Contextualizer, cfg Configurer, key OnceKey) bool { 22 return IsPromptable(c) && SetPrompted(cfg, key) 23 } 24 25 // OnceKey represents config keys as tokens. 26 type OnceKey string 27 28 // OnceKey contants enumerate relevant config keys. 29 const ( 30 DefaultProject OnceKey = "default_project_prompt" 31 ) 32 33 // Configurer describes the behavior required to track info via config. 34 type Configurer interface { 35 GetBool(key string) (value bool) 36 Set(key string, value interface{}) error 37 } 38 39 // SetPrompted tracks whether a prompt has been called before using the config 40 // type and key. A response of true indicates that the config has been updated. 41 // A response of false indicates that the config has not been updated. If the 42 // configuration "set" call fails, this functions always returns true. 43 func SetPrompted(cfg Configurer, key OnceKey) bool { 44 asked := cfg.GetBool(string(key)) 45 if asked { 46 logging.Debug("%s: already asked", key) 47 return false 48 } 49 50 logging.Debug("%s: setting asked", key) 51 if err := cfg.Set(string(key), true); err != nil { 52 multilog.Log(logging.ErrorNoStacktrace, rollbar.Error)("Failed to set %q: %v", key, err) 53 } 54 return true 55 }