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  }