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 }