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