github.com/kbehouse/nsc@v0.0.6/cmd/action.go (about) 1 /* 2 * Copyright 2018 The NATS Authors 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package cmd 17 18 import ( 19 "fmt" 20 "strings" 21 22 "github.com/kbehouse/nsc/cmd/store" 23 "github.com/spf13/cobra" 24 ) 25 26 type ActionCtx interface { 27 StoreCtx() *store.Context 28 CurrentCmd() *cobra.Command 29 Args() []string 30 NothingToDo(flagNames ...string) bool 31 AllSet(flagNames ...string) bool 32 AnySet(flagNames ...string) bool 33 CountSet(flagNames ...string) int 34 } 35 36 type ActionFn func(ctx ActionCtx) error 37 type ActionRunFn func(ctx ActionCtx) (store.Status, error) 38 39 type Action interface { 40 // SetDefaults that can be derived from cmd flags 41 SetDefaults(ctx ActionCtx) error 42 // PreInteractive ask user for values 43 PreInteractive(ctx ActionCtx) error 44 // Load any data needed for the Run 45 Load(ctx ActionCtx) error 46 // PostInteractive ask user for values related to the action 47 PostInteractive(ctx ActionCtx) error 48 // Validate the action 49 Validate(ctx ActionCtx) error 50 // Run the action 51 Run(ctx ActionCtx) (store.Status, error) 52 } 53 54 type Actx struct { 55 ctx *store.Context 56 cmd *cobra.Command 57 args []string 58 } 59 60 func NewActx(cmd *cobra.Command, args []string) (ActionCtx, error) { 61 s, err := GetStore() 62 // in the case of add operator, there might not be a store 63 if err == ErrNoOperator { 64 if cmd.Name() == "operator" && cmd.Parent().Name() == "add" { 65 return nil, nil 66 } 67 } 68 if err != nil { 69 return nil, err 70 } 71 ctx, err := s.GetContext() 72 if err != nil { 73 return nil, err 74 } 75 76 return &Actx{cmd: cmd, ctx: ctx, args: args}, nil 77 } 78 79 func NewStoreLessActx(cmd *cobra.Command, args []string) (ActionCtx, error) { 80 var ctx Actx 81 ctx.cmd = cmd 82 ctx.args = args 83 ctx.ctx = &store.Context{} 84 return &ctx, nil 85 } 86 87 func RunMaybeStorelessAction(cmd *cobra.Command, args []string, action interface{}) error { 88 ctx, err := NewActx(cmd, args) 89 if err != nil { 90 ctx, err = NewStoreLessActx(cmd, args) 91 if err != nil { 92 return err 93 } 94 } 95 return run(ctx, action) 96 97 } 98 99 func RunStoreLessAction(cmd *cobra.Command, args []string, action interface{}) error { 100 ctx, err := NewStoreLessActx(cmd, args) 101 if err != nil { 102 return err 103 } 104 return run(ctx, action) 105 } 106 107 func RunAction(cmd *cobra.Command, args []string, action interface{}) error { 108 ctx, err := NewActx(cmd, args) 109 if err != nil { 110 return err 111 } 112 return run(ctx, action) 113 } 114 115 func run(ctx ActionCtx, action interface{}) error { 116 e, ok := action.(Action) 117 if !ok { 118 return fmt.Errorf("action provided is not an Action") 119 } 120 if err := e.SetDefaults(ctx); err != nil { 121 return err 122 } 123 124 if InteractiveFlag { 125 if err := e.PreInteractive(ctx); err != nil { 126 return err 127 } 128 } 129 130 if err := e.Load(ctx); err != nil { 131 return err 132 } 133 134 if InteractiveFlag { 135 if err := e.PostInteractive(ctx); err != nil { 136 return err 137 } 138 } 139 140 if err := e.Validate(ctx); err != nil { 141 return err 142 } 143 144 rs, err := e.Run(ctx) 145 if rs != nil { 146 ctx.CurrentCmd().Println(rs.Message()) 147 sum, ok := rs.(store.Summarizer) 148 if ok { 149 m, err := sum.Summary() 150 if err != nil { 151 return err 152 } 153 if m != "" { 154 ctx.CurrentCmd().Println(strings.TrimSuffix(m, "\n")) 155 } 156 } 157 } 158 return err 159 } 160 161 func (c *Actx) StoreCtx() *store.Context { 162 return c.ctx 163 } 164 165 func (c *Actx) CurrentCmd() *cobra.Command { 166 return c.cmd 167 } 168 169 func (c *Actx) Args() []string { 170 return c.args 171 } 172 173 func (c *Actx) NothingToDo(flagNames ...string) bool { 174 for _, n := range flagNames { 175 if c.cmd.Flag(n).Changed { 176 return false 177 } 178 } 179 return true 180 } 181 182 // AnySet returns true if any of the flags are set 183 func (c *Actx) AnySet(flagNames ...string) bool { 184 for _, n := range flagNames { 185 if c.cmd.Flag(n).Changed { 186 return true 187 } 188 } 189 return false 190 } 191 192 // AllSet returns true if all flags are set 193 func (c *Actx) AllSet(flagNames ...string) bool { 194 count := 0 195 for _, n := range flagNames { 196 if c.cmd.Flag(n).Changed { 197 count++ 198 } 199 } 200 return len(flagNames) == count 201 } 202 203 func (c *Actx) CountSet(flagNames ...string) int { 204 count := 0 205 for _, n := range flagNames { 206 if c.cmd.Flag(n).Changed { 207 count++ 208 } 209 } 210 return count 211 }