github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/cmd/juju/switch.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/errors"
    12  	"github.com/juju/utils/set"
    13  	"launchpad.net/gnuflag"
    14  
    15  	"github.com/juju/juju/cmd/envcmd"
    16  	"github.com/juju/juju/environs"
    17  	"github.com/juju/juju/environs/configstore"
    18  )
    19  
    20  type SwitchCommand struct {
    21  	cmd.CommandBase
    22  	EnvName string
    23  	List    bool
    24  }
    25  
    26  var switchDoc = `
    27  Show or change the default juju environment name.
    28  
    29  If no command line parameters are passed, switch will output the current
    30  environment as defined by the file $JUJU_HOME/current-environment.
    31  
    32  If a command line parameter is passed in, that value will is stored in the
    33  current environment file if it represents a valid environment name as
    34  specified in the environments.yaml file.
    35  `
    36  
    37  func (c *SwitchCommand) Info() *cmd.Info {
    38  	return &cmd.Info{
    39  		Name:    "switch",
    40  		Args:    "[environment name]",
    41  		Purpose: "show or change the default juju environment name",
    42  		Doc:     switchDoc,
    43  		Aliases: []string{"env"},
    44  	}
    45  }
    46  
    47  func (c *SwitchCommand) SetFlags(f *gnuflag.FlagSet) {
    48  	f.BoolVar(&c.List, "l", false, "list the environment names")
    49  	f.BoolVar(&c.List, "list", false, "")
    50  }
    51  
    52  func (c *SwitchCommand) Init(args []string) (err error) {
    53  	c.EnvName, err = cmd.ZeroOrOneArgs(args)
    54  	return
    55  }
    56  
    57  func getConfigstoreEnvironments() (set.Strings, error) {
    58  	store, err := configstore.Default()
    59  	if err != nil {
    60  		return nil, errors.Annotate(err, "failed to get config store")
    61  	}
    62  	other, err := store.List()
    63  	if err != nil {
    64  		return nil, errors.Annotate(err, "failed to list environments in config store")
    65  	}
    66  	return set.NewStrings(other...), nil
    67  }
    68  
    69  func (c *SwitchCommand) Run(ctx *cmd.Context) error {
    70  	// Switch is an alternative way of dealing with environments than using
    71  	// the JUJU_ENV environment setting, and as such, doesn't play too well.
    72  	// If JUJU_ENV is set we should report that as the current environment,
    73  	// and not allow switching when it is set.
    74  
    75  	// Passing through the empty string reads the default environments.yaml file.
    76  	environments, err := environs.ReadEnvirons("")
    77  	if err != nil {
    78  		return errors.Errorf("couldn't read the environment")
    79  	}
    80  
    81  	names := set.NewStrings(environments.Names()...)
    82  	configEnvirons, err := getConfigstoreEnvironments()
    83  	if err != nil {
    84  		return err
    85  	}
    86  	names = names.Union(configEnvirons)
    87  
    88  	if c.List {
    89  		// List all environments.
    90  		if c.EnvName != "" {
    91  			return errors.New("cannot switch and list at the same time")
    92  		}
    93  		for _, name := range names.SortedValues() {
    94  			fmt.Fprintf(ctx.Stdout, "%s\n", name)
    95  		}
    96  		return nil
    97  	}
    98  
    99  	jujuEnv := os.Getenv("JUJU_ENV")
   100  	if jujuEnv != "" {
   101  		if c.EnvName == "" {
   102  			fmt.Fprintf(ctx.Stdout, "%s\n", jujuEnv)
   103  			return nil
   104  		} else {
   105  			return errors.Errorf("cannot switch when JUJU_ENV is overriding the environment (set to %q)", jujuEnv)
   106  		}
   107  	}
   108  
   109  	currentEnv := envcmd.ReadCurrentEnvironment()
   110  	if currentEnv == "" {
   111  		currentEnv = environments.Default
   112  	}
   113  
   114  	// Handle the different operation modes.
   115  	switch {
   116  	case c.EnvName == "" && currentEnv == "":
   117  		// Nothing specified and nothing to switch to.
   118  		return errors.New("no currently specified environment")
   119  	case c.EnvName == "":
   120  		// Simply print the current environment.
   121  		fmt.Fprintf(ctx.Stdout, "%s\n", currentEnv)
   122  	default:
   123  		// Switch the environment.
   124  		if !names.Contains(c.EnvName) {
   125  			return errors.Errorf("%q is not a name of an existing defined environment", c.EnvName)
   126  		}
   127  		if err := envcmd.WriteCurrentEnvironment(c.EnvName); err != nil {
   128  			return err
   129  		}
   130  		if currentEnv == "" {
   131  			fmt.Fprintf(ctx.Stdout, "-> %s\n", c.EnvName)
   132  		} else {
   133  			fmt.Fprintf(ctx.Stdout, "%s -> %s\n", currentEnv, c.EnvName)
   134  		}
   135  	}
   136  	return nil
   137  }