github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/worker/uniter/runner/jujuc/action-set.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc 5 6 import ( 7 "fmt" 8 "regexp" 9 "strings" 10 11 "github.com/juju/cmd" 12 "launchpad.net/gnuflag" 13 ) 14 15 var keyRule = regexp.MustCompile("^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$") 16 17 // ActionSetCommand implements the action-set command. 18 type ActionSetCommand struct { 19 cmd.CommandBase 20 ctx Context 21 args [][]string 22 } 23 24 // NewActionSetCommand returns a new ActionSetCommand with the given context. 25 func NewActionSetCommand(ctx Context) cmd.Command { 26 return &ActionSetCommand{ctx: ctx} 27 } 28 29 // Info returns the content for --help. 30 func (c *ActionSetCommand) Info() *cmd.Info { 31 doc := ` 32 action-set adds the given values to the results map of the Action. This map 33 is returned to the user after the completion of the Action. 34 35 Example usage: 36 action-set outfile.size=10G 37 action-set foo.bar=2 38 action-set foo.baz.val=3 39 action-set foo.bar.zab=4 40 action-set foo.baz=1 41 42 will yield: 43 44 outfile: 45 size: "10G" 46 foo: 47 bar: 48 zab: "4" 49 baz: "1" 50 ` 51 return &cmd.Info{ 52 Name: "action-set", 53 Args: "<key>=<value> [<key>=<value> ...]", 54 Purpose: "set action results", 55 Doc: doc, 56 } 57 } 58 59 // SetFlags handles known option flags. 60 func (c *ActionSetCommand) SetFlags(f *gnuflag.FlagSet) { 61 // TODO(binary132): add cmd.Input type as in cmd.Output for YAML piping. 62 } 63 64 // Init accepts maps in the form of key=value, key.key2.keyN....=value 65 func (c *ActionSetCommand) Init(args []string) error { 66 c.args = make([][]string, 0) 67 for _, arg := range args { 68 thisArg := strings.SplitN(arg, "=", 2) 69 if len(thisArg) != 2 { 70 return fmt.Errorf("argument %q must be of the form key...=value", arg) 71 } 72 keySlice := strings.Split(thisArg[0], ".") 73 // check each key for validity 74 for _, key := range keySlice { 75 if valid := keyRule.MatchString(key); !valid { 76 return fmt.Errorf("key %q must start and end with lowercase alphanumeric, and contain only lowercase alphanumeric and hyphens", key) 77 } 78 } 79 // [key, key, key, key, value] 80 c.args = append(c.args, append(keySlice, thisArg[1])) 81 } 82 83 return nil 84 } 85 86 // Run adds the given <key list>/<value> pairs, such as foo.bar=baz to the 87 // existing map of results for the Action. 88 func (c *ActionSetCommand) Run(ctx *cmd.Context) error { 89 for _, argSlice := range c.args { 90 valueIndex := len(argSlice) - 1 91 keys := argSlice[:valueIndex] 92 value := argSlice[valueIndex] 93 err := c.ctx.UpdateActionResults(keys, value) 94 if err != nil { 95 return err 96 } 97 } 98 99 return nil 100 }