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