Merge lp:~themue/juju-core/054-env-more-script-friendly into lp:~go-bot/juju-core/trunk
- 054-env-more-script-friendly
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Frank Mueller | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 2071 | ||||
Proposed branch: | lp:~themue/juju-core/054-env-more-script-friendly | ||||
Merge into: | lp:~go-bot/juju-core/trunk | ||||
Diff against target: |
180 lines (+39/-42) 2 files modified
cmd/juju/switch.go (+25/-22) cmd/juju/switch_test.go (+14/-20) |
||||
To merge this branch: | bzr merge lp:~themue/juju-core/054-env-more-script-friendly | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Engineering | Pending | ||
Review via email: mp+191838@code.launchpad.net |
Commit message
switch: more script friendly output
Changed switch command to more script friendly
output. Branch has been newly created after an
error when reverting.
Description of the change
switch: more script friendly output
Changed switch command to more script friendly
output. Branch has been newly created after an
error when reverting.
Frank Mueller (themue) wrote : | # |
Martin Packman (gz) wrote : | # |
Code looks fine apart from one possibly spurious struct member addition.
I have mixed feelings about making switch less user friendly and more
script friendly. It feels mostly like a user-only command to me, unlike
status say. In bzr it's similar, status gives output that's quite
machine parsable, but switch is an interactive command. In the bug, stub
doesn't really go into *why* he wants to script this, my instinct would
be to say using seperate juju homes would be more suitable than having
one and switching.
https:/
File cmd/juju/switch.go (right):
https:/
cmd/juju/
What's this used for?
Frank Mueller (themue) wrote : | # |
On 2013/10/18 17:41:49, gz wrote:
> Code looks fine apart from one possibly spurious struct member
addition.
> I have mixed feelings about making switch less user friendly and more
script
> friendly. It feels mostly like a user-only command to me, unlike
status say. In
> bzr it's similar, status gives output that's quite machine parsable,
but switch
> is an interactive command. In the bug, stub doesn't really go into
*why* he
> wants to script this, my instinct would be to say using seperate juju
homes
> would be more suitable than having one and switching.
> https:/
> File cmd/juju/switch.go (right):
https:/
> cmd/juju/
> What's this used for?
Ooops, the raw has indeed to be removed, it's a leftover of a former
try.
The discussion about the output has gone through several circles, with
--raw and raw as default. This is the agreement after the discussion.
The problem is that this command is overloaded. It gets, sets and lists
for the user and for scripts.
Roger Peppe (rogpeppe) wrote : | # |
LGTM with one thought below.
Personally I think that the script friendly output is also user friendly
- verbosity does not necessarily imply friendliness.
Also many people write ad-hoc scripts on the command line - it's good to
be an upstanding command line citizen and play nicely with the shell
IMHO.
https:/
File cmd/juju/switch.go (right):
https:/
cmd/juju/
I'm not sure it's worth showing this.
It means that this won't work, for example:
for i in `juju switch -l`; do
juju status -e $i
done
I'm not sure we need to combine the two
functionalities (list environments and print
current environment name). Let's keep it as
simple as possible.
YMMV though.
William Reade (fwereade) wrote : | # |
This looks like a perfect situation for a --format param and some
structs, and leaving the existing output unchanged as the "smart" (haha)
option. What led us do do it otherwise?
Frank Mueller (themue) wrote : | # |
On 2013/11/18 10:46:13, william.reade wrote:
> This looks like a perfect situation for a --format param and some
structs, and
> leaving the existing output unchanged as the "smart" (haha) option.
What led us
> do do it otherwise?
There has been a first approach:
https:/
The reviews and the discussion for it led to a second approach.
Different people have different preferences. I'll talk to Stuart about
his preferences, he "owns" the issue.
Roger Peppe (rogpeppe) wrote : | # |
On 18 November 2013 10:46, <email address hidden> wrote:
> This looks like a perfect situation for a --format param and some
> structs, and leaving the existing output unchanged as the "smart" (haha)
> option. What led us do do it otherwise?
This was a very new command.
I thought that changing it now would result in cleaner
code and a somewhat slicker interface with minimal
compatibility issues. I don't think the verbose
output adds any particular value.
This was all discussed quite a while ago.
William Reade (fwereade) wrote : | # |
On 2013/11/18 14:05:05, rog wrote:
> On 18 November 2013 10:46, <mailto:<email address hidden>>
wrote:
> > This looks like a perfect situation for a --format param and some
> > structs, and leaving the existing output unchanged as the "smart"
(haha)
> > option. What led us do do it otherwise?
> This was a very new command.
> I thought that changing it now would result in cleaner
> code and a somewhat slicker interface with minimal
> compatibility issues. I don't think the verbose
> output adds any particular value.
> This was all discussed quite a while ago.
Fair enough, I guess I just missed that one. Thanks for the history. I'm
+1 on your drop-the-(*) suggestion FWIW.
Frank Mueller (themue) wrote : | # |
On 2013/11/18 14:16:40, william.reade wrote:
> On 2013/11/18 14:05:05, rog wrote:
> > On 18 November 2013 10:46, <mailto:<email address hidden>>
wrote:
> > > This looks like a perfect situation for a --format param and some
> > > structs, and leaving the existing output unchanged as the "smart"
(haha)
> > > option. What led us do do it otherwise?
> >
> > This was a very new command.
> >
> > I thought that changing it now would result in cleaner
> > code and a somewhat slicker interface with minimal
> > compatibility issues. I don't think the verbose
> > output adds any particular value.
> >
> > This was all discussed quite a while ago.
> Fair enough, I guess I just missed that one. Thanks for the history.
I'm +1 on
> your drop-the-(*) suggestion FWIW.
Fine, then I'll do it that way.
Frank Mueller (themue) wrote : | # |
https:/
File cmd/juju/switch.go (right):
https:/
cmd/juju/
On 2013/10/18 17:41:49, gz wrote:
> What's this used for?
Ouch, old approach, missed to remove it. Thx.
https:/
cmd/juju/
On 2013/11/12 16:11:27, rog wrote:
> I'm not sure it's worth showing this.
> It means that this won't work, for example:
> for i in `juju switch -l`; do
> juju status -e $i
> done
> I'm not sure we need to combine the two
> functionalities (list environments and print
> current environment name). Let's keep it as
> simple as possible.
> YMMV though.
Done.
Frank Mueller (themue) wrote : | # |
Please take a look.
Go Bot (go-bot) wrote : | # |
The attempt to merge lp:~themue/juju-core/054-env-more-script-friendly into lp:juju-core failed. Below is the output from the failed tests.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
-------
FAIL: apiconn_test.go:0: DeployLocalSuit
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for s...
Go Bot (go-bot) wrote : | # |
The attempt to merge lp:~themue/juju-core/054-env-more-script-friendly into lp:juju-core failed. Below is the output from the failed tests.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
-------
FAIL: apiconn_test.go:0: DeployLocalSuit
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for sockets to die: 0 in use, 1 alive
Waiting for ...
Preview Diff
1 | === modified file 'cmd/juju/switch.go' |
2 | --- cmd/juju/switch.go 2013-10-08 14:53:20 +0000 |
3 | +++ cmd/juju/switch.go 2013-11-18 16:47:14 +0000 |
4 | @@ -69,17 +69,17 @@ |
5 | jujuEnv := os.Getenv("JUJU_ENV") |
6 | if jujuEnv != "" { |
7 | if c.EnvName == "" { |
8 | - fmt.Fprintf(ctx.Stdout, "Current environment: %q (from JUJU_ENV)\n", jujuEnv) |
9 | + fmt.Fprintf(ctx.Stdout, "%s\n", jujuEnv) |
10 | return nil |
11 | } else { |
12 | - return fmt.Errorf("Cannot switch when JUJU_ENV is overriding the environment (set to %q)", jujuEnv) |
13 | + return fmt.Errorf("cannot switch when JUJU_ENV is overriding the environment (set to %q)", jujuEnv) |
14 | } |
15 | } |
16 | |
17 | // Passing through the empty string reads the default environments.yaml file. |
18 | environments, err := environs.ReadEnvirons("") |
19 | if err != nil { |
20 | - return errors.New("couldn't read the environment.") |
21 | + return errors.New("couldn't read the environment") |
22 | } |
23 | names := environments.Names() |
24 | sort.Strings(names) |
25 | @@ -89,32 +89,35 @@ |
26 | currentEnv = environments.Default |
27 | } |
28 | |
29 | - // In order to have only a set environment name quoted, make a small function |
30 | - env := func() string { |
31 | - if currentEnv == "" { |
32 | - return "<not specified>" |
33 | - } |
34 | - return fmt.Sprintf("%q", currentEnv) |
35 | - } |
36 | - |
37 | - if c.EnvName == "" || c.EnvName == currentEnv { |
38 | - fmt.Fprintf(ctx.Stdout, "Current environment: %s\n", env()) |
39 | - } else { |
40 | - // Check to make sure that the specified environment |
41 | + // Handle the different operation modes. |
42 | + switch { |
43 | + case c.List: |
44 | + // List all environments. |
45 | + if c.EnvName != "" { |
46 | + return errors.New("cannot switch and list at the same time") |
47 | + } |
48 | + for _, name := range names { |
49 | + fmt.Fprintf(ctx.Stdout, "%s\n", name) |
50 | + } |
51 | + case c.EnvName == "" && currentEnv == "": |
52 | + // Nothing specified and nothing to switch to. |
53 | + return errors.New("no currently specified environment") |
54 | + case c.EnvName == "": |
55 | + // Simply print the current environment. |
56 | + fmt.Fprintf(ctx.Stdout, "%s\n", currentEnv) |
57 | + default: |
58 | + // Switch the environment. |
59 | if !validEnvironmentName(c.EnvName, names) { |
60 | return fmt.Errorf("%q is not a name of an existing defined environment", c.EnvName) |
61 | } |
62 | if err := cmd.WriteCurrentEnvironment(c.EnvName); err != nil { |
63 | return err |
64 | } |
65 | - fmt.Fprintf(ctx.Stdout, "Changed default environment from %s to %q\n", env(), c.EnvName) |
66 | - } |
67 | - if c.List { |
68 | - fmt.Fprintf(ctx.Stdout, "\nEnvironments:\n") |
69 | - for _, name := range names { |
70 | - fmt.Fprintf(ctx.Stdout, "\t%s\n", name) |
71 | + if currentEnv == "" { |
72 | + fmt.Fprintf(ctx.Stdout, "-> %s\n", c.EnvName) |
73 | + } else { |
74 | + fmt.Fprintf(ctx.Stdout, "%s -> %s\n", currentEnv, c.EnvName) |
75 | } |
76 | } |
77 | - |
78 | return nil |
79 | } |
80 | |
81 | === modified file 'cmd/juju/switch_test.go' |
82 | --- cmd/juju/switch_test.go 2013-09-13 14:48:13 +0000 |
83 | +++ cmd/juju/switch_test.go 2013-11-18 16:47:14 +0000 |
84 | @@ -21,21 +21,20 @@ |
85 | func (*SwitchSimpleSuite) TestNoEnvironment(c *gc.C) { |
86 | defer testing.MakeEmptyFakeHome(c).Restore() |
87 | _, err := testing.RunCommand(c, &SwitchCommand{}, nil) |
88 | - c.Assert(err, gc.ErrorMatches, "couldn't read the environment.") |
89 | + c.Assert(err, gc.ErrorMatches, "couldn't read the environment") |
90 | } |
91 | |
92 | func (*SwitchSimpleSuite) TestNoDefault(c *gc.C) { |
93 | defer testing.MakeFakeHome(c, testing.MultipleEnvConfigNoDefault).Restore() |
94 | - context, err := testing.RunCommand(c, &SwitchCommand{}, nil) |
95 | - c.Assert(err, gc.IsNil) |
96 | - c.Assert(testing.Stdout(context), gc.Equals, "Current environment: <not specified>\n") |
97 | + _, err := testing.RunCommand(c, &SwitchCommand{}, nil) |
98 | + c.Assert(err, gc.ErrorMatches, "no currently specified environment") |
99 | } |
100 | |
101 | func (*SwitchSimpleSuite) TestShowsDefault(c *gc.C) { |
102 | defer testing.MakeFakeHome(c, testing.MultipleEnvConfig).Restore() |
103 | context, err := testing.RunCommand(c, &SwitchCommand{}, nil) |
104 | c.Assert(err, gc.IsNil) |
105 | - c.Assert(testing.Stdout(context), gc.Equals, "Current environment: \"erewhemos\"\n") |
106 | + c.Assert(testing.Stdout(context), gc.Equals, "erewhemos\n") |
107 | } |
108 | |
109 | func (*SwitchSimpleSuite) TestCurrentEnvironmentHasPrecidence(c *gc.C) { |
110 | @@ -44,7 +43,7 @@ |
111 | home.AddFiles(c, []testing.TestFile{{".juju/current-environment", "fubar"}}) |
112 | context, err := testing.RunCommand(c, &SwitchCommand{}, nil) |
113 | c.Assert(err, gc.IsNil) |
114 | - c.Assert(testing.Stdout(context), gc.Equals, "Current environment: \"fubar\"\n") |
115 | + c.Assert(testing.Stdout(context), gc.Equals, "fubar\n") |
116 | } |
117 | |
118 | func (*SwitchSimpleSuite) TestShowsJujuEnv(c *gc.C) { |
119 | @@ -52,7 +51,7 @@ |
120 | os.Setenv("JUJU_ENV", "using-env") |
121 | context, err := testing.RunCommand(c, &SwitchCommand{}, nil) |
122 | c.Assert(err, gc.IsNil) |
123 | - c.Assert(testing.Stdout(context), gc.Equals, "Current environment: \"using-env\" (from JUJU_ENV)\n") |
124 | + c.Assert(testing.Stdout(context), gc.Equals, "using-env\n") |
125 | } |
126 | |
127 | func (*SwitchSimpleSuite) TestJujuEnvOverCurrentEnvironment(c *gc.C) { |
128 | @@ -62,14 +61,14 @@ |
129 | os.Setenv("JUJU_ENV", "using-env") |
130 | context, err := testing.RunCommand(c, &SwitchCommand{}, nil) |
131 | c.Assert(err, gc.IsNil) |
132 | - c.Assert(testing.Stdout(context), gc.Equals, "Current environment: \"using-env\" (from JUJU_ENV)\n") |
133 | + c.Assert(testing.Stdout(context), gc.Equals, "using-env\n") |
134 | } |
135 | |
136 | func (*SwitchSimpleSuite) TestSettingWritesFile(c *gc.C) { |
137 | defer testing.MakeFakeHome(c, testing.MultipleEnvConfig).Restore() |
138 | context, err := testing.RunCommand(c, &SwitchCommand{}, []string{"erewhemos-2"}) |
139 | c.Assert(err, gc.IsNil) |
140 | - c.Assert(testing.Stdout(context), gc.Equals, "Changed default environment from \"erewhemos\" to \"erewhemos-2\"\n") |
141 | + c.Assert(testing.Stdout(context), gc.Equals, "erewhemos -> erewhemos-2\n") |
142 | c.Assert(cmd.ReadCurrentEnvironment(), gc.Equals, "erewhemos-2") |
143 | } |
144 | |
145 | @@ -83,29 +82,24 @@ |
146 | defer testing.MakeFakeHome(c, testing.MultipleEnvConfig).Restore() |
147 | os.Setenv("JUJU_ENV", "using-env") |
148 | _, err := testing.RunCommand(c, &SwitchCommand{}, []string{"erewhemos-2"}) |
149 | - c.Assert(err, gc.ErrorMatches, `Cannot switch when JUJU_ENV is overriding the environment \(set to "using-env"\)`) |
150 | + c.Assert(err, gc.ErrorMatches, `cannot switch when JUJU_ENV is overriding the environment \(set to "using-env"\)`) |
151 | } |
152 | |
153 | -const expectedEnvironments = ` |
154 | -Environments: |
155 | - erewhemos |
156 | - erewhemos-2 |
157 | +const expectedEnvironments = `erewhemos |
158 | +erewhemos-2 |
159 | ` |
160 | |
161 | func (*SwitchSimpleSuite) TestListEnvironments(c *gc.C) { |
162 | defer testing.MakeFakeHome(c, testing.MultipleEnvConfig).Restore() |
163 | context, err := testing.RunCommand(c, &SwitchCommand{}, []string{"--list"}) |
164 | c.Assert(err, gc.IsNil) |
165 | - c.Assert(testing.Stdout(context), gc.Matches, "Current environment: \"erewhemos\"(.|\n)*") |
166 | - c.Assert(testing.Stdout(context), gc.Matches, "(.|\n)*"+expectedEnvironments) |
167 | + c.Assert(testing.Stdout(context), gc.Equals, expectedEnvironments) |
168 | } |
169 | |
170 | func (*SwitchSimpleSuite) TestListEnvironmentsAndChange(c *gc.C) { |
171 | defer testing.MakeFakeHome(c, testing.MultipleEnvConfig).Restore() |
172 | - context, err := testing.RunCommand(c, &SwitchCommand{}, []string{"--list", "erewhemos-2"}) |
173 | - c.Assert(err, gc.IsNil) |
174 | - c.Assert(testing.Stdout(context), gc.Matches, "Changed default environment from \"erewhemos\" to \"erewhemos-2\"(.|\n)*") |
175 | - c.Assert(testing.Stdout(context), gc.Matches, "(.|\n)*"+expectedEnvironments) |
176 | + _, err := testing.RunCommand(c, &SwitchCommand{}, []string{"--list", "erewhemos-2"}) |
177 | + c.Assert(err, gc.ErrorMatches, "cannot switch and list at the same time") |
178 | } |
179 | |
180 | func (*SwitchSimpleSuite) TestTooManyParams(c *gc.C) { |
Reviewers: mp+191838_ code.launchpad. net,
Message:
Please take a look.
Description:
switch: more script friendly output
Changed switch command to more script friendly
output. Branch has been newly created after an
error when reverting.
https:/ /code.launchpad .net/~themue/ juju-core/ 054-env- more-script- friendly/ +merge/ 191838
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/15080044/
Affected files (+46, -42 lines): switch_ test.go
A [revision details]
M cmd/juju/switch.go
M cmd/juju/
Index: [revision details] 20131018031007- g87i6t5sgxtr7gx l
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: tarmac-
+New revision: <email address hidden>
Index: cmd/juju/switch.go switch. go'
=== modified file 'cmd/juju/
--- cmd/juju/switch.go 2013-10-08 14:53:20 +0000
+++ cmd/juju/switch.go 2013-10-18 16:43:45 +0000
@@ -19,6 +19,7 @@
cmd.CommandBase
EnvName string
List bool
+ Raw bool
}
var switchDoc = ` "JUJU_ENV" ) ctx.Stdout, "Current environment: %q (from JUJU_ENV)\n", ctx.Stdout, "%s\n", jujuEnv)
@@ -69,17 +70,17 @@
jujuEnv := os.Getenv(
if jujuEnv != "" {
if c.EnvName == "" {
- fmt.Fprintf(
jujuEnv)
+ fmt.Fprintf(
return nil
} else {
- return fmt.Errorf("Cannot switch when JUJU_ENV is overriding the
environment (set to %q)", jujuEnv)
+ return fmt.Errorf("cannot switch when JUJU_ENV is overriding the
environment (set to %q)", jujuEnv)
}
}
// Passing through the empty string reads the default environments.yaml ReadEnvirons( "") New("couldn' t read the environment.") New("couldn' t read the environment") Names() Strings( names) Default
file.
environments, err := environs.
if err != nil {
- return errors.
+ return errors.
}
names := environments.
sort.
@@ -89,32 +90,39 @@
currentEnv = environments.
}
- // In order to have only a set environment name quoted, make a small ctx.Stdout, "Current environment: %s\n", env()) ctx.Stdout, "%s (*)\n", name) ctx.Stdout, "%s\n", name) ctx.Stdout, "%s\n", currentEnv) ntName( c.EnvName, names) {
function
- env := func() string {
- if currentEnv == "" {
- return "<not specified>"
- }
- return fmt.Sprintf("%q", currentEnv)
- }
-
- if c.EnvName == "" || c.EnvName == currentEnv {
- fmt.Fprintf(
- } else {
- // Check to make sure that the specified environment
+ // Handle the different operation modes.
+ switch {
+ case c.List:
+ // List all environments.
+ if c.EnvName != "" {
+ return errors.New("cannot switch and list at the same time")
+ }
+ for _, name := range names {
+ if name == currentEnv {
+ fmt.Fprintf(
+ } else {
+ fmt.Fprintf(
+ }
+ }
+ case c.EnvName == "" && currentEnv == "":
+ // Nothing specified and nothing to switch to.
+ return errors.New("no currently specified environment")
+ case c.EnvName == "":
+ // Simply print the current environment.
+ fmt.Fprintf(
+ default:
+ // Switch the environment.
if !validEnvironme
return fmt.Errorf("%q is not a name of an existing defined
environment",...