Merge lp:~axwalk/juju-core/envcmd-inversion into lp:~go-bot/juju-core/trunk

Proposed by Andrew Wilkins
Status: Merged
Approved by: Andrew Wilkins
Approved revision: no longer in the source branch.
Merged at revision: 2721
Proposed branch: lp:~axwalk/juju-core/envcmd-inversion
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 3088 lines (+421/-485)
83 files modified
cmd/cmd.go (+12/-9)
cmd/envcmd/environmentcommand.go (+77/-37)
cmd/envcmd/environmentcommand_test.go (+42/-18)
cmd/juju/addmachine.go (+1/-5)
cmd/juju/addmachine_test.go (+2/-1)
cmd/juju/addrelation.go (+0/-3)
cmd/juju/addrelation_test.go (+2/-1)
cmd/juju/addunit.go (+0/-4)
cmd/juju/addunit_test.go (+3/-2)
cmd/juju/adduser.go (+0/-3)
cmd/juju/adduser_test.go (+15/-9)
cmd/juju/authorizedkeys.go (+5/-4)
cmd/juju/authorizedkeys_add.go (+0/-4)
cmd/juju/authorizedkeys_delete.go (+0/-4)
cmd/juju/authorizedkeys_import.go (+0/-4)
cmd/juju/authorizedkeys_list.go (+0/-8)
cmd/juju/authorizedkeys_test.go (+11/-10)
cmd/juju/bootstrap.go (+0/-4)
cmd/juju/bootstrap_test.go (+15/-14)
cmd/juju/cmd_test.go (+20/-19)
cmd/juju/constraints.go (+0/-8)
cmd/juju/constraints_test.go (+3/-2)
cmd/juju/debuglog.go (+0/-5)
cmd/juju/debuglog_test.go (+5/-4)
cmd/juju/deploy.go (+0/-4)
cmd/juju/deploy_test.go (+4/-3)
cmd/juju/endpoint.go (+0/-8)
cmd/juju/endpoint_test.go (+2/-1)
cmd/juju/ensureavailability.go (+0/-4)
cmd/juju/ensureavailability_test.go (+2/-1)
cmd/juju/environment.go (+0/-12)
cmd/juju/environment_test.go (+12/-11)
cmd/juju/expose.go (+0/-3)
cmd/juju/expose_test.go (+2/-1)
cmd/juju/get.go (+0/-4)
cmd/juju/get_test.go (+2/-1)
cmd/juju/main.go (+67/-71)
cmd/juju/main_test.go (+20/-2)
cmd/juju/plugin.go (+2/-9)
cmd/juju/publish.go (+0/-4)
cmd/juju/publish_test.go (+8/-7)
cmd/juju/removemachine.go (+0/-4)
cmd/juju/removemachine_test.go (+2/-1)
cmd/juju/removerelation.go (+0/-3)
cmd/juju/removerelation_test.go (+2/-1)
cmd/juju/removeservice.go (+0/-3)
cmd/juju/removeservice_test.go (+2/-1)
cmd/juju/removeunit.go (+0/-3)
cmd/juju/removeunit_test.go (+2/-1)
cmd/juju/removeuser.go (+0/-3)
cmd/juju/removeuser_test.go (+5/-4)
cmd/juju/resolved.go (+0/-4)
cmd/juju/resolved_test.go (+2/-1)
cmd/juju/retryprovisioning.go (+0/-3)
cmd/juju/retryprovisioning_test.go (+2/-1)
cmd/juju/run.go (+0/-4)
cmd/juju/run_test.go (+5/-4)
cmd/juju/set.go (+0/-4)
cmd/juju/set_test.go (+3/-2)
cmd/juju/ssh.go (+0/-4)
cmd/juju/ssh_test.go (+2/-1)
cmd/juju/status.go (+0/-4)
cmd/juju/status_test.go (+2/-1)
cmd/juju/synctools.go (+0/-4)
cmd/juju/synctools_test.go (+2/-1)
cmd/juju/unexpose.go (+0/-3)
cmd/juju/unexpose_test.go (+2/-1)
cmd/juju/unset.go (+0/-9)
cmd/juju/unset_test.go (+3/-2)
cmd/juju/upgradecharm.go (+0/-4)
cmd/juju/upgradecharm_test.go (+2/-1)
cmd/juju/upgradejuju.go (+0/-4)
cmd/juju/upgradejuju_test.go (+2/-1)
cmd/plugins/juju-metadata/imagemetadata.go (+0/-8)
cmd/plugins/juju-metadata/imagemetadata_test.go (+8/-7)
cmd/plugins/juju-metadata/metadata.go (+5/-4)
cmd/plugins/juju-metadata/toolsmetadata.go (+0/-8)
cmd/plugins/juju-metadata/toolsmetadata_test.go (+7/-6)
cmd/plugins/juju-metadata/validateimagemetadata.go (+0/-4)
cmd/plugins/juju-metadata/validateimagemetadata_test.go (+11/-10)
cmd/plugins/juju-metadata/validatetoolsmetadata.go (+0/-4)
cmd/plugins/juju-metadata/validatetoolsmetadata_test.go (+15/-14)
cmd/plugins/juju-restore/restore.go (+1/-5)
To merge this branch: bzr merge lp:~axwalk/juju-core/envcmd-inversion
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+219135@code.launchpad.net

Commit message

Invert envcmd relationship

Previously we embedded EnvCommandBase in all commands
requring an environment, and EnvCommandBase included
everything (SetFlags, and Init). The problem with this
is that it was easy to miss initialisation of the
EnvCommandBase type (this happened a few times), which
leads to bad things happening like sync-tools destroying
environments.

I have inverted the relationship so that we now have
envcmd.EnvironCommand, an interface that extends Command
with a SetEnvName method, and EnvCommandBase, which
implements EnvironCommand. A new method, envcmd.Wrap takes
an EnvironCommand and creates a Command that calls
SetEnvName prior to the wrapped method's Init method. If
the environment name cannot be determined, the wrapping
command will error out early.

https://codereview.appspot.com/94350045/

Description of the change

Invert envcmd relationship

Previously we embedded EnvCommandBase in all commands
requring an environment, and EnvCommandBase included
everything (SetFlags, and Init). The problem with this
is that it was easy to miss initialisation of the
EnvCommandBase type (this happened a few times), which
leads to bad things happening like sync-tools destroying
environments.

I have inverted the relationship so that we now have
envcmd.EnvironCommand, an interface that extends Command
with a SetEnvName method, and EnvCommandBase, which
implements EnvironCommand. A new method, envcmd.Wrap takes
an EnvironCommand and creates a Command that calls
SetEnvName prior to the wrapped method's Init method. If
the environment name cannot be determined, the wrapping
command will error out early.

https://codereview.appspot.com/94350045/

To post a comment you must log in.
Revision history for this message
Andrew Wilkins (axwalk) wrote :
Download full text (3.7 KiB)

Reviewers: mp+219135_code.launchpad.net,

Message:
Please take a look.

Description:
Invert envcmd relationship

Previously we embedded EnvCommandBase in all commands
requring an environment, and EnvCommandBase included
everything (SetFlags, and Init). The problem with this
is that it was easy to miss initialisation of the
EnvCommandBase type (this happened a few times), which
leads to bad things happening like sync-tools destroying
environments.

I have inverted the relationship so that we now have
envcmd.EnvironCommand, an interface that extends Command
with a SetEnvName method, and EnvCommandBase, which
implements EnvironCommand. A new method, envcmd.Wrap takes
an EnvironCommand and creates a Command that calls
SetEnvName prior to the wrapped method's Init method. If
the environment name cannot be determined, the wrapping
command will error out early.

https://code.launchpad.net/~axwalk/juju-core/envcmd-inversion/+merge/219135

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/94350045/

Affected files (+354, -440 lines):
   A [revision details]
   M cmd/cmd.go
   M cmd/envcmd/environmentcommand.go
   M cmd/envcmd/environmentcommand_test.go
   M cmd/juju/addmachine.go
   M cmd/juju/addmachine_test.go
   M cmd/juju/addrelation.go
   M cmd/juju/addrelation_test.go
   M cmd/juju/addunit.go
   M cmd/juju/addunit_test.go
   M cmd/juju/adduser.go
   M cmd/juju/adduser_test.go
   M cmd/juju/authorizedkeys_add.go
   M cmd/juju/authorizedkeys_delete.go
   M cmd/juju/authorizedkeys_import.go
   M cmd/juju/authorizedkeys_list.go
   M cmd/juju/authorizedkeys_test.go
   M cmd/juju/bootstrap.go
   M cmd/juju/bootstrap_test.go
   M cmd/juju/cmd_test.go
   M cmd/juju/constraints.go
   M cmd/juju/constraints_test.go
   M cmd/juju/debuglog.go
   M cmd/juju/debuglog_test.go
   M cmd/juju/deploy.go
   M cmd/juju/deploy_test.go
   M cmd/juju/endpoint.go
   M cmd/juju/endpoint_test.go
   M cmd/juju/ensureavailability.go
   M cmd/juju/ensureavailability_test.go
   M cmd/juju/environment.go
   M cmd/juju/environment_test.go
   M cmd/juju/expose.go
   M cmd/juju/expose_test.go
   M cmd/juju/get.go
   M cmd/juju/get_test.go
   M cmd/juju/main.go
   M cmd/juju/main_test.go
   M cmd/juju/plugin.go
   M cmd/juju/publish.go
   M cmd/juju/publish_test.go
   M cmd/juju/removemachine.go
   M cmd/juju/removemachine_test.go
   M cmd/juju/removerelation.go
   M cmd/juju/removerelation_test.go
   M cmd/juju/removeservice.go
   M cmd/juju/removeservice_test.go
   M cmd/juju/removeunit.go
   M cmd/juju/removeunit_test.go
   M cmd/juju/removeuser.go
   M cmd/juju/removeuser_test.go
   M cmd/juju/resolved.go
   M cmd/juju/resolved_test.go
   M cmd/juju/retryprovisioning.go
   M cmd/juju/retryprovisioning_test.go
   M cmd/juju/run.go
   M cmd/juju/run_test.go
   M cmd/juju/set.go
   M cmd/juju/set_test.go
   M cmd/juju/ssh.go
   M cmd/juju/ssh_test.go
   M cmd/juju/status.go
   M cmd/juju/status_test.go
   M cmd/juju/synctools.go
   M cmd/juju/synctools_test.go
   M cmd/juju/unexpose.go
   M cmd/juju/unexpose_test.go
   M cmd/juju/unset.go
   M cmd/juju/unset_test.go
   M cmd/juju/upgradecharm.go
   M cmd/juju/upgradecharm_test....

Read more...

Revision history for this message
Ian Booth (wallyworld) wrote :

LGTM with perhaps a 2nd opinion from William.

It does seem that we are missing tests to ensure that each command is
wrapped as expected. We test the wrapping function itself in
environmentcommand but I can't see how or where we are testing that each
business command is wrapped eg for add-machine, how do we test that it
has been registered using
jujucmd.Register(wrap(&AddMachineCommand{}))and not just
jujucmd.Register(&AddMachineCommand{})

We should be able to iterate over all registered commands to check. Can
we do this before landing?

https://codereview.appspot.com/94350045/

Revision history for this message
William Reade (fwereade) wrote :

This LGTM as far as it goes (modulo the need for testing -- I'd like it
to be impossible to *casually* add a command that isn't an environment
command).

But I'm wondering whether it's rational to take it a step further -- do
something like insert the EnvName into the Run args, such that the
commands we create/test/etc are not actually cmd.Commands -- thereby
making it impossible(?) to accidentally register an unwrapped env
command.

FWIW, if it were structured that way, I'd be less dogmatic about the
need for testing the list of registered commands...

https://codereview.appspot.com/94350045/diff/1/cmd/juju/main.go
File cmd/juju/main.go (right):

https://codereview.appspot.com/94350045/diff/1/cmd/juju/main.go#newcode140
cmd/juju/main.go:140: jujucmd.Register(wrap(&cmd.VersionCommand{}))
Yeah, as Ian suggested, I'd really like us to be able to directly test
that we actually get functional environment commands -- and ideally we'd
get this tested on *every* registered command.

https://codereview.appspot.com/94350045/

Revision history for this message
Andrew Wilkins (axwalk) wrote :

On 2014/05/12 07:24:18, fwereade wrote:
> This LGTM as far as it goes (modulo the need for testing -- I'd like
it to be
> impossible to *casually* add a command that isn't an environment
command).

> But I'm wondering whether it's rational to take it a step further --
do
> something like insert the EnvName into the Run args, such that the
commands we
> create/test/etc are not actually cmd.Commands -- thereby making it
impossible(?)
> to accidentally register an unwrapped env command.

Not all commands operate on an environment. I started down this path of
having an alternative Run method (RunInEnv) which takes *cmd.Context and
envName, but found it too clumsy. The approach I've taken takes us in
that direction, so it could be changed with less churn later if desired.

> FWIW, if it were structured that way, I'd be less dogmatic about the
need for
> testing the list of registered commands...

> https://codereview.appspot.com/94350045/diff/1/cmd/juju/main.go
> File cmd/juju/main.go (right):

https://codereview.appspot.com/94350045/diff/1/cmd/juju/main.go#newcode140
> cmd/juju/main.go:140: jujucmd.Register(wrap(&cmd.VersionCommand{}))
> Yeah, as Ian suggested, I'd really like us to be able to directly test
that we
> actually get functional environment commands -- and ideally we'd get
this tested
> on *every* registered command.

I'll add a test that checks each registered command is an environment
command, with a list of exceptions.

https://codereview.appspot.com/94350045/

Revision history for this message
Andrew Wilkins (axwalk) wrote :

On 2014/05/12 07:53:07, axw wrote:
> On 2014/05/12 07:24:18, fwereade wrote:
> > This LGTM as far as it goes (modulo the need for testing -- I'd like
it to be
> > impossible to *casually* add a command that isn't an environment
command).
> >
> > But I'm wondering whether it's rational to take it a step further --
do
> > something like insert the EnvName into the Run args, such that the
commands we
> > create/test/etc are not actually cmd.Commands -- thereby making it
> impossible(?)
> > to accidentally register an unwrapped env command.

> Not all commands operate on an environment. I started down this path
of having
> an alternative Run method (RunInEnv) which takes *cmd.Context and
envName, but
> found it too clumsy. The approach I've taken takes us in that
direction, so it
> could be changed with less churn later if desired.

> > FWIW, if it were structured that way, I'd be less dogmatic about the
need for
> > testing the list of registered commands...
> >
> > https://codereview.appspot.com/94350045/diff/1/cmd/juju/main.go
> > File cmd/juju/main.go (right):
> >
> >
https://codereview.appspot.com/94350045/diff/1/cmd/juju/main.go#newcode140
> > cmd/juju/main.go:140: jujucmd.Register(wrap(&cmd.VersionCommand{}))
> > Yeah, as Ian suggested, I'd really like us to be able to directly
test that we
> > actually get functional environment commands -- and ideally we'd get
this
> tested
> > on *every* registered command.

> I'll add a test that checks each registered command is an environment
command,
> with a list of exceptions.

Actually the test is simpler than that: it just checks that there are no
EnvironCommands registered. All EnvironCommands must be wrapped.

https://codereview.appspot.com/94350045/

Revision history for this message
Andrew Wilkins (axwalk) wrote :
Revision history for this message
Ian Booth (wallyworld) wrote :

On 2014/05/12 11:11:19, axw wrote:
> Please take a look.

LGTM

https://codereview.appspot.com/94350045/

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (11.8 KiB)

The attempt to merge lp:~axwalk/juju-core/envcmd-inversion into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.013s
ok launchpad.net/juju-core/agent 0.885s
ok launchpad.net/juju-core/agent/mongo 0.441s
ok launchpad.net/juju-core/agent/tools 0.219s
ok launchpad.net/juju-core/bzr 4.744s
ok launchpad.net/juju-core/cert 2.578s
ok launchpad.net/juju-core/charm 0.511s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.026s
ok launchpad.net/juju-core/cloudinit/sshinit 0.781s
ok launchpad.net/juju-core/cmd 0.142s
ok launchpad.net/juju-core/cmd/charm-admin 0.276s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/envcmd 0.181s
ok launchpad.net/juju-core/cmd/juju 218.654s
ok launchpad.net/juju-core/cmd/jujud 65.577s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 9.149s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.179s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.028s
ok launchpad.net/juju-core/container 0.040s
ok launchpad.net/juju-core/container/factory 0.037s
ok launchpad.net/juju-core/container/kvm 0.166s
ok launchpad.net/juju-core/container/kvm/mock 0.040s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.283s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.206s
ok launchpad.net/juju-core/environs 2.176s
ok launchpad.net/juju-core/environs/bootstrap 12.224s
ok launchpad.net/juju-core/environs/cloudinit 0.420s
ok launchpad.net/juju-core/environs/config 1.910s
ok launchpad.net/juju-core/environs/configstore 0.029s
ok launchpad.net/juju-core/environs/filestorage 0.024s
ok launchpad.net/juju-core/environs/httpstorage 0.645s
ok launchpad.net/juju-core/environs/imagemetadata 0.416s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.044s
ok launchpad.net/juju-core/environs/jujutest 0.168s
ok launchpad.net/juju-core/environs/manual 8.986s
? launchpad.net/juju-core/environs/network [no test files]
ok launchpad.net/juju-core/environs/simplestreams 0.246s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 0.858s
ok launchpad.net/juju-core/environs/storage 0.757s
ok launchpad.net/juju-core/environs/sync 50.475s
ok launchpad.net/juju-core/environs/testing 0.133s
ok launchpad.net/juju-core/environs/tools 4.920s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.015s
ok launchpad.net/juju-core/instance 0.019s
? launchpad.net/juju-core/instance/testing [...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cmd/cmd.go'
2--- cmd/cmd.go 2014-04-01 07:47:11 +0000
3+++ cmd/cmd.go 2014-05-12 11:08:32 +0000
4@@ -210,20 +210,23 @@
5 return buf.Bytes()
6 }
7
8-// Errors from commands can be either ErrHelp, which means "show the help" or
9-// some other error related to needed flags missing, or needed positional args
10-// missing, in which case we should print the error and return a non-zero
11-// return code.
12-func handleCommandError(c Command, ctx *Context, err error, f *gnuflag.FlagSet) (int, bool) {
13- if err == gnuflag.ErrHelp {
14+// Errors from commands can be ErrSilent (don't print an error message),
15+// ErrHelp (show the help) or some other error related to needed flags
16+// missing, or needed positional args missing, in which case we should
17+// print the error and return a non-zero return code.
18+func handleCommandError(c Command, ctx *Context, err error, f *gnuflag.FlagSet) (rc int, done bool) {
19+ switch err {
20+ case nil:
21+ return 0, false
22+ case gnuflag.ErrHelp:
23 ctx.Stdout.Write(c.Info().Help(f))
24 return 0, true
25- }
26- if err != nil {
27+ case ErrSilent:
28+ return 2, true
29+ default:
30 fmt.Fprintf(ctx.Stderr, "error: %v\n", err)
31 return 2, true
32 }
33- return 0, false
34 }
35
36 // Main runs the given Command in the supplied Context with the given
37
38=== modified file 'cmd/envcmd/environmentcommand.go'
39--- cmd/envcmd/environmentcommand.go 2014-05-09 13:24:50 +0000
40+++ cmd/envcmd/environmentcommand.go 2014-05-12 11:08:32 +0000
41@@ -24,13 +24,6 @@
42 // has been explicitly specified, and there is no default environment.
43 var ErrNoEnvironmentSpecified = fmt.Errorf("no environment specified")
44
45-// The purpose of EnvCommandBase is to provide a default member and flag
46-// setting for commands that deal across different environments.
47-type EnvCommandBase struct {
48- cmd.CommandBase
49- EnvName string
50-}
51-
52 func getCurrentEnvironmentFilePath() string {
53 return filepath.Join(osenv.JujuHome(), CurrentEnvironmentFilename)
54 }
55@@ -60,39 +53,86 @@
56
57 // There is simple ordering for the default environment. Firstly check the
58 // JUJU_ENV environment variable. If that is set, it gets used. If it isn't
59-// set, look in the $JUJU_HOME/current-environment file.
60-func getDefaultEnvironment() string {
61- defaultEnv := os.Getenv(osenv.JujuEnvEnvKey)
62- if defaultEnv != "" {
63- return defaultEnv
64- }
65- return ReadCurrentEnvironment()
66-}
67-
68-// EnsureEnvName ensures that c.EnvName is non-empty, or sets it to the default
69-// environment name. If there is no default environment name, then
70-// EnsureEnvName returns ErrNoEnvironmentSpecified.
71-func (c *EnvCommandBase) EnsureEnvName() error {
72- if c.EnvName == "" {
73- envs, err := environs.ReadEnvirons("")
74- if err != nil {
75- return err
76- }
77- if envs.Default == "" {
78- return ErrNoEnvironmentSpecified
79- }
80- c.EnvName = envs.Default
81- }
82+// set, look in the $JUJU_HOME/current-environment file. If neither are
83+// available, read environments.yaml and use the default environment therein.
84+func getDefaultEnvironment() (string, error) {
85+ if defaultEnv := os.Getenv(osenv.JujuEnvEnvKey); defaultEnv != "" {
86+ return defaultEnv, nil
87+ }
88+ if currentEnv := ReadCurrentEnvironment(); currentEnv != "" {
89+ return currentEnv, nil
90+ }
91+ envs, err := environs.ReadEnvirons("")
92+ if err != nil {
93+ return "", err
94+ }
95+ if envs.Default == "" {
96+ return "", ErrNoEnvironmentSpecified
97+ }
98+ return envs.Default, nil
99+}
100+
101+// EnvironCommand extends cmd.Command with a SetEnvName method.
102+type EnvironCommand interface {
103+ cmd.Command
104+
105+ // SetEnvName is called prior to the wrapped command's Init method
106+ // with the active environment name. The environment name is guaranteed
107+ // to be non-empty at entry of Init.
108+ SetEnvName(envName string)
109+}
110+
111+// EnvCommandBase is a convenience type for embedding in commands
112+// that wish to implement EnvironCommand.
113+type EnvCommandBase struct {
114+ cmd.CommandBase
115+ EnvName string
116+}
117+
118+func (c *EnvCommandBase) SetEnvName(envName string) {
119+ c.EnvName = envName
120+}
121+
122+// Wrap wraps the specified EnvironCommand, returning a Command
123+// that proxies to each of the EnvironCommand methods.
124+func Wrap(c EnvironCommand) cmd.Command {
125+ return &environCommandWrapper{EnvironCommand: c}
126+}
127+
128+type environCommandWrapper struct {
129+ EnvironCommand
130+ envName string
131+}
132+
133+func (w *environCommandWrapper) EnvironName() string {
134+ return w.envName
135+}
136+
137+// ensureEnvName ensures that w.envName is non-empty, or sets it to
138+// the default environment name. If there is no default environment name,
139+// then ensureEnvName returns ErrNoEnvironmentSpecified.
140+func (w *environCommandWrapper) ensureEnvName() error {
141+ if w.envName != "" {
142+ return nil
143+ }
144+ defaultEnv, err := getDefaultEnvironment()
145+ if err != nil {
146+ return err
147+ }
148+ w.envName = defaultEnv
149 return nil
150 }
151
152-func (c *EnvCommandBase) SetFlags(f *gnuflag.FlagSet) {
153- defaultEnv := getDefaultEnvironment()
154- f.StringVar(&c.EnvName, "e", defaultEnv, "juju environment to operate in")
155- f.StringVar(&c.EnvName, "environment", defaultEnv, "")
156+func (w *environCommandWrapper) SetFlags(f *gnuflag.FlagSet) {
157+ f.StringVar(&w.envName, "e", "", "juju environment to operate in")
158+ f.StringVar(&w.envName, "environment", "", "")
159+ w.EnvironCommand.SetFlags(f)
160 }
161
162-// EnvironName returns the name of the environment for this command
163-func (c *EnvCommandBase) EnvironName() string {
164- return c.EnvName
165+func (w *environCommandWrapper) Init(args []string) error {
166+ if err := w.ensureEnvName(); err != nil {
167+ return err
168+ }
169+ w.SetEnvName(w.envName)
170+ return w.EnvironCommand.Init(args)
171 }
172
173=== modified file 'cmd/envcmd/environmentcommand_test.go'
174--- cmd/envcmd/environmentcommand_test.go 2014-05-09 13:24:50 +0000
175+++ cmd/envcmd/environmentcommand_test.go 2014-05-12 11:08:32 +0000
176@@ -12,6 +12,7 @@
177 "launchpad.net/gnuflag"
178 gc "launchpad.net/gocheck"
179
180+ "launchpad.net/juju-core/cmd"
181 "launchpad.net/juju-core/cmd/envcmd"
182 "launchpad.net/juju-core/environs"
183 "launchpad.net/juju-core/juju/osenv"
184@@ -47,29 +48,33 @@
185 }
186
187 func (s *EnvironmentCommandSuite) TestGetDefaultEnvironmentNothingSet(c *gc.C) {
188- env := envcmd.GetDefaultEnvironment()
189+ env, err := envcmd.GetDefaultEnvironment()
190 c.Assert(env, gc.Equals, "")
191+ c.Assert(err, jc.Satisfies, environs.IsNoEnv)
192 }
193
194 func (s *EnvironmentCommandSuite) TestGetDefaultEnvironmentCurrentEnvironmentSet(c *gc.C) {
195 err := envcmd.WriteCurrentEnvironment("fubar")
196 c.Assert(err, gc.IsNil)
197- env := envcmd.GetDefaultEnvironment()
198+ env, err := envcmd.GetDefaultEnvironment()
199 c.Assert(env, gc.Equals, "fubar")
200+ c.Assert(err, gc.IsNil)
201 }
202
203 func (s *EnvironmentCommandSuite) TestGetDefaultEnvironmentJujuEnvSet(c *gc.C) {
204 os.Setenv(osenv.JujuEnvEnvKey, "magic")
205- env := envcmd.GetDefaultEnvironment()
206+ env, err := envcmd.GetDefaultEnvironment()
207 c.Assert(env, gc.Equals, "magic")
208+ c.Assert(err, gc.IsNil)
209 }
210
211 func (s *EnvironmentCommandSuite) TestGetDefaultEnvironmentBothSet(c *gc.C) {
212 os.Setenv(osenv.JujuEnvEnvKey, "magic")
213 err := envcmd.WriteCurrentEnvironment("fubar")
214 c.Assert(err, gc.IsNil)
215- env := envcmd.GetDefaultEnvironment()
216+ env, err := envcmd.GetDefaultEnvironment()
217 c.Assert(env, gc.Equals, "magic")
218+ c.Assert(err, gc.IsNil)
219 }
220
221 func (s *EnvironmentCommandSuite) TestWriteAddsNewline(c *gc.C) {
222@@ -87,12 +92,12 @@
223 c.Assert(err, gc.ErrorMatches, "unable to write to the environment file: .*")
224 }
225
226-func (s *EnvironmentCommandSuite) TestEnsureEnvName(c *gc.C) {
227+func (s *EnvironmentCommandSuite) TestEnvironCommandInit(c *gc.C) {
228 // Take environment name from command line arg.
229- cmd := initEnvCommandBase(c, "explicit")
230- err := cmd.EnsureEnvName()
231+ cmd, envName := prepareEnvCommand(c, "explicit")
232+ err := cmd.Init(nil)
233 c.Assert(err, gc.IsNil)
234- c.Assert(cmd.EnvName, gc.Equals, "explicit")
235+ c.Assert(*envName, gc.Equals, "explicit")
236
237 // Take environment name from the default.
238 defer coretesting.MakeFakeHome(c, coretesting.MultipleEnvConfig).Restore()
239@@ -108,33 +113,52 @@
240 testEnsureEnvName(c, "fubar")
241 }
242
243-func (s *EnvironmentCommandSuite) TestEnsureEnvNameErrors(c *gc.C) {
244- err := initEnvCommandBase(c, "").EnsureEnvName()
245+func (s *EnvironmentCommandSuite) TestEnvironCommandInitErrors(c *gc.C) {
246+ cmd, _ := prepareEnvCommand(c, "")
247+ err := cmd.Init(nil)
248 c.Assert(err, jc.Satisfies, environs.IsNoEnv)
249
250 // If there are multiple environments but no default,
251 // an error should be returned.
252 defer coretesting.MakeFakeHome(c, coretesting.MultipleEnvConfigNoDefault).Restore()
253- err = initEnvCommandBase(c, "").EnsureEnvName()
254+ cmd, _ = prepareEnvCommand(c, "")
255+ err = cmd.Init(nil)
256 c.Assert(err, gc.Equals, envcmd.ErrNoEnvironmentSpecified)
257 }
258
259-func initEnvCommandBase(c *gc.C, name string) *envcmd.EnvCommandBase {
260+type testCommand struct {
261+ envcmd.EnvCommandBase
262+}
263+
264+func (c *testCommand) Info() *cmd.Info {
265+ panic("should not be called")
266+}
267+
268+func (c *testCommand) Run(ctx *cmd.Context) error {
269+ panic("should not be called")
270+}
271+
272+// prepareEnvCommand prepares a Command for a call to Init,
273+// returning the Command and a pointer to a string that will
274+// contain the environment name after the Command's Init method
275+// has been called.
276+func prepareEnvCommand(c *gc.C, name string) (cmd.Command, *string) {
277 var flags gnuflag.FlagSet
278- var cmd envcmd.EnvCommandBase
279- cmd.SetFlags(&flags)
280+ var cmd testCommand
281+ wrapped := envcmd.Wrap(&cmd)
282+ wrapped.SetFlags(&flags)
283 var args []string
284 if name != "" {
285 args = []string{"-e", name}
286 }
287 err := flags.Parse(false, args)
288 c.Assert(err, gc.IsNil)
289- return &cmd
290+ return wrapped, &cmd.EnvName
291 }
292
293 func testEnsureEnvName(c *gc.C, expect string) {
294- cmd := initEnvCommandBase(c, "")
295- err := cmd.EnsureEnvName()
296+ cmd, envName := prepareEnvCommand(c, "")
297+ err := cmd.Init(nil)
298 c.Assert(err, gc.IsNil)
299- c.Assert(cmd.EnvName, gc.Equals, expect)
300+ c.Assert(*envName, gc.Equals, expect)
301 }
302
303=== modified file 'cmd/juju/addmachine.go'
304--- cmd/juju/addmachine.go 2014-05-09 13:24:50 +0000
305+++ cmd/juju/addmachine.go 2014-05-12 11:08:32 +0000
306@@ -74,15 +74,11 @@
307 }
308
309 func (c *AddMachineCommand) SetFlags(f *gnuflag.FlagSet) {
310- c.EnvCommandBase.SetFlags(f)
311 f.StringVar(&c.Series, "series", "", "the charm series")
312 f.Var(constraints.ConstraintsValue{Target: &c.Constraints}, "constraints", "additional machine constraints")
313 }
314
315 func (c *AddMachineCommand) Init(args []string) error {
316- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
317- return err
318- }
319 if c.Constraints.Container != nil {
320 return fmt.Errorf("container constraint %q not allowed when adding a machine", *c.Constraints.Container)
321 }
322@@ -92,7 +88,7 @@
323 }
324 c.Placement, err = instance.ParsePlacement(placement)
325 if err == instance.ErrPlacementScopeMissing {
326- placement = c.EnvironName() + ":" + placement
327+ placement = c.EnvName + ":" + placement
328 c.Placement, err = instance.ParsePlacement(placement)
329 }
330 if err != nil {
331
332=== modified file 'cmd/juju/addmachine_test.go'
333--- cmd/juju/addmachine_test.go 2014-04-23 05:38:27 +0000
334+++ cmd/juju/addmachine_test.go 2014-05-12 11:08:32 +0000
335@@ -10,6 +10,7 @@
336 jc "github.com/juju/testing/checkers"
337 gc "launchpad.net/gocheck"
338
339+ "launchpad.net/juju-core/cmd/envcmd"
340 "launchpad.net/juju-core/constraints"
341 "launchpad.net/juju-core/instance"
342 jujutesting "launchpad.net/juju-core/juju/testing"
343@@ -24,7 +25,7 @@
344 var _ = gc.Suite(&AddMachineSuite{})
345
346 func runAddMachine(c *gc.C, args ...string) error {
347- _, err := testing.RunCommand(c, &AddMachineCommand{}, args)
348+ _, err := testing.RunCommand(c, envcmd.Wrap(&AddMachineCommand{}), args)
349 return err
350 }
351
352
353=== modified file 'cmd/juju/addrelation.go'
354--- cmd/juju/addrelation.go 2014-05-09 13:24:50 +0000
355+++ cmd/juju/addrelation.go 2014-05-12 11:08:32 +0000
356@@ -26,9 +26,6 @@
357 }
358
359 func (c *AddRelationCommand) Init(args []string) error {
360- if err := c.EnsureEnvName(); err != nil {
361- return err
362- }
363 if len(args) != 2 {
364 return fmt.Errorf("a relation must involve two services")
365 }
366
367=== modified file 'cmd/juju/addrelation_test.go'
368--- cmd/juju/addrelation_test.go 2013-09-13 14:48:13 +0000
369+++ cmd/juju/addrelation_test.go 2014-05-12 11:08:32 +0000
370@@ -6,6 +6,7 @@
371 import (
372 gc "launchpad.net/gocheck"
373
374+ "launchpad.net/juju-core/cmd/envcmd"
375 jujutesting "launchpad.net/juju-core/juju/testing"
376 "launchpad.net/juju-core/testing"
377 )
378@@ -17,7 +18,7 @@
379 var _ = gc.Suite(&AddRelationSuite{})
380
381 func runAddRelation(c *gc.C, args ...string) error {
382- _, err := testing.RunCommand(c, &AddRelationCommand{}, args)
383+ _, err := testing.RunCommand(c, envcmd.Wrap(&AddRelationCommand{}), args)
384 return err
385 }
386
387
388=== modified file 'cmd/juju/addunit.go'
389--- cmd/juju/addunit.go 2014-05-09 13:24:50 +0000
390+++ cmd/juju/addunit.go 2014-05-12 11:08:32 +0000
391@@ -74,15 +74,11 @@
392 }
393
394 func (c *AddUnitCommand) SetFlags(f *gnuflag.FlagSet) {
395- c.EnvCommandBase.SetFlags(f)
396 c.UnitCommandBase.SetFlags(f)
397 f.IntVar(&c.NumUnits, "n", 1, "number of service units to add")
398 }
399
400 func (c *AddUnitCommand) Init(args []string) error {
401- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
402- return err
403- }
404 switch len(args) {
405 case 1:
406 c.ServiceName = args[0]
407
408=== modified file 'cmd/juju/addunit_test.go'
409--- cmd/juju/addunit_test.go 2013-12-05 17:30:02 +0000
410+++ cmd/juju/addunit_test.go 2014-05-12 11:08:32 +0000
411@@ -7,6 +7,7 @@
412 gc "launchpad.net/gocheck"
413
414 "launchpad.net/juju-core/charm"
415+ "launchpad.net/juju-core/cmd/envcmd"
416 "launchpad.net/juju-core/instance"
417 jujutesting "launchpad.net/juju-core/juju/testing"
418 "launchpad.net/juju-core/state"
419@@ -38,13 +39,13 @@
420 func (s *AddUnitSuite) TestInitErrors(c *gc.C) {
421 for i, t := range initAddUnitErrorTests {
422 c.Logf("test %d", i)
423- err := testing.InitCommand(&AddUnitCommand{}, t.args)
424+ err := testing.InitCommand(envcmd.Wrap(&AddUnitCommand{}), t.args)
425 c.Check(err, gc.ErrorMatches, t.err)
426 }
427 }
428
429 func runAddUnit(c *gc.C, args ...string) error {
430- _, err := testing.RunCommand(c, &AddUnitCommand{}, args)
431+ _, err := testing.RunCommand(c, envcmd.Wrap(&AddUnitCommand{}), args)
432 return err
433 }
434
435
436=== modified file 'cmd/juju/adduser.go'
437--- cmd/juju/adduser.go 2014-05-09 13:24:50 +0000
438+++ cmd/juju/adduser.go 2014-05-12 11:08:32 +0000
439@@ -51,9 +51,6 @@
440 })
441 }
442 func (c *AddUserCommand) Init(args []string) error {
443- if err := c.EnsureEnvName(); err != nil {
444- return err
445- }
446 switch len(args) {
447 case 0:
448 return fmt.Errorf("no username supplied")
449
450=== modified file 'cmd/juju/adduser_test.go'
451--- cmd/juju/adduser_test.go 2014-03-28 10:55:18 +0000
452+++ cmd/juju/adduser_test.go 2014-05-12 11:08:32 +0000
453@@ -11,6 +11,8 @@
454 "launchpad.net/goyaml"
455 jujutesting "launchpad.net/juju-core/juju/testing"
456
457+ "launchpad.net/juju-core/cmd"
458+ "launchpad.net/juju-core/cmd/envcmd"
459 "launchpad.net/juju-core/testing"
460 )
461
462@@ -22,22 +24,26 @@
463
464 var _ = gc.Suite(&AddUserSuite{})
465
466+func newAddUserCommand() cmd.Command {
467+ return envcmd.Wrap(&AddUserCommand{})
468+}
469+
470 func (s *AddUserSuite) TestAddUser(c *gc.C) {
471
472- _, err := testing.RunCommand(c, &AddUserCommand{}, []string{"foobar", "password"})
473+ _, err := testing.RunCommand(c, newAddUserCommand(), []string{"foobar", "password"})
474 c.Assert(err, gc.IsNil)
475
476- _, err = testing.RunCommand(c, &AddUserCommand{}, []string{"foobar", "newpassword"})
477+ _, err = testing.RunCommand(c, newAddUserCommand(), []string{"foobar", "newpassword"})
478 c.Assert(err, gc.ErrorMatches, "Failed to create user: user already exists")
479 }
480
481 func (s *AddUserSuite) TestTooManyArgs(c *gc.C) {
482- _, err := testing.RunCommand(c, &AddUserCommand{}, []string{"foobar", "password", "whoops"})
483+ _, err := testing.RunCommand(c, newAddUserCommand(), []string{"foobar", "password", "whoops"})
484 c.Assert(err, gc.ErrorMatches, `unrecognized args: \["whoops"\]`)
485 }
486
487 func (s *AddUserSuite) TestNotEnoughArgs(c *gc.C) {
488- _, err := testing.RunCommand(c, &AddUserCommand{}, []string{})
489+ _, err := testing.RunCommand(c, newAddUserCommand(), []string{})
490 c.Assert(err, gc.ErrorMatches, `no username supplied`)
491 }
492
493@@ -50,7 +56,7 @@
494 tempFile, err := ioutil.TempFile("", "adduser-test")
495 tempFile.Close()
496 c.Assert(err, gc.IsNil)
497- _, err = testing.RunCommand(c, &AddUserCommand{}, []string{"foobar", "password", "-o", tempFile.Name()})
498+ _, err = testing.RunCommand(c, newAddUserCommand(), []string{"foobar", "password", "-o", tempFile.Name()})
499 c.Assert(err, gc.IsNil)
500 data, err := ioutil.ReadFile(tempFile.Name())
501 result := map[string]interface{}{}
502@@ -65,7 +71,7 @@
503 "password": "password",
504 "state-servers": []interface{}{},
505 "ca-cert": ""}
506- ctx, err := testing.RunCommand(c, &AddUserCommand{}, []string{"foobar", "password"})
507+ ctx, err := testing.RunCommand(c, newAddUserCommand(), []string{"foobar", "password"})
508 c.Assert(err, gc.IsNil)
509 stdout := ctx.Stdout.(*bytes.Buffer).Bytes()
510 result := map[string]interface{}{}
511@@ -80,7 +86,7 @@
512 tempFile, err := ioutil.TempFile("", "adduser-test")
513 tempFile.Close()
514 c.Assert(err, gc.IsNil)
515- _, err = testing.RunCommand(c, &AddUserCommand{}, []string{"foobar", "password", "-o", tempFile.Name(), "--format", "json"})
516+ _, err = testing.RunCommand(c, newAddUserCommand(), []string{"foobar", "password", "-o", tempFile.Name(), "--format", "json"})
517 c.Assert(err, gc.IsNil)
518 data, err := ioutil.ReadFile(tempFile.Name())
519 c.Assert(string(data), gc.DeepEquals, expected)
520@@ -89,14 +95,14 @@
521 func (s *AddUserSuite) TestJenvJsonFileOutput(c *gc.C) {
522 expected := `{"User":"foobar","Password":"password","state-servers":null,"ca-cert":""}
523 `
524- ctx, err := testing.RunCommand(c, &AddUserCommand{}, []string{"foobar", "password", "--format", "json"})
525+ ctx, err := testing.RunCommand(c, newAddUserCommand(), []string{"foobar", "password", "--format", "json"})
526 c.Assert(err, gc.IsNil)
527 stdout := ctx.Stdout.(*bytes.Buffer).String()
528 c.Assert(stdout, gc.DeepEquals, expected)
529 }
530
531 func (s *AddUserSuite) TestGeneratePassword(c *gc.C) {
532- ctx, err := testing.RunCommand(c, &AddUserCommand{}, []string{"foobar"})
533+ ctx, err := testing.RunCommand(c, newAddUserCommand(), []string{"foobar"})
534 c.Assert(err, gc.IsNil)
535 stdout := ctx.Stdout.(*bytes.Buffer).Bytes()
536 var d map[string]interface{}
537
538=== modified file 'cmd/juju/authorizedkeys.go'
539--- cmd/juju/authorizedkeys.go 2014-04-25 06:39:01 +0000
540+++ cmd/juju/authorizedkeys.go 2014-05-12 11:08:32 +0000
541@@ -7,6 +7,7 @@
542 "launchpad.net/gnuflag"
543
544 "launchpad.net/juju-core/cmd"
545+ "launchpad.net/juju-core/cmd/envcmd"
546 )
547
548 var authKeysDoc = `
549@@ -29,10 +30,10 @@
550 Aliases: []string{"authorised-keys"},
551 }),
552 }
553- sshkeyscmd.Register(&AddKeysCommand{})
554- sshkeyscmd.Register(&DeleteKeysCommand{})
555- sshkeyscmd.Register(&ImportKeysCommand{})
556- sshkeyscmd.Register(&ListKeysCommand{})
557+ sshkeyscmd.Register(envcmd.Wrap(&AddKeysCommand{}))
558+ sshkeyscmd.Register(envcmd.Wrap(&DeleteKeysCommand{}))
559+ sshkeyscmd.Register(envcmd.Wrap(&ImportKeysCommand{}))
560+ sshkeyscmd.Register(envcmd.Wrap(&ListKeysCommand{}))
561 return sshkeyscmd
562 }
563
564
565=== modified file 'cmd/juju/authorizedkeys_add.go'
566--- cmd/juju/authorizedkeys_add.go 2014-05-09 13:24:50 +0000
567+++ cmd/juju/authorizedkeys_add.go 2014-05-12 11:08:32 +0000
568@@ -35,9 +35,6 @@
569 }
570
571 func (c *AddKeysCommand) Init(args []string) error {
572- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
573- return err
574- }
575 switch len(args) {
576 case 0:
577 return errors.New("no ssh key specified")
578@@ -48,7 +45,6 @@
579 }
580
581 func (c *AddKeysCommand) SetFlags(f *gnuflag.FlagSet) {
582- c.EnvCommandBase.SetFlags(f)
583 f.StringVar(&c.user, "user", "admin", "the user for which to add the keys")
584 }
585
586
587=== modified file 'cmd/juju/authorizedkeys_delete.go'
588--- cmd/juju/authorizedkeys_delete.go 2014-05-09 13:24:50 +0000
589+++ cmd/juju/authorizedkeys_delete.go 2014-05-12 11:08:32 +0000
590@@ -37,9 +37,6 @@
591 }
592
593 func (c *DeleteKeysCommand) Init(args []string) error {
594- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
595- return err
596- }
597 switch len(args) {
598 case 0:
599 return errors.New("no ssh key id specified")
600@@ -50,7 +47,6 @@
601 }
602
603 func (c *DeleteKeysCommand) SetFlags(f *gnuflag.FlagSet) {
604- c.EnvCommandBase.SetFlags(f)
605 f.StringVar(&c.user, "user", "admin", "the user for which to delete the keys")
606 }
607
608
609=== modified file 'cmd/juju/authorizedkeys_import.go'
610--- cmd/juju/authorizedkeys_import.go 2014-05-09 13:24:50 +0000
611+++ cmd/juju/authorizedkeys_import.go 2014-05-12 11:08:32 +0000
612@@ -36,9 +36,6 @@
613 }
614
615 func (c *ImportKeysCommand) Init(args []string) error {
616- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
617- return err
618- }
619 switch len(args) {
620 case 0:
621 return errors.New("no ssh key id specified")
622@@ -49,7 +46,6 @@
623 }
624
625 func (c *ImportKeysCommand) SetFlags(f *gnuflag.FlagSet) {
626- c.EnvCommandBase.SetFlags(f)
627 f.StringVar(&c.user, "user", "admin", "the user for which to import the keys")
628 }
629
630
631=== modified file 'cmd/juju/authorizedkeys_list.go'
632--- cmd/juju/authorizedkeys_list.go 2014-05-09 13:24:50 +0000
633+++ cmd/juju/authorizedkeys_list.go 2014-05-12 11:08:32 +0000
634@@ -37,18 +37,10 @@
635 }
636
637 func (c *ListKeysCommand) SetFlags(f *gnuflag.FlagSet) {
638- c.EnvCommandBase.SetFlags(f)
639 f.BoolVar(&c.showFullKey, "full", false, "show full key instead of just the key fingerprint")
640 f.StringVar(&c.user, "user", "admin", "the user for which to list the keys")
641 }
642
643-func (c *ListKeysCommand) Init(args []string) error {
644- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
645- return err
646- }
647- return cmd.CheckEmpty(args)
648-}
649-
650 func (c *ListKeysCommand) Run(context *cmd.Context) error {
651 client, err := juju.NewKeyManagerClient(c.EnvName)
652 if err != nil {
653
654=== modified file 'cmd/juju/authorizedkeys_test.go'
655--- cmd/juju/authorizedkeys_test.go 2014-04-25 06:39:01 +0000
656+++ cmd/juju/authorizedkeys_test.go 2014-05-12 11:08:32 +0000
657@@ -9,6 +9,7 @@
658
659 gc "launchpad.net/gocheck"
660
661+ "launchpad.net/juju-core/cmd/envcmd"
662 "launchpad.net/juju-core/juju/osenv"
663 jujutesting "launchpad.net/juju-core/juju/testing"
664 keymanagerserver "launchpad.net/juju-core/state/apiserver/keymanager"
665@@ -127,7 +128,7 @@
666 key2 := sshtesting.ValidKeyTwo.Key + " another@host"
667 s.setAuthorizedKeys(c, key1, key2)
668
669- context, err := coretesting.RunCommand(c, &ListKeysCommand{}, []string{})
670+ context, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}), []string{})
671 c.Assert(err, gc.IsNil)
672 output := strings.TrimSpace(coretesting.Stdout(context))
673 c.Assert(err, gc.IsNil)
674@@ -139,7 +140,7 @@
675 key2 := sshtesting.ValidKeyTwo.Key + " another@host"
676 s.setAuthorizedKeys(c, key1, key2)
677
678- context, err := coretesting.RunCommand(c, &ListKeysCommand{}, []string{"--full"})
679+ context, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}), []string{"--full"})
680 c.Assert(err, gc.IsNil)
681 output := strings.TrimSpace(coretesting.Stdout(context))
682 c.Assert(err, gc.IsNil)
683@@ -153,7 +154,7 @@
684 _, err := s.State.AddUser("fred", "password")
685 c.Assert(err, gc.IsNil)
686
687- context, err := coretesting.RunCommand(c, &ListKeysCommand{}, []string{"--user", "fred"})
688+ context, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}), []string{"--user", "fred"})
689 c.Assert(err, gc.IsNil)
690 output := strings.TrimSpace(coretesting.Stdout(context))
691 c.Assert(err, gc.IsNil)
692@@ -161,7 +162,7 @@
693 }
694
695 func (s *ListKeysSuite) TestTooManyArgs(c *gc.C) {
696- _, err := coretesting.RunCommand(c, &ListKeysCommand{}, []string{"foo"})
697+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}), []string{"foo"})
698 c.Assert(err, gc.ErrorMatches, `unrecognized args: \["foo"\]`)
699 }
700
701@@ -176,7 +177,7 @@
702 s.setAuthorizedKeys(c, key1)
703
704 key2 := sshtesting.ValidKeyTwo.Key + " another@host"
705- context, err := coretesting.RunCommand(c, &AddKeysCommand{}, []string{key2, "invalid-key"})
706+ context, err := coretesting.RunCommand(c, envcmd.Wrap(&AddKeysCommand{}), []string{key2, "invalid-key"})
707 c.Assert(err, gc.IsNil)
708 c.Assert(coretesting.Stderr(context), gc.Matches, `cannot add key "invalid-key".*\n`)
709 s.assertEnvironKeys(c, key1, key2)
710@@ -189,7 +190,7 @@
711 c.Assert(err, gc.IsNil)
712
713 key2 := sshtesting.ValidKeyTwo.Key + " another@host"
714- context, err := coretesting.RunCommand(c, &AddKeysCommand{}, []string{"--user", "fred", key2})
715+ context, err := coretesting.RunCommand(c, envcmd.Wrap(&AddKeysCommand{}), []string{"--user", "fred", key2})
716 c.Assert(err, gc.IsNil)
717 c.Assert(coretesting.Stderr(context), gc.Equals, "")
718 s.assertEnvironKeys(c, key1, key2)
719@@ -207,7 +208,7 @@
720 s.setAuthorizedKeys(c, key1, key2)
721
722 context, err := coretesting.RunCommand(
723- c, &DeleteKeysCommand{}, []string{sshtesting.ValidKeyTwo.Fingerprint, "invalid-key"})
724+ c, envcmd.Wrap(&DeleteKeysCommand{}), []string{sshtesting.ValidKeyTwo.Fingerprint, "invalid-key"})
725 c.Assert(err, gc.IsNil)
726 c.Assert(coretesting.Stderr(context), gc.Matches, `cannot delete key id "invalid-key".*\n`)
727 s.assertEnvironKeys(c, key1)
728@@ -221,7 +222,7 @@
729 c.Assert(err, gc.IsNil)
730
731 context, err := coretesting.RunCommand(
732- c, &DeleteKeysCommand{}, []string{"--user", "fred", sshtesting.ValidKeyTwo.Fingerprint})
733+ c, envcmd.Wrap(&DeleteKeysCommand{}), []string{"--user", "fred", sshtesting.ValidKeyTwo.Fingerprint})
734 c.Assert(err, gc.IsNil)
735 c.Assert(coretesting.Stderr(context), gc.Equals, "")
736 s.assertEnvironKeys(c, key1)
737@@ -242,7 +243,7 @@
738 key1 := sshtesting.ValidKeyOne.Key + " user@host"
739 s.setAuthorizedKeys(c, key1)
740
741- context, err := coretesting.RunCommand(c, &ImportKeysCommand{}, []string{"lp:validuser", "invalid-key"})
742+ context, err := coretesting.RunCommand(c, envcmd.Wrap(&ImportKeysCommand{}), []string{"lp:validuser", "invalid-key"})
743 c.Assert(err, gc.IsNil)
744 c.Assert(coretesting.Stderr(context), gc.Matches, `cannot import key id "invalid-key".*\n`)
745 s.assertEnvironKeys(c, key1, sshtesting.ValidKeyThree.Key)
746@@ -254,7 +255,7 @@
747 _, err := s.State.AddUser("fred", "password")
748 c.Assert(err, gc.IsNil)
749
750- context, err := coretesting.RunCommand(c, &ImportKeysCommand{}, []string{"--user", "fred", "lp:validuser"})
751+ context, err := coretesting.RunCommand(c, envcmd.Wrap(&ImportKeysCommand{}), []string{"--user", "fred", "lp:validuser"})
752 c.Assert(err, gc.IsNil)
753 c.Assert(coretesting.Stderr(context), gc.Equals, "")
754 s.assertEnvironKeys(c, key1, sshtesting.ValidKeyThree.Key)
755
756=== modified file 'cmd/juju/bootstrap.go'
757--- cmd/juju/bootstrap.go 2014-05-09 13:24:50 +0000
758+++ cmd/juju/bootstrap.go 2014-05-12 11:08:32 +0000
759@@ -78,7 +78,6 @@
760 }
761
762 func (c *BootstrapCommand) SetFlags(f *gnuflag.FlagSet) {
763- c.EnvCommandBase.SetFlags(f)
764 f.Var(constraints.ConstraintsValue{Target: &c.Constraints}, "constraints", "set environment constraints")
765 f.BoolVar(&c.UploadTools, "upload-tools", false, "upload local version of tools before bootstrapping")
766 f.Var(newSeriesValue(nil, &c.Series), "upload-series", "upload tools for supplied comma-separated series list")
767@@ -88,9 +87,6 @@
768 }
769
770 func (c *BootstrapCommand) Init(args []string) (err error) {
771- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
772- return err
773- }
774 if len(c.Series) > 0 && !c.UploadTools {
775 return fmt.Errorf("--upload-series requires --upload-tools")
776 }
777
778=== modified file 'cmd/juju/bootstrap_test.go'
779--- cmd/juju/bootstrap_test.go 2014-05-12 00:24:54 +0000
780+++ cmd/juju/bootstrap_test.go 2014-05-12 11:08:32 +0000
781@@ -12,6 +12,7 @@
782 gc "launchpad.net/gocheck"
783
784 "launchpad.net/juju-core/cmd"
785+ "launchpad.net/juju-core/cmd/envcmd"
786 "launchpad.net/juju-core/constraints"
787 "launchpad.net/juju-core/environs"
788 "launchpad.net/juju-core/environs/config"
789@@ -142,7 +143,7 @@
790 restore := envtools.TestingPatchBootstrapFindTools(mockFindTools)
791 defer restore()
792
793- _, errc := runCommand(nullContext(c), new(BootstrapCommand), test.args...)
794+ _, errc := runCommand(nullContext(c), envcmd.Wrap(new(BootstrapCommand)), test.args...)
795 err := <-errc
796 c.Check(findToolsRetryValues, gc.DeepEquals, test.expectedAllowRetry)
797 stripped := strings.Replace(err.Error(), "\n", "", -1)
798@@ -225,7 +226,7 @@
799 }
800
801 // Run command and check for uploads.
802- opc, errc := runCommand(nullContext(c), new(BootstrapCommand), test.args...)
803+ opc, errc := runCommand(nullContext(c), envcmd.Wrap(new(BootstrapCommand)), test.args...)
804 // Check for remaining operations/errors.
805 if test.err != "" {
806 err := <-errc
807@@ -402,10 +403,10 @@
808 defaultSeriesVersion.Minor = 11
809 s.PatchValue(&version.Current, defaultSeriesVersion)
810
811- _, err := coretesting.RunCommand(c, &BootstrapCommand{}, nil)
812+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}), nil)
813 c.Assert(err, gc.IsNil)
814
815- _, err = coretesting.RunCommand(c, &BootstrapCommand{}, nil)
816+ _, err = coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}), nil)
817 c.Assert(err, gc.ErrorMatches, "environment is already bootstrapped")
818 }
819
820@@ -428,7 +429,7 @@
821 _, fake := makeEmptyFakeHome(c)
822 defer fake.Restore()
823
824- ctx, err := coretesting.RunCommand(c, &BootstrapCommand{},
825+ ctx, err := coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}),
826 []string{"--upload-tools", argVariant, "foo,bar"})
827
828 c.Assert(err, gc.IsNil)
829@@ -457,7 +458,7 @@
830 loggo.RegisterWriter(logger, testWriter, loggo.WARNING)
831 defer loggo.RemoveWriter(logger)
832
833- _, errc := runCommand(ctx, new(BootstrapCommand), "-e", "peckham")
834+ _, errc := runCommand(ctx, envcmd.Wrap(new(BootstrapCommand)), "-e", "peckham")
835 c.Assert(<-errc, gc.IsNil)
836 c.Assert(testWriter.Log, jc.LogMatches, []string{"ignoring environments.yaml: using bootstrap config in .*"})
837 }
838@@ -469,7 +470,7 @@
839
840 // Bootstrap the environment with an invalid source.
841 // The command returns with an error.
842- _, err := coretesting.RunCommand(c, &BootstrapCommand{}, []string{"--metadata-source", c.MkDir()})
843+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}), []string{"--metadata-source", c.MkDir()})
844 c.Check(err, gc.ErrorMatches, "cannot upload bootstrap tools: Juju "+
845 "cannot bootstrap because no tools are available for your "+
846 "environment(.|\n)*")
847@@ -524,7 +525,7 @@
848 devVersion.Minor = 11
849 s.PatchValue(&version.Current, devVersion)
850
851- _, err := coretesting.RunCommand(c, &BootstrapCommand{}, []string{"--metadata-source", sourceDir})
852+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}), []string{"--metadata-source", sourceDir})
853 c.Assert(err, gc.IsNil)
854 c.Assert(imagemetadata.DefaultBaseURL, gc.Equals, imagemetadata.UbuntuCloudImagesURL)
855
856@@ -541,7 +542,7 @@
857 // Bootstrap the environment with the valid source.
858 // The bootstrapping has to show no error, because the tools
859 // are automatically synchronized.
860- _, err := coretesting.RunCommand(c, &BootstrapCommand{}, []string{"--metadata-source", sourceDir})
861+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}), []string{"--metadata-source", sourceDir})
862 c.Assert(err, gc.IsNil)
863
864 // Now check the available tools which are the 1.2.0 envtools.
865@@ -575,7 +576,7 @@
866
867 env := s.setupAutoUploadTest(c, "1.7.3", otherSeries)
868 // Run command and check for that upload has been run for tools matching the current juju version.
869- opc, errc := runCommand(nullContext(c), new(BootstrapCommand))
870+ opc, errc := runCommand(nullContext(c), envcmd.Wrap(new(BootstrapCommand)))
871 c.Assert(<-errc, gc.IsNil)
872 c.Assert((<-opc).(dummy.OpPutFile).Env, gc.Equals, "peckham")
873 list, err := envtools.FindTools(env, version.Current.Major, version.Current.Minor, coretools.Filter{}, false)
874@@ -603,7 +604,7 @@
875
876 func (s *BootstrapSuite) TestAutoUploadOnlyForDev(c *gc.C) {
877 s.setupAutoUploadTest(c, "1.8.3", "precise")
878- _, errc := runCommand(nullContext(c), new(BootstrapCommand))
879+ _, errc := runCommand(nullContext(c), envcmd.Wrap(new(BootstrapCommand)))
880 err := <-errc
881 stripped := strings.Replace(err.Error(), "\n", "", -1)
882 c.Assert(stripped, gc.Matches, noToolsAvailableMessage)
883@@ -612,7 +613,7 @@
884 func (s *BootstrapSuite) TestMissingToolsError(c *gc.C) {
885 s.setupAutoUploadTest(c, "1.8.3", "precise")
886
887- _, err := coretesting.RunCommand(c, &BootstrapCommand{}, nil)
888+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}), nil)
889 c.Assert(err, gc.ErrorMatches, "cannot upload bootstrap tools: Juju "+
890 "cannot bootstrap because no tools are available for your "+
891 "environment(.|\n)*")
892@@ -626,7 +627,7 @@
893 s.setupAutoUploadTest(c, "1.7.3", "precise")
894 s.PatchValue(&sync.Upload, uploadToolsAlwaysFails)
895
896- ctx, err := coretesting.RunCommand(c, &BootstrapCommand{}, nil)
897+ ctx, err := coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}), nil)
898
899 c.Check(coretesting.Stderr(ctx), gc.Matches,
900 "uploading tools for series \\[precise .* raring\\]\n")
901@@ -642,7 +643,7 @@
902 // upload is only enabled for dev versions.
903 devVersion.Minor = 11
904 s.PatchValue(&version.Current, devVersion)
905- opc, errc := runCommand(nullContext(c), new(BootstrapCommand), "-e", "brokenenv")
906+ opc, errc := runCommand(nullContext(c), envcmd.Wrap(new(BootstrapCommand)), "-e", "brokenenv")
907 err := <-errc
908 c.Assert(err, gc.ErrorMatches, "dummy.Bootstrap is broken")
909 var opDestroy *dummy.OpDestroy
910
911=== modified file 'cmd/juju/cmd_test.go'
912--- cmd/juju/cmd_test.go 2014-05-11 22:52:40 +0000
913+++ cmd/juju/cmd_test.go 2014-05-12 11:08:32 +0000
914@@ -13,6 +13,7 @@
915 gc "launchpad.net/gocheck"
916
917 "launchpad.net/juju-core/cmd"
918+ "launchpad.net/juju-core/cmd/envcmd"
919 "launchpad.net/juju-core/juju/osenv"
920 "launchpad.net/juju-core/juju/testing"
921 "launchpad.net/juju-core/provider/dummy"
922@@ -68,12 +69,12 @@
923 }
924 }
925
926-// assertConnName asserts that the Command is using
927+// assertEnvName asserts that the Command is using
928 // the given environment name.
929 // Since every command has a different type,
930 // we use reflection to look at the value of the
931 // Conn field in the value.
932-func assertConnName(c *gc.C, com cmd.Command, name string) {
933+func assertEnvName(c *gc.C, com cmd.Command, name string) {
934 v := reflect.ValueOf(com).Elem().FieldByName("EnvName")
935 c.Assert(v, jc.Satisfies, reflect.Value.IsValid)
936 c.Assert(v.Interface(), gc.Equals, name)
937@@ -81,12 +82,12 @@
938
939 // All members of EnvironmentInitTests are tested for the -environment and -e
940 // flags, and that extra arguments will cause parsing to fail.
941-var EnvironmentInitTests = []func() (cmd.Command, []string){
942- func() (cmd.Command, []string) { return new(BootstrapCommand), nil },
943- func() (cmd.Command, []string) {
944+var EnvironmentInitTests = []func() (envcmd.EnvironCommand, []string){
945+ func() (envcmd.EnvironCommand, []string) { return new(BootstrapCommand), nil },
946+ func() (envcmd.EnvironCommand, []string) {
947 return new(DeployCommand), []string{"charm-name", "service-name"}
948 },
949- func() (cmd.Command, []string) { return new(StatusCommand), nil },
950+ func() (envcmd.EnvironCommand, []string) { return new(StatusCommand), nil },
951 }
952
953 // TestEnvironmentInit tests that all commands which accept
954@@ -96,24 +97,24 @@
955 for i, cmdFunc := range EnvironmentInitTests {
956 c.Logf("test %d", i)
957 com, args := cmdFunc()
958- testInit(c, com, args, "")
959- assertConnName(c, com, "peckham")
960-
961- com, args = cmdFunc()
962- testInit(c, com, append(args, "-e", "walthamstow"), "")
963- assertConnName(c, com, "walthamstow")
964-
965- com, args = cmdFunc()
966- testInit(c, com, append(args, "--environment", "walthamstow"), "")
967- assertConnName(c, com, "walthamstow")
968+ testInit(c, envcmd.Wrap(com), args, "")
969+ assertEnvName(c, com, "peckham")
970+
971+ com, args = cmdFunc()
972+ testInit(c, envcmd.Wrap(com), append(args, "-e", "walthamstow"), "")
973+ assertEnvName(c, com, "walthamstow")
974+
975+ com, args = cmdFunc()
976+ testInit(c, envcmd.Wrap(com), append(args, "--environment", "walthamstow"), "")
977+ assertEnvName(c, com, "walthamstow")
978
979 // JUJU_ENV is the final place the environment can be overriden
980 com, args = cmdFunc()
981 oldenv := os.Getenv(osenv.JujuEnvEnvKey)
982 os.Setenv(osenv.JujuEnvEnvKey, "walthamstow")
983- testInit(c, com, args, "")
984+ testInit(c, envcmd.Wrap(com), args, "")
985 os.Setenv(osenv.JujuEnvEnvKey, oldenv)
986- assertConnName(c, com, "walthamstow")
987+ assertEnvName(c, com, "walthamstow")
988 }
989 }
990
991@@ -192,7 +193,7 @@
992
993 func initDeployCommand(args ...string) (*DeployCommand, error) {
994 com := &DeployCommand{}
995- return com, coretesting.InitCommand(com, args)
996+ return com, coretesting.InitCommand(envcmd.Wrap(com), args)
997 }
998
999 func (*CmdSuite) TestDeployCommandInit(c *gc.C) {
1000
1001=== modified file 'cmd/juju/constraints.go'
1002--- cmd/juju/constraints.go 2014-05-09 13:24:50 +0000
1003+++ cmd/juju/constraints.go 2014-05-12 11:08:32 +0000
1004@@ -70,7 +70,6 @@
1005 }
1006
1007 func (c *GetConstraintsCommand) SetFlags(f *gnuflag.FlagSet) {
1008- c.EnvCommandBase.SetFlags(f)
1009 c.out.AddFlags(f, "constraints", map[string]cmd.Formatter{
1010 "constraints": formatConstraints,
1011 "yaml": cmd.FormatYaml,
1012@@ -79,9 +78,6 @@
1013 }
1014
1015 func (c *GetConstraintsCommand) Init(args []string) error {
1016- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
1017- return err
1018- }
1019 if len(args) > 0 {
1020 if !names.IsService(args[0]) {
1021 return fmt.Errorf("invalid service name %q", args[0])
1022@@ -127,15 +123,11 @@
1023 }
1024
1025 func (c *SetConstraintsCommand) SetFlags(f *gnuflag.FlagSet) {
1026- c.EnvCommandBase.SetFlags(f)
1027 f.StringVar(&c.ServiceName, "s", "", "set service constraints")
1028 f.StringVar(&c.ServiceName, "service", "", "")
1029 }
1030
1031 func (c *SetConstraintsCommand) Init(args []string) (err error) {
1032- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
1033- return err
1034- }
1035 if c.ServiceName != "" && !names.IsService(c.ServiceName) {
1036 return fmt.Errorf("invalid service name %q", c.ServiceName)
1037 }
1038
1039=== modified file 'cmd/juju/constraints_test.go'
1040--- cmd/juju/constraints_test.go 2014-03-13 07:54:56 +0000
1041+++ cmd/juju/constraints_test.go 2014-05-12 11:08:32 +0000
1042@@ -10,6 +10,7 @@
1043 gc "launchpad.net/gocheck"
1044
1045 "launchpad.net/juju-core/cmd"
1046+ "launchpad.net/juju-core/cmd/envcmd"
1047 "launchpad.net/juju-core/constraints"
1048 "launchpad.net/juju-core/juju/testing"
1049 coretesting "launchpad.net/juju-core/testing"
1050@@ -35,7 +36,7 @@
1051 }
1052
1053 func assertSet(c *gc.C, args ...string) {
1054- rcode, rstdout, rstderr := runCmdLine(c, &SetConstraintsCommand{}, args...)
1055+ rcode, rstdout, rstderr := runCmdLine(c, envcmd.Wrap(&SetConstraintsCommand{}), args...)
1056 c.Assert(rcode, gc.Equals, 0)
1057 c.Assert(rstdout, gc.Equals, "")
1058 c.Assert(rstderr, gc.Equals, "")
1059@@ -78,7 +79,7 @@
1060 }
1061
1062 func assertSetError(c *gc.C, code int, stderr string, args ...string) {
1063- rcode, rstdout, rstderr := runCmdLine(c, &SetConstraintsCommand{}, args...)
1064+ rcode, rstdout, rstderr := runCmdLine(c, envcmd.Wrap(&SetConstraintsCommand{}), args...)
1065 c.Assert(rcode, gc.Equals, code)
1066 c.Assert(rstdout, gc.Equals, "")
1067 c.Assert(rstderr, gc.Matches, "error: "+stderr+"\n")
1068
1069=== modified file 'cmd/juju/debuglog.go'
1070--- cmd/juju/debuglog.go 2014-05-11 22:36:42 +0000
1071+++ cmd/juju/debuglog.go 2014-05-12 11:08:32 +0000
1072@@ -44,8 +44,6 @@
1073 }
1074
1075 func (c *DebugLogCommand) SetFlags(f *gnuflag.FlagSet) {
1076- c.EnvCommandBase.SetFlags(f)
1077-
1078 f.Var(cmd.NewAppendStringsValue(&c.params.IncludeEntity), "i", "only show log messages for these entities")
1079 f.Var(cmd.NewAppendStringsValue(&c.params.IncludeEntity), "include", "only show log messages for these entities")
1080 f.Var(cmd.NewAppendStringsValue(&c.params.ExcludeEntity), "x", "do not show log messages for these entities")
1081@@ -63,9 +61,6 @@
1082 }
1083
1084 func (c *DebugLogCommand) Init(args []string) error {
1085- if err := c.EnsureEnvName(); err != nil {
1086- return err
1087- }
1088 if c.level != "" {
1089 level, ok := loggo.ParseLevel(c.level)
1090 if !ok || level < loggo.TRACE || level > loggo.ERROR {
1091
1092=== modified file 'cmd/juju/debuglog_test.go'
1093--- cmd/juju/debuglog_test.go 2014-05-09 13:24:50 +0000
1094+++ cmd/juju/debuglog_test.go 2014-05-12 11:08:32 +0000
1095@@ -14,6 +14,7 @@
1096 gc "launchpad.net/gocheck"
1097
1098 "launchpad.net/juju-core/cmd"
1099+ "launchpad.net/juju-core/cmd/envcmd"
1100 "launchpad.net/juju-core/errors"
1101 "launchpad.net/juju-core/state/api"
1102 "launchpad.net/juju-core/testing"
1103@@ -91,7 +92,7 @@
1104 } {
1105 c.Logf("test %v", i)
1106 command := &DebugLogCommand{}
1107- err := testing.InitCommand(command, test.args)
1108+ err := testing.InitCommand(envcmd.Wrap(command), test.args)
1109 if test.errMatch == "" {
1110 c.Check(err, gc.IsNil)
1111 c.Check(command.params, jc.DeepEquals, test.expected)
1112@@ -106,7 +107,7 @@
1113 s.PatchValue(&getDebugLogAPI, func(envName string) (DebugLogAPI, error) {
1114 return fake, nil
1115 })
1116- _, err := testing.RunCommand(c, &DebugLogCommand{}, []string{
1117+ _, err := testing.RunCommand(c, envcmd.Wrap(&DebugLogCommand{}), []string{
1118 "-i", "machine-1*", "-x", "machine-1-lxc-1",
1119 "--include-module=juju.provisioner",
1120 "--lines=500",
1121@@ -126,7 +127,7 @@
1122 s.PatchValue(&getDebugLogAPI, func(envName string) (DebugLogAPI, error) {
1123 return &fakeDebugLogAPI{log: "this is the log output"}, nil
1124 })
1125- ctx, err := testing.RunCommand(c, &DebugLogCommand{}, nil)
1126+ ctx, err := testing.RunCommand(c, envcmd.Wrap(&DebugLogCommand{}), nil)
1127 c.Assert(err, gc.IsNil)
1128 c.Assert(testing.Stdout(ctx), gc.Equals, "this is the log output")
1129 }
1130@@ -139,7 +140,7 @@
1131 s.PatchValue(&getDebugLogAPI, func(envName string) (DebugLogAPI, error) {
1132 return &fakeDebugLogAPI{err: errors.NotSupportedf("testing")}, nil
1133 })
1134- ctx, err := testing.RunCommand(c, &DebugLogCommand{}, []string{"-n", "100"})
1135+ ctx, err := testing.RunCommand(c, envcmd.Wrap(&DebugLogCommand{}), []string{"-n", "100"})
1136 c.Assert(err, gc.IsNil)
1137 c.Check(testing.Stderr(ctx), gc.Equals, "Server does not support new stream log, falling back to tail\n")
1138 c.Check(testing.Stdout(ctx), gc.Equals, "[tail -n -100 -f /var/log/juju/all-machines.log]")
1139
1140=== modified file 'cmd/juju/deploy.go'
1141--- cmd/juju/deploy.go 2014-05-09 13:24:50 +0000
1142+++ cmd/juju/deploy.go 2014-05-12 11:08:32 +0000
1143@@ -100,7 +100,6 @@
1144 }
1145
1146 func (c *DeployCommand) SetFlags(f *gnuflag.FlagSet) {
1147- c.EnvCommandBase.SetFlags(f)
1148 c.UnitCommandBase.SetFlags(f)
1149 f.IntVar(&c.NumUnits, "n", 1, "number of service units to deploy for principal charms")
1150 f.BoolVar(&c.BumpRevision, "u", false, "increment local charm directory revision (DEPRECATED)")
1151@@ -113,9 +112,6 @@
1152 }
1153
1154 func (c *DeployCommand) Init(args []string) error {
1155- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
1156- return err
1157- }
1158 switch len(args) {
1159 case 2:
1160 if !names.IsService(args[1]) {
1161
1162=== modified file 'cmd/juju/deploy_test.go'
1163--- cmd/juju/deploy_test.go 2014-05-02 22:26:15 +0000
1164+++ cmd/juju/deploy_test.go 2014-05-12 11:08:32 +0000
1165@@ -10,6 +10,7 @@
1166 gc "launchpad.net/gocheck"
1167
1168 "launchpad.net/juju-core/charm"
1169+ "launchpad.net/juju-core/cmd/envcmd"
1170 "launchpad.net/juju-core/constraints"
1171 "launchpad.net/juju-core/errors"
1172 "launchpad.net/juju-core/instance"
1173@@ -26,7 +27,7 @@
1174 var _ = gc.Suite(&DeploySuite{})
1175
1176 func runDeploy(c *gc.C, args ...string) error {
1177- _, err := coretesting.RunCommand(c, &DeployCommand{}, args)
1178+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&DeployCommand{}), args)
1179 return err
1180 }
1181
1182@@ -64,7 +65,7 @@
1183 func (s *DeploySuite) TestInitErrors(c *gc.C) {
1184 for i, t := range initErrorTests {
1185 c.Logf("test %d", i)
1186- err := coretesting.InitCommand(&DeployCommand{}, t.args)
1187+ err := coretesting.InitCommand(envcmd.Wrap(&DeployCommand{}), t.args)
1188 c.Assert(err, gc.ErrorMatches, t.err)
1189 }
1190 }
1191@@ -84,7 +85,7 @@
1192
1193 func (s *DeploySuite) TestUpgradeReportsDeprecated(c *gc.C) {
1194 coretesting.Charms.ClonedDirPath(s.SeriesPath, "dummy")
1195- ctx, err := coretesting.RunCommand(c, &DeployCommand{}, []string{"local:dummy", "-u"})
1196+ ctx, err := coretesting.RunCommand(c, envcmd.Wrap(&DeployCommand{}), []string{"local:dummy", "-u"})
1197 c.Assert(err, gc.IsNil)
1198
1199 c.Assert(coretesting.Stdout(ctx), gc.Equals, "")
1200
1201=== modified file 'cmd/juju/endpoint.go'
1202--- cmd/juju/endpoint.go 2014-05-09 13:24:50 +0000
1203+++ cmd/juju/endpoint.go 2014-05-12 11:08:32 +0000
1204@@ -37,15 +37,7 @@
1205 }
1206 }
1207
1208-func (c *EndpointCommand) Init(args []string) error {
1209- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
1210- return err
1211- }
1212- return cmd.CheckEmpty(args)
1213-}
1214-
1215 func (c *EndpointCommand) SetFlags(f *gnuflag.FlagSet) {
1216- c.EnvCommandBase.SetFlags(f)
1217 c.out.AddFlags(f, "smart", cmd.DefaultFormatters)
1218 f.BoolVar(&c.refresh, "refresh", false, "connect to the API to ensure up-to-date endpoint locations")
1219 }
1220
1221=== modified file 'cmd/juju/endpoint_test.go'
1222--- cmd/juju/endpoint_test.go 2013-08-15 15:00:54 +0000
1223+++ cmd/juju/endpoint_test.go 2014-05-12 11:08:32 +0000
1224@@ -10,6 +10,7 @@
1225 gc "launchpad.net/gocheck"
1226
1227 "launchpad.net/juju-core/cmd"
1228+ "launchpad.net/juju-core/cmd/envcmd"
1229 "launchpad.net/juju-core/juju/testing"
1230 coretesting "launchpad.net/juju-core/testing"
1231 )
1232@@ -22,7 +23,7 @@
1233
1234 func (s *EndpointSuite) TestEndpoint(c *gc.C) {
1235 ctx := coretesting.Context(c)
1236- code := cmd.Main(&EndpointCommand{}, ctx, []string{})
1237+ code := cmd.Main(envcmd.Wrap(&EndpointCommand{}), ctx, []string{})
1238 c.Check(code, gc.Equals, 0)
1239 c.Assert(ctx.Stderr.(*bytes.Buffer).String(), gc.Equals, "")
1240 output := string(ctx.Stdout.(*bytes.Buffer).Bytes())
1241
1242=== modified file 'cmd/juju/ensureavailability.go'
1243--- cmd/juju/ensureavailability.go 2014-05-09 13:24:50 +0000
1244+++ cmd/juju/ensureavailability.go 2014-05-12 11:08:32 +0000
1245@@ -56,16 +56,12 @@
1246 }
1247
1248 func (c *EnsureAvailabilityCommand) SetFlags(f *gnuflag.FlagSet) {
1249- c.EnvCommandBase.SetFlags(f)
1250 f.IntVar(&c.NumStateServers, "n", 0, "number of state servers to make available")
1251 f.StringVar(&c.Series, "series", "", "the charm series")
1252 f.Var(constraints.ConstraintsValue{&c.Constraints}, "constraints", "additional machine constraints")
1253 }
1254
1255 func (c *EnsureAvailabilityCommand) Init(args []string) error {
1256- if err := c.EnsureEnvName(); err != nil {
1257- return err
1258- }
1259 if c.NumStateServers < 0 || (c.NumStateServers%2 != 1 && c.NumStateServers != 0) {
1260 return fmt.Errorf("must specify a number of state servers odd and non-negative")
1261 }
1262
1263=== modified file 'cmd/juju/ensureavailability_test.go'
1264--- cmd/juju/ensureavailability_test.go 2014-04-23 11:57:06 +0000
1265+++ cmd/juju/ensureavailability_test.go 2014-05-12 11:08:32 +0000
1266@@ -9,6 +9,7 @@
1267 jc "github.com/juju/testing/checkers"
1268 gc "launchpad.net/gocheck"
1269
1270+ "launchpad.net/juju-core/cmd/envcmd"
1271 "launchpad.net/juju-core/constraints"
1272 jujutesting "launchpad.net/juju-core/juju/testing"
1273 "launchpad.net/juju-core/state"
1274@@ -49,7 +50,7 @@
1275 }
1276
1277 func runEnsureAvailability(c *gc.C, args ...string) error {
1278- _, err := coretesting.RunCommand(c, &EnsureAvailabilityCommand{}, args)
1279+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&EnsureAvailabilityCommand{}), args)
1280 return err
1281 }
1282
1283
1284=== modified file 'cmd/juju/environment.go'
1285--- cmd/juju/environment.go 2014-05-09 13:24:50 +0000
1286+++ cmd/juju/environment.go 2014-05-12 11:08:32 +0000
1287@@ -45,14 +45,10 @@
1288 }
1289
1290 func (c *GetEnvironmentCommand) SetFlags(f *gnuflag.FlagSet) {
1291- c.EnvCommandBase.SetFlags(f)
1292 c.out.AddFlags(f, "smart", cmd.DefaultFormatters)
1293 }
1294
1295 func (c *GetEnvironmentCommand) Init(args []string) (err error) {
1296- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
1297- return err
1298- }
1299 c.key, err = cmd.ZeroOrOneArgs(args)
1300 return
1301 }
1302@@ -102,12 +98,7 @@
1303 }
1304 }
1305
1306-// SetFlags handled entirely by envcmd.EnvCommandBase
1307-
1308 func (c *SetEnvironmentCommand) Init(args []string) (err error) {
1309- if err := c.EnsureEnvName(); err != nil {
1310- return err
1311- }
1312 if len(args) == 0 {
1313 return fmt.Errorf("No key, value pairs specified")
1314 }
1315@@ -166,9 +157,6 @@
1316 }
1317
1318 func (c *UnsetEnvironmentCommand) Init(args []string) (err error) {
1319- if err := c.EnsureEnvName(); err != nil {
1320- return err
1321- }
1322 if len(args) == 0 {
1323 return fmt.Errorf("No keys specified")
1324 }
1325
1326=== modified file 'cmd/juju/environment_test.go'
1327--- cmd/juju/environment_test.go 2014-04-09 16:36:12 +0000
1328+++ cmd/juju/environment_test.go 2014-05-12 11:08:32 +0000
1329@@ -10,6 +10,7 @@
1330 jc "github.com/juju/testing/checkers"
1331 gc "launchpad.net/gocheck"
1332
1333+ "launchpad.net/juju-core/cmd/envcmd"
1334 "launchpad.net/juju-core/environs/config"
1335 jujutesting "launchpad.net/juju-core/juju/testing"
1336 "launchpad.net/juju-core/provider/dummy"
1337@@ -45,7 +46,7 @@
1338
1339 func (s *GetEnvironmentSuite) TestSingleValue(c *gc.C) {
1340 for _, t := range singleValueTests {
1341- context, err := testing.RunCommand(c, &GetEnvironmentCommand{}, []string{t.key})
1342+ context, err := testing.RunCommand(c, envcmd.Wrap(&GetEnvironmentCommand{}), []string{t.key})
1343 if t.err != "" {
1344 c.Assert(err, gc.ErrorMatches, t.err)
1345 } else {
1346@@ -57,12 +58,12 @@
1347 }
1348
1349 func (s *GetEnvironmentSuite) TestTooManyArgs(c *gc.C) {
1350- _, err := testing.RunCommand(c, &GetEnvironmentCommand{}, []string{"name", "type"})
1351+ _, err := testing.RunCommand(c, envcmd.Wrap(&GetEnvironmentCommand{}), []string{"name", "type"})
1352 c.Assert(err, gc.ErrorMatches, `unrecognized args: \["type"\]`)
1353 }
1354
1355 func (s *GetEnvironmentSuite) TestAllValues(c *gc.C) {
1356- context, _ := testing.RunCommand(c, &GetEnvironmentCommand{}, []string{})
1357+ context, _ := testing.RunCommand(c, envcmd.Wrap(&GetEnvironmentCommand{}), []string{})
1358 output := strings.TrimSpace(testing.Stdout(context))
1359
1360 // Make sure that all the environment keys are there. The admin
1361@@ -116,7 +117,7 @@
1362 func (s *SetEnvironmentSuite) TestInit(c *gc.C) {
1363 for _, t := range setEnvInitTests {
1364 command := &SetEnvironmentCommand{}
1365- testing.TestInit(c, command, t.args, t.err)
1366+ testing.TestInit(c, envcmd.Wrap(command), t.args, t.err)
1367 if t.expected != nil {
1368 c.Assert(command.values, gc.DeepEquals, t.expected)
1369 }
1370@@ -131,7 +132,7 @@
1371 c.Assert(ok, gc.Equals, true)
1372 c.Assert(series, gc.Equals, "precise") // default-series set in RepoSuite.SetUpTest
1373
1374- _, err = testing.RunCommand(c, &SetEnvironmentCommand{}, []string{"default-series=raring"})
1375+ _, err = testing.RunCommand(c, envcmd.Wrap(&SetEnvironmentCommand{}), []string{"default-series=raring"})
1376 c.Assert(err, gc.IsNil)
1377
1378 stateConfig, err = s.State.EnvironConfig()
1379@@ -143,7 +144,7 @@
1380 }
1381
1382 func (s *SetEnvironmentSuite) TestChangeBooleanAttribute(c *gc.C) {
1383- _, err := testing.RunCommand(c, &SetEnvironmentCommand{}, []string{"ssl-hostname-verification=false"})
1384+ _, err := testing.RunCommand(c, envcmd.Wrap(&SetEnvironmentCommand{}), []string{"ssl-hostname-verification=false"})
1385 c.Assert(err, gc.IsNil)
1386
1387 stateConfig, err := s.State.EnvironConfig()
1388@@ -152,7 +153,7 @@
1389 }
1390
1391 func (s *SetEnvironmentSuite) TestChangeMultipleValues(c *gc.C) {
1392- _, err := testing.RunCommand(c, &SetEnvironmentCommand{}, []string{"default-series=spartan", "broken=nope", "secret=sekrit"})
1393+ _, err := testing.RunCommand(c, envcmd.Wrap(&SetEnvironmentCommand{}), []string{"default-series=spartan", "broken=nope", "secret=sekrit"})
1394 c.Assert(err, gc.IsNil)
1395
1396 stateConfig, err := s.State.EnvironConfig()
1397@@ -164,10 +165,10 @@
1398 }
1399
1400 func (s *SetEnvironmentSuite) TestChangeAsCommandPair(c *gc.C) {
1401- _, err := testing.RunCommand(c, &SetEnvironmentCommand{}, []string{"default-series=raring"})
1402+ _, err := testing.RunCommand(c, envcmd.Wrap(&SetEnvironmentCommand{}), []string{"default-series=raring"})
1403 c.Assert(err, gc.IsNil)
1404
1405- context, err := testing.RunCommand(c, &GetEnvironmentCommand{}, []string{"default-series"})
1406+ context, err := testing.RunCommand(c, envcmd.Wrap(&GetEnvironmentCommand{}), []string{"default-series"})
1407 c.Assert(err, gc.IsNil)
1408 output := strings.TrimSpace(testing.Stdout(context))
1409
1410@@ -185,7 +186,7 @@
1411 func (s *SetEnvironmentSuite) TestImmutableConfigValues(c *gc.C) {
1412 for name, value := range immutableConfigTests {
1413 param := fmt.Sprintf("%s=%s", name, value)
1414- _, err := testing.RunCommand(c, &SetEnvironmentCommand{}, []string{param})
1415+ _, err := testing.RunCommand(c, envcmd.Wrap(&SetEnvironmentCommand{}), []string{param})
1416 errorPattern := fmt.Sprintf("cannot change %s from .* to [\"]?%v[\"]?", name, value)
1417 c.Assert(err, gc.ErrorMatches, errorPattern)
1418 }
1419@@ -239,7 +240,7 @@
1420 for _, t := range unsetEnvTests {
1421 c.Logf("testing unset-env %v", t.args)
1422 s.initConfig(c)
1423- _, err := testing.RunCommand(c, &UnsetEnvironmentCommand{}, t.args)
1424+ _, err := testing.RunCommand(c, envcmd.Wrap(&UnsetEnvironmentCommand{}), t.args)
1425 if t.err != "" {
1426 c.Assert(err, gc.ErrorMatches, t.err)
1427 } else {
1428
1429=== modified file 'cmd/juju/expose.go'
1430--- cmd/juju/expose.go 2014-05-09 13:24:50 +0000
1431+++ cmd/juju/expose.go 2014-05-12 11:08:32 +0000
1432@@ -33,9 +33,6 @@
1433 }
1434
1435 func (c *ExposeCommand) Init(args []string) error {
1436- if err := c.EnsureEnvName(); err != nil {
1437- return err
1438- }
1439 if len(args) == 0 {
1440 return errors.New("no service name specified")
1441 }
1442
1443=== modified file 'cmd/juju/expose_test.go'
1444--- cmd/juju/expose_test.go 2013-09-13 14:48:13 +0000
1445+++ cmd/juju/expose_test.go 2014-05-12 11:08:32 +0000
1446@@ -7,6 +7,7 @@
1447 gc "launchpad.net/gocheck"
1448
1449 "launchpad.net/juju-core/charm"
1450+ "launchpad.net/juju-core/cmd/envcmd"
1451 jujutesting "launchpad.net/juju-core/juju/testing"
1452 "launchpad.net/juju-core/testing"
1453 )
1454@@ -18,7 +19,7 @@
1455 var _ = gc.Suite(&ExposeSuite{})
1456
1457 func runExpose(c *gc.C, args ...string) error {
1458- _, err := testing.RunCommand(c, &ExposeCommand{}, args)
1459+ _, err := testing.RunCommand(c, envcmd.Wrap(&ExposeCommand{}), args)
1460 return err
1461 }
1462
1463
1464=== modified file 'cmd/juju/get.go'
1465--- cmd/juju/get.go 2014-05-09 13:24:50 +0000
1466+++ cmd/juju/get.go 2014-05-12 11:08:32 +0000
1467@@ -29,7 +29,6 @@
1468 }
1469
1470 func (c *GetCommand) SetFlags(f *gnuflag.FlagSet) {
1471- c.EnvCommandBase.SetFlags(f)
1472 // TODO(dfc) add json formatting ?
1473 c.out.AddFlags(f, "yaml", map[string]cmd.Formatter{
1474 "yaml": cmd.FormatYaml,
1475@@ -37,9 +36,6 @@
1476 }
1477
1478 func (c *GetCommand) Init(args []string) error {
1479- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
1480- return err
1481- }
1482 // TODO(dfc) add --schema-only
1483 if len(args) == 0 {
1484 return errors.New("no service name specified")
1485
1486=== modified file 'cmd/juju/get_test.go'
1487--- cmd/juju/get_test.go 2013-10-09 13:55:14 +0000
1488+++ cmd/juju/get_test.go 2014-05-12 11:08:32 +0000
1489@@ -11,6 +11,7 @@
1490
1491 "launchpad.net/juju-core/charm"
1492 "launchpad.net/juju-core/cmd"
1493+ "launchpad.net/juju-core/cmd/envcmd"
1494 "launchpad.net/juju-core/juju/testing"
1495 coretesting "launchpad.net/juju-core/testing"
1496 )
1497@@ -67,7 +68,7 @@
1498 c.Assert(err, gc.IsNil)
1499 for _, t := range getTests {
1500 ctx := coretesting.Context(c)
1501- code := cmd.Main(&GetCommand{}, ctx, []string{t.service})
1502+ code := cmd.Main(envcmd.Wrap(&GetCommand{}), ctx, []string{t.service})
1503 c.Check(code, gc.Equals, 0)
1504 c.Assert(ctx.Stderr.(*bytes.Buffer).String(), gc.Equals, "")
1505 // round trip via goyaml to avoid being sucked into a quagmire of
1506
1507=== modified file 'cmd/juju/main.go'
1508--- cmd/juju/main.go 2014-05-09 22:56:29 +0000
1509+++ cmd/juju/main.go 2014-05-12 11:08:32 +0000
1510@@ -10,6 +10,7 @@
1511 "github.com/juju/loggo"
1512
1513 "launchpad.net/juju-core/cmd"
1514+ "launchpad.net/juju-core/cmd/envcmd"
1515 "launchpad.net/juju-core/environs"
1516 "launchpad.net/juju-core/juju"
1517
1518@@ -72,104 +73,99 @@
1519
1520 jujucmd.AddHelpTopicCallback("plugins", "Show Juju plugins", PluginHelpTopic)
1521
1522+ registerCommands(jujucmd, ctx)
1523+ os.Exit(cmd.Main(jujucmd, ctx, args[1:]))
1524+}
1525+
1526+type commandRegistry interface {
1527+ Register(cmd.Command)
1528+}
1529+
1530+// registerCommands registers commands in the specified registry.
1531+// EnvironCommands must be wrapped with an envCmdWrapper.
1532+func registerCommands(r commandRegistry, ctx *cmd.Context) {
1533+ wrapEnvCommand := func(c envcmd.EnvironCommand) cmd.Command {
1534+ return envCmdWrapper{envcmd.Wrap(c), ctx}
1535+ }
1536+
1537 // Creation commands.
1538- jujucmd.Register(wrap(&BootstrapCommand{}))
1539- jujucmd.Register(wrap(&AddMachineCommand{}))
1540- jujucmd.Register(wrap(&DeployCommand{}))
1541- jujucmd.Register(wrap(&AddRelationCommand{}))
1542- jujucmd.Register(wrap(&AddUnitCommand{}))
1543+ r.Register(wrapEnvCommand(&BootstrapCommand{}))
1544+ r.Register(wrapEnvCommand(&AddMachineCommand{}))
1545+ r.Register(wrapEnvCommand(&DeployCommand{}))
1546+ r.Register(wrapEnvCommand(&AddRelationCommand{}))
1547+ r.Register(wrapEnvCommand(&AddUnitCommand{}))
1548
1549 // Destruction commands.
1550- jujucmd.Register(wrap(&RemoveMachineCommand{}))
1551- jujucmd.Register(wrap(&RemoveRelationCommand{}))
1552- jujucmd.Register(wrap(&RemoveServiceCommand{}))
1553- jujucmd.Register(wrap(&RemoveUnitCommand{}))
1554- jujucmd.Register(wrap(&DestroyEnvironmentCommand{}))
1555+ r.Register(wrapEnvCommand(&RemoveMachineCommand{}))
1556+ r.Register(wrapEnvCommand(&RemoveRelationCommand{}))
1557+ r.Register(wrapEnvCommand(&RemoveServiceCommand{}))
1558+ r.Register(wrapEnvCommand(&RemoveUnitCommand{}))
1559+ r.Register(&DestroyEnvironmentCommand{})
1560
1561 // Reporting commands.
1562- jujucmd.Register(wrap(&StatusCommand{}))
1563- jujucmd.Register(wrap(&SwitchCommand{}))
1564- jujucmd.Register(wrap(&EndpointCommand{}))
1565+ r.Register(wrapEnvCommand(&StatusCommand{}))
1566+ r.Register(&SwitchCommand{})
1567+ r.Register(wrapEnvCommand(&EndpointCommand{}))
1568
1569 // Error resolution and debugging commands.
1570- jujucmd.Register(wrap(&RunCommand{}))
1571- jujucmd.Register(wrap(&SCPCommand{}))
1572- jujucmd.Register(wrap(&SSHCommand{}))
1573- jujucmd.Register(wrap(&ResolvedCommand{}))
1574- jujucmd.Register(wrap(&DebugLogCommand{}))
1575- jujucmd.Register(wrap(&DebugHooksCommand{}))
1576- jujucmd.Register(wrap(&RetryProvisioningCommand{}))
1577+ r.Register(wrapEnvCommand(&RunCommand{}))
1578+ r.Register(wrapEnvCommand(&SCPCommand{}))
1579+ r.Register(wrapEnvCommand(&SSHCommand{}))
1580+ r.Register(wrapEnvCommand(&ResolvedCommand{}))
1581+ r.Register(wrapEnvCommand(&DebugLogCommand{}))
1582+ r.Register(wrapEnvCommand(&DebugHooksCommand{}))
1583+ r.Register(wrapEnvCommand(&RetryProvisioningCommand{}))
1584
1585 // Configuration commands.
1586- jujucmd.Register(wrap(&InitCommand{}))
1587- jujucmd.Register(wrap(&GetCommand{}))
1588- jujucmd.Register(wrap(&SetCommand{}))
1589- jujucmd.Register(wrap(&UnsetCommand{}))
1590- jujucmd.Register(wrap(&GetConstraintsCommand{}))
1591- jujucmd.Register(wrap(&SetConstraintsCommand{}))
1592- jujucmd.Register(wrap(&GetEnvironmentCommand{}))
1593- jujucmd.Register(wrap(&SetEnvironmentCommand{}))
1594- jujucmd.Register(wrap(&UnsetEnvironmentCommand{}))
1595- jujucmd.Register(wrap(&ExposeCommand{}))
1596- jujucmd.Register(wrap(&SyncToolsCommand{}))
1597- jujucmd.Register(wrap(&UnexposeCommand{}))
1598- jujucmd.Register(wrap(&UpgradeJujuCommand{}))
1599- jujucmd.Register(wrap(&UpgradeCharmCommand{}))
1600+ r.Register(&InitCommand{})
1601+ r.Register(wrapEnvCommand(&GetCommand{}))
1602+ r.Register(wrapEnvCommand(&SetCommand{}))
1603+ r.Register(wrapEnvCommand(&UnsetCommand{}))
1604+ r.Register(wrapEnvCommand(&GetConstraintsCommand{}))
1605+ r.Register(wrapEnvCommand(&SetConstraintsCommand{}))
1606+ r.Register(wrapEnvCommand(&GetEnvironmentCommand{}))
1607+ r.Register(wrapEnvCommand(&SetEnvironmentCommand{}))
1608+ r.Register(wrapEnvCommand(&UnsetEnvironmentCommand{}))
1609+ r.Register(wrapEnvCommand(&ExposeCommand{}))
1610+ r.Register(wrapEnvCommand(&SyncToolsCommand{}))
1611+ r.Register(wrapEnvCommand(&UnexposeCommand{}))
1612+ r.Register(wrapEnvCommand(&UpgradeJujuCommand{}))
1613+ r.Register(wrapEnvCommand(&UpgradeCharmCommand{}))
1614
1615 // Charm publishing commands.
1616- jujucmd.Register(wrap(&PublishCommand{}))
1617+ r.Register(wrapEnvCommand(&PublishCommand{}))
1618
1619 // Charm tool commands.
1620- jujucmd.Register(wrap(&HelpToolCommand{}))
1621+ r.Register(&HelpToolCommand{})
1622
1623 // Manage authorized ssh keys.
1624- jujucmd.Register(wrap(NewAuthorizedKeysCommand()))
1625+ r.Register(NewAuthorizedKeysCommand())
1626
1627 // Manage state server availability.
1628- // TODO: enable once the backend is ready for it.
1629- jujucmd.Register(wrap(&EnsureAvailabilityCommand{}))
1630+ r.Register(wrapEnvCommand(&EnsureAvailabilityCommand{}))
1631
1632 // Common commands.
1633- jujucmd.Register(wrap(&cmd.VersionCommand{}))
1634-
1635- os.Exit(cmd.Main(jujucmd, ctx, args[1:]))
1636-}
1637-
1638-// wrap encapsulates code that wraps some of the commands in a helper class
1639-// that handles some common errors
1640-func wrap(c cmd.Command) cmd.Command {
1641- if ec, ok := c.(envCmd); ok {
1642- return envCmdWrapper{ec}
1643- }
1644- return c
1645-}
1646-
1647-// envCmd is a Command that interacts with the juju client environment
1648-type envCmd interface {
1649- cmd.Command
1650- EnvironName() string
1651+ r.Register(&cmd.VersionCommand{})
1652 }
1653
1654 // envCmdWrapper is a struct that wraps an environment command and lets us handle
1655-// errors returned from Run before they're returned to the main function
1656+// errors returned from Init before they're returned to the main function.
1657 type envCmdWrapper struct {
1658- envCmd
1659+ cmd.Command
1660+ ctx *cmd.Context
1661 }
1662
1663-// Run in envCmdWrapper gives us an opportunity to handle errors after the command is
1664-// run. This is used to give informative messages to the user.
1665-func (c envCmdWrapper) Run(ctx *cmd.Context) error {
1666- err := c.envCmd.Run(ctx)
1667- if environs.IsNoEnv(err) && c.EnvironName() == "" {
1668- fmt.Fprintln(ctx.Stderr, "No juju environment configuration file exists.")
1669- fmt.Fprintln(ctx.Stderr, err)
1670- fmt.Fprintln(ctx.Stderr, "Please create a configuration by running:")
1671- fmt.Fprintln(ctx.Stderr, " juju init")
1672- fmt.Fprintln(ctx.Stderr, "then edit the file to configure your juju environment.")
1673- fmt.Fprintln(ctx.Stderr, "You can then re-run the command.")
1674+func (w envCmdWrapper) Init(args []string) error {
1675+ err := w.Command.Init(args)
1676+ if environs.IsNoEnv(err) {
1677+ fmt.Fprintln(w.ctx.Stderr, "No juju environment configuration file exists.")
1678+ fmt.Fprintln(w.ctx.Stderr, err)
1679+ fmt.Fprintln(w.ctx.Stderr, "Please create a configuration by running:")
1680+ fmt.Fprintln(w.ctx.Stderr, " juju init")
1681+ fmt.Fprintln(w.ctx.Stderr, "then edit the file to configure your juju environment.")
1682+ fmt.Fprintln(w.ctx.Stderr, "You can then re-run the command.")
1683 return cmd.ErrSilent
1684 }
1685-
1686 return err
1687 }
1688
1689
1690=== modified file 'cmd/juju/main_test.go'
1691--- cmd/juju/main_test.go 2014-04-25 13:57:06 +0000
1692+++ cmd/juju/main_test.go 2014-05-12 11:08:32 +0000
1693@@ -19,6 +19,7 @@
1694 gc "launchpad.net/gocheck"
1695
1696 "launchpad.net/juju-core/cmd"
1697+ "launchpad.net/juju-core/cmd/envcmd"
1698 "launchpad.net/juju-core/juju/osenv"
1699 _ "launchpad.net/juju-core/provider/dummy"
1700 "launchpad.net/juju-core/testing"
1701@@ -70,11 +71,11 @@
1702 }
1703
1704 func deployHelpText() string {
1705- return helpText(&DeployCommand{}, "juju deploy")
1706+ return helpText(envcmd.Wrap(&DeployCommand{}), "juju deploy")
1707 }
1708
1709 func syncToolsHelpText() string {
1710- return helpText(&SyncToolsCommand{}, "juju sync-tools")
1711+ return helpText(envcmd.Wrap(&SyncToolsCommand{}), "juju sync-tools")
1712 }
1713
1714 func (s *MainSuite) TestRunMain(c *gc.C) {
1715@@ -350,3 +351,20 @@
1716 c.Assert(line, gc.Matches, globalFlags[i])
1717 }
1718 }
1719+
1720+type commands []cmd.Command
1721+
1722+func (r *commands) Register(c cmd.Command) {
1723+ *r = append(*r, c)
1724+}
1725+
1726+func (s *MainSuite) TestEnvironCommands(c *gc.C) {
1727+ var commands commands
1728+ registerCommands(&commands, testing.Context(c))
1729+ // There should not be any EnvironCommands registered.
1730+ // EnvironCommands must be wrapped using envcmd.Wrap.
1731+ for _, cmd := range commands {
1732+ c.Logf("%v", cmd.Info().Name)
1733+ c.Check(cmd, gc.Not(gc.FitsTypeOf), envcmd.EnvironCommand(&BootstrapCommand{}))
1734+ }
1735+}
1736
1737=== modified file 'cmd/juju/plugin.go'
1738--- cmd/juju/plugin.go 2014-05-09 13:24:50 +0000
1739+++ cmd/juju/plugin.go 2014-05-12 11:08:32 +0000
1740@@ -46,7 +46,7 @@
1741
1742 func RunPlugin(ctx *cmd.Context, subcommand string, args []string) error {
1743 cmdName := JujuPluginPrefix + subcommand
1744- plugin := &PluginCommand{name: cmdName}
1745+ plugin := envcmd.Wrap(&PluginCommand{name: cmdName})
1746
1747 // We process common flags supported by Juju commands.
1748 // To do this, we extract only those supported flags from the
1749@@ -84,22 +84,15 @@
1750 }
1751
1752 func (c *PluginCommand) Init(args []string) error {
1753- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
1754- return err
1755- }
1756 c.args = args
1757 return nil
1758 }
1759
1760-func (c *PluginCommand) SetFlags(f *gnuflag.FlagSet) {
1761- c.EnvCommandBase.SetFlags(f)
1762-}
1763-
1764 func (c *PluginCommand) Run(ctx *cmd.Context) error {
1765 command := exec.Command(c.name, c.args...)
1766 command.Env = append(os.Environ(), []string{
1767 osenv.JujuHomeEnvKey + "=" + osenv.JujuHome(),
1768- osenv.JujuEnvEnvKey + "=" + c.EnvironName()}...,
1769+ osenv.JujuEnvEnvKey + "=" + c.EnvName}...,
1770 )
1771
1772 // Now hook up stdin, stdout, stderr
1773
1774=== modified file 'cmd/juju/publish.go'
1775--- cmd/juju/publish.go 2014-05-09 13:24:50 +0000
1776+++ cmd/juju/publish.go 2014-05-12 11:08:32 +0000
1777@@ -55,14 +55,10 @@
1778 }
1779
1780 func (c *PublishCommand) SetFlags(f *gnuflag.FlagSet) {
1781- c.EnvCommandBase.SetFlags(f)
1782 f.StringVar(&c.CharmPath, "from", ".", "path for charm to be published")
1783 }
1784
1785 func (c *PublishCommand) Init(args []string) error {
1786- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
1787- return err
1788- }
1789 if len(args) == 0 {
1790 return nil
1791 }
1792
1793=== modified file 'cmd/juju/publish_test.go'
1794--- cmd/juju/publish_test.go 2014-05-09 13:24:50 +0000
1795+++ cmd/juju/publish_test.go 2014-05-12 11:08:32 +0000
1796@@ -12,6 +12,7 @@
1797 "launchpad.net/juju-core/bzr"
1798 "launchpad.net/juju-core/charm"
1799 "launchpad.net/juju-core/cmd"
1800+ "launchpad.net/juju-core/cmd/envcmd"
1801 "launchpad.net/juju-core/testing"
1802 "launchpad.net/juju-core/testing/testbase"
1803 )
1804@@ -52,7 +53,7 @@
1805 }
1806
1807 func (s *PublishSuite) runPublish(c *gc.C, args ...string) (*cmd.Context, error) {
1808- return testing.RunCommandInDir(c, &PublishCommand{}, args, s.dir)
1809+ return testing.RunCommandInDir(c, envcmd.Wrap(&PublishCommand{}), args, s.dir)
1810 }
1811
1812 const pollDelay = testing.ShortWait
1813@@ -94,7 +95,7 @@
1814
1815 func (s *PublishSuite) TestNoBranch(c *gc.C) {
1816 dir := c.MkDir()
1817- _, err := testing.RunCommandInDir(c, &PublishCommand{}, []string{"cs:precise/wordpress"}, dir)
1818+ _, err := testing.RunCommandInDir(c, envcmd.Wrap(&PublishCommand{}), []string{"cs:precise/wordpress"}, dir)
1819 c.Assert(err, gc.ErrorMatches, fmt.Sprintf("not a charm branch: %s", dir))
1820 }
1821
1822@@ -104,7 +105,7 @@
1823 }
1824
1825 func (s *PublishSuite) TestFrom(c *gc.C) {
1826- _, err := testing.RunCommandInDir(c, &PublishCommand{}, []string{"--from", s.dir, "cs:precise/wordpress"}, c.MkDir())
1827+ _, err := testing.RunCommandInDir(c, envcmd.Wrap(&PublishCommand{}), []string{"--from", s.dir, "cs:precise/wordpress"}, c.MkDir())
1828 c.Assert(err, gc.ErrorMatches, `cannot obtain local digest: branch has no content`)
1829 }
1830
1831@@ -149,7 +150,7 @@
1832 panic("unreachable")
1833 })
1834
1835- _, err := testing.RunCommandInDir(c, cmd, []string{"precise/wordpress"}, s.dir)
1836+ _, err := testing.RunCommandInDir(c, envcmd.Wrap(cmd), []string{"precise/wordpress"}, s.dir)
1837 c.Assert(err, gc.IsNil)
1838 c.Fatal("shouldn't get here; location closure didn't run?")
1839 }
1840@@ -264,7 +265,7 @@
1841 body = `{"cs:~user/precise/wordpress": {"kind": "published", "digest": %q, "revision": 42}}`
1842 testing.Server.Response(200, nil, []byte(fmt.Sprintf(body, digest)))
1843
1844- ctx, err := testing.RunCommandInDir(c, cmd, []string{"cs:~user/precise/wordpress"}, s.dir)
1845+ ctx, err := testing.RunCommandInDir(c, envcmd.Wrap(cmd), []string{"cs:~user/precise/wordpress"}, s.dir)
1846 c.Assert(err, gc.IsNil)
1847 c.Assert(testing.Stdout(ctx), gc.Equals, "cs:~user/precise/wordpress-42\n")
1848
1849@@ -320,7 +321,7 @@
1850 body = `{"cs:~user/precise/wordpress": {"kind": "published", "digest": %q, "revision": 42}}`
1851 testing.Server.Response(200, nil, []byte(fmt.Sprintf(body, digest)))
1852
1853- ctx, err := testing.RunCommandInDir(c, cmd, []string{"cs:~user/precise/wordpress"}, s.dir)
1854+ ctx, err := testing.RunCommandInDir(c, envcmd.Wrap(cmd), []string{"cs:~user/precise/wordpress"}, s.dir)
1855 c.Assert(err, gc.IsNil)
1856 c.Assert(testing.Stdout(ctx), gc.Equals, "cs:~user/precise/wordpress-42\n")
1857
1858@@ -376,7 +377,7 @@
1859 body = `{"cs:~user/precise/wordpress": {"kind": "published", "digest": "surprising-digest", "revision": 42}}`
1860 testing.Server.Response(200, nil, []byte(body))
1861
1862- _, err = testing.RunCommandInDir(c, cmd, []string{"cs:~user/precise/wordpress"}, s.dir)
1863+ _, err = testing.RunCommandInDir(c, envcmd.Wrap(cmd), []string{"cs:~user/precise/wordpress"}, s.dir)
1864 c.Assert(err, gc.ErrorMatches, `charm changed but not to local charm digest; publishing race\?`)
1865
1866 // Ensure the branch was actually pushed.
1867
1868=== modified file 'cmd/juju/removemachine.go'
1869--- cmd/juju/removemachine.go 2014-05-11 22:52:40 +0000
1870+++ cmd/juju/removemachine.go 2014-05-12 11:08:32 +0000
1871@@ -46,14 +46,10 @@
1872 }
1873
1874 func (c *RemoveMachineCommand) SetFlags(f *gnuflag.FlagSet) {
1875- c.EnvCommandBase.SetFlags(f)
1876 f.BoolVar(&c.Force, "force", false, "completely remove machine and all dependencies")
1877 }
1878
1879 func (c *RemoveMachineCommand) Init(args []string) error {
1880- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
1881- return err
1882- }
1883 if len(args) == 0 {
1884 return fmt.Errorf("no machines specified")
1885 }
1886
1887=== modified file 'cmd/juju/removemachine_test.go'
1888--- cmd/juju/removemachine_test.go 2014-05-09 22:56:29 +0000
1889+++ cmd/juju/removemachine_test.go 2014-05-12 11:08:32 +0000
1890@@ -7,6 +7,7 @@
1891 jc "github.com/juju/testing/checkers"
1892 gc "launchpad.net/gocheck"
1893
1894+ "launchpad.net/juju-core/cmd/envcmd"
1895 "launchpad.net/juju-core/errors"
1896 jujutesting "launchpad.net/juju-core/juju/testing"
1897 "launchpad.net/juju-core/state"
1898@@ -20,7 +21,7 @@
1899 var _ = gc.Suite(&RemoveMachineSuite{})
1900
1901 func runRemoveMachine(c *gc.C, args ...string) error {
1902- _, err := testing.RunCommand(c, &RemoveMachineCommand{}, args)
1903+ _, err := testing.RunCommand(c, envcmd.Wrap(&RemoveMachineCommand{}), args)
1904 return err
1905 }
1906
1907
1908=== modified file 'cmd/juju/removerelation.go'
1909--- cmd/juju/removerelation.go 2014-05-11 22:52:40 +0000
1910+++ cmd/juju/removerelation.go 2014-05-12 11:08:32 +0000
1911@@ -27,9 +27,6 @@
1912 }
1913
1914 func (c *RemoveRelationCommand) Init(args []string) error {
1915- if err := c.EnsureEnvName(); err != nil {
1916- return err
1917- }
1918 if len(args) != 2 {
1919 return fmt.Errorf("a relation must involve two services")
1920 }
1921
1922=== modified file 'cmd/juju/removerelation_test.go'
1923--- cmd/juju/removerelation_test.go 2014-05-08 21:27:00 +0000
1924+++ cmd/juju/removerelation_test.go 2014-05-12 11:08:32 +0000
1925@@ -6,6 +6,7 @@
1926 import (
1927 gc "launchpad.net/gocheck"
1928
1929+ "launchpad.net/juju-core/cmd/envcmd"
1930 jujutesting "launchpad.net/juju-core/juju/testing"
1931 "launchpad.net/juju-core/testing"
1932 )
1933@@ -17,7 +18,7 @@
1934 var _ = gc.Suite(&RemoveRelationSuite{})
1935
1936 func runRemoveRelation(c *gc.C, args ...string) error {
1937- _, err := testing.RunCommand(c, &RemoveRelationCommand{}, args)
1938+ _, err := testing.RunCommand(c, envcmd.Wrap(&RemoveRelationCommand{}), args)
1939 return err
1940 }
1941
1942
1943=== modified file 'cmd/juju/removeservice.go'
1944--- cmd/juju/removeservice.go 2014-05-11 22:52:40 +0000
1945+++ cmd/juju/removeservice.go 2014-05-12 11:08:32 +0000
1946@@ -29,9 +29,6 @@
1947 }
1948
1949 func (c *RemoveServiceCommand) Init(args []string) error {
1950- if err := c.EnsureEnvName(); err != nil {
1951- return err
1952- }
1953 if len(args) == 0 {
1954 return fmt.Errorf("no service specified")
1955 }
1956
1957=== modified file 'cmd/juju/removeservice_test.go'
1958--- cmd/juju/removeservice_test.go 2014-05-08 21:27:00 +0000
1959+++ cmd/juju/removeservice_test.go 2014-05-12 11:08:32 +0000
1960@@ -6,6 +6,7 @@
1961 import (
1962 gc "launchpad.net/gocheck"
1963
1964+ "launchpad.net/juju-core/cmd/envcmd"
1965 jujutesting "launchpad.net/juju-core/juju/testing"
1966 "launchpad.net/juju-core/state"
1967 "launchpad.net/juju-core/testing"
1968@@ -18,7 +19,7 @@
1969 var _ = gc.Suite(&RemoveServiceSuite{})
1970
1971 func runRemoveService(c *gc.C, args ...string) error {
1972- _, err := testing.RunCommand(c, &RemoveServiceCommand{}, args)
1973+ _, err := testing.RunCommand(c, envcmd.Wrap(&RemoveServiceCommand{}), args)
1974 return err
1975 }
1976
1977
1978=== modified file 'cmd/juju/removeunit.go'
1979--- cmd/juju/removeunit.go 2014-05-11 22:52:40 +0000
1980+++ cmd/juju/removeunit.go 2014-05-12 11:08:32 +0000
1981@@ -29,9 +29,6 @@
1982 }
1983
1984 func (c *RemoveUnitCommand) Init(args []string) error {
1985- if err := c.EnsureEnvName(); err != nil {
1986- return err
1987- }
1988 c.UnitNames = args
1989 if len(c.UnitNames) == 0 {
1990 return errors.New("no units specified")
1991
1992=== modified file 'cmd/juju/removeunit_test.go'
1993--- cmd/juju/removeunit_test.go 2014-05-08 21:27:00 +0000
1994+++ cmd/juju/removeunit_test.go 2014-05-12 11:08:32 +0000
1995@@ -7,6 +7,7 @@
1996 gc "launchpad.net/gocheck"
1997
1998 "launchpad.net/juju-core/charm"
1999+ "launchpad.net/juju-core/cmd/envcmd"
2000 jujutesting "launchpad.net/juju-core/juju/testing"
2001 "launchpad.net/juju-core/state"
2002 "launchpad.net/juju-core/testing"
2003@@ -19,7 +20,7 @@
2004 var _ = gc.Suite(&RemoveUnitSuite{})
2005
2006 func runRemoveUnit(c *gc.C, args ...string) error {
2007- _, err := testing.RunCommand(c, &RemoveUnitCommand{}, args)
2008+ _, err := testing.RunCommand(c, envcmd.Wrap(&RemoveUnitCommand{}), args)
2009 return err
2010 }
2011
2012
2013=== modified file 'cmd/juju/removeuser.go'
2014--- cmd/juju/removeuser.go 2014-05-09 13:24:50 +0000
2015+++ cmd/juju/removeuser.go 2014-05-12 11:08:32 +0000
2016@@ -33,9 +33,6 @@
2017 }
2018
2019 func (c *RemoveUserCommand) Init(args []string) error {
2020- if err := c.EnsureEnvName(); err != nil {
2021- return err
2022- }
2023 if len(args) == 0 {
2024 return errors.New("no username supplied")
2025 }
2026
2027=== modified file 'cmd/juju/removeuser_test.go'
2028--- cmd/juju/removeuser_test.go 2014-03-27 04:28:45 +0000
2029+++ cmd/juju/removeuser_test.go 2014-05-12 11:08:32 +0000
2030@@ -6,6 +6,7 @@
2031 import (
2032 gc "launchpad.net/gocheck"
2033
2034+ "launchpad.net/juju-core/cmd/envcmd"
2035 jujutesting "launchpad.net/juju-core/juju/testing"
2036 "launchpad.net/juju-core/testing"
2037 )
2038@@ -17,19 +18,19 @@
2039 var _ = gc.Suite(&RemoveUserSuite{})
2040
2041 func (s *RemoveUserSuite) TestRemoveUser(c *gc.C) {
2042- _, err := testing.RunCommand(c, &AddUserCommand{}, []string{"foobar", "password"})
2043+ _, err := testing.RunCommand(c, envcmd.Wrap(&AddUserCommand{}), []string{"foobar", "password"})
2044 c.Assert(err, gc.IsNil)
2045
2046- _, err = testing.RunCommand(c, &RemoveUserCommand{}, []string{"foobar"})
2047+ _, err = testing.RunCommand(c, envcmd.Wrap(&RemoveUserCommand{}), []string{"foobar"})
2048 c.Assert(err, gc.IsNil)
2049 }
2050
2051 func (s *RemoveUserSuite) TestTooManyArgs(c *gc.C) {
2052- _, err := testing.RunCommand(c, &RemoveUserCommand{}, []string{"foobar", "password"})
2053+ _, err := testing.RunCommand(c, envcmd.Wrap(&RemoveUserCommand{}), []string{"foobar", "password"})
2054 c.Assert(err, gc.ErrorMatches, `unrecognized args: \["password"\]`)
2055 }
2056
2057 func (s *RemoveUserSuite) TestNotEnoughArgs(c *gc.C) {
2058- _, err := testing.RunCommand(c, &RemoveUserCommand{}, []string{})
2059+ _, err := testing.RunCommand(c, envcmd.Wrap(&RemoveUserCommand{}), []string{})
2060 c.Assert(err, gc.ErrorMatches, `no username supplied`)
2061 }
2062
2063=== modified file 'cmd/juju/resolved.go'
2064--- cmd/juju/resolved.go 2014-05-09 13:24:50 +0000
2065+++ cmd/juju/resolved.go 2014-05-12 11:08:32 +0000
2066@@ -30,15 +30,11 @@
2067 }
2068
2069 func (c *ResolvedCommand) SetFlags(f *gnuflag.FlagSet) {
2070- c.EnvCommandBase.SetFlags(f)
2071 f.BoolVar(&c.Retry, "r", false, "re-execute failed hooks")
2072 f.BoolVar(&c.Retry, "retry", false, "")
2073 }
2074
2075 func (c *ResolvedCommand) Init(args []string) error {
2076- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2077- return err
2078- }
2079 if len(args) > 0 {
2080 c.UnitName = args[0]
2081 if !names.IsUnit(c.UnitName) {
2082
2083=== modified file 'cmd/juju/resolved_test.go'
2084--- cmd/juju/resolved_test.go 2013-09-18 15:57:30 +0000
2085+++ cmd/juju/resolved_test.go 2014-05-12 11:08:32 +0000
2086@@ -6,6 +6,7 @@
2087 import (
2088 gc "launchpad.net/gocheck"
2089
2090+ "launchpad.net/juju-core/cmd/envcmd"
2091 jujutesting "launchpad.net/juju-core/juju/testing"
2092 "launchpad.net/juju-core/state"
2093 "launchpad.net/juju-core/state/api/params"
2094@@ -19,7 +20,7 @@
2095 var _ = gc.Suite(&ResolvedSuite{})
2096
2097 func runResolved(c *gc.C, args []string) error {
2098- _, err := testing.RunCommand(c, &ResolvedCommand{}, args)
2099+ _, err := testing.RunCommand(c, envcmd.Wrap(&ResolvedCommand{}), args)
2100 return err
2101 }
2102
2103
2104=== modified file 'cmd/juju/retryprovisioning.go'
2105--- cmd/juju/retryprovisioning.go 2014-05-09 13:24:50 +0000
2106+++ cmd/juju/retryprovisioning.go 2014-05-12 11:08:32 +0000
2107@@ -28,9 +28,6 @@
2108 }
2109
2110 func (c *RetryProvisioningCommand) Init(args []string) error {
2111- if err := c.EnsureEnvName(); err != nil {
2112- return err
2113- }
2114 if len(args) == 0 {
2115 return fmt.Errorf("no machine specified")
2116 }
2117
2118=== modified file 'cmd/juju/retryprovisioning_test.go'
2119--- cmd/juju/retryprovisioning_test.go 2014-03-26 12:42:30 +0000
2120+++ cmd/juju/retryprovisioning_test.go 2014-05-12 11:08:32 +0000
2121@@ -9,6 +9,7 @@
2122 jc "github.com/juju/testing/checkers"
2123 gc "launchpad.net/gocheck"
2124
2125+ "launchpad.net/juju-core/cmd/envcmd"
2126 jujutesting "launchpad.net/juju-core/juju/testing"
2127 "launchpad.net/juju-core/state"
2128 "launchpad.net/juju-core/state/api/params"
2129@@ -61,7 +62,7 @@
2130
2131 for i, t := range resolvedMachineTests {
2132 c.Logf("test %d: %v", i, t.args)
2133- context, err := testing.RunCommand(c, &RetryProvisioningCommand{}, t.args)
2134+ context, err := testing.RunCommand(c, envcmd.Wrap(&RetryProvisioningCommand{}), t.args)
2135 if t.err != "" {
2136 c.Check(err, gc.ErrorMatches, t.err)
2137 continue
2138
2139=== modified file 'cmd/juju/run.go'
2140--- cmd/juju/run.go 2014-05-09 13:24:50 +0000
2141+++ cmd/juju/run.go 2014-05-12 11:08:32 +0000
2142@@ -70,7 +70,6 @@
2143 }
2144
2145 func (c *RunCommand) SetFlags(f *gnuflag.FlagSet) {
2146- c.EnvCommandBase.SetFlags(f)
2147 c.out.AddFlags(f, "smart", cmd.DefaultFormatters)
2148 f.BoolVar(&c.all, "all", false, "run the commands on all the machines")
2149 f.DurationVar(&c.timeout, "timeout", 5*time.Minute, "how long to wait before the remote command is considered to have failed")
2150@@ -80,9 +79,6 @@
2151 }
2152
2153 func (c *RunCommand) Init(args []string) error {
2154- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2155- return err
2156- }
2157 if len(args) == 0 {
2158 return errors.New("no commands specified")
2159 }
2160
2161=== modified file 'cmd/juju/run_test.go'
2162--- cmd/juju/run_test.go 2014-03-27 04:10:28 +0000
2163+++ cmd/juju/run_test.go 2014-05-12 11:08:32 +0000
2164@@ -11,6 +11,7 @@
2165 gc "launchpad.net/gocheck"
2166
2167 "launchpad.net/juju-core/cmd"
2168+ "launchpad.net/juju-core/cmd/envcmd"
2169 "launchpad.net/juju-core/state/api/params"
2170 "launchpad.net/juju-core/testing"
2171 "launchpad.net/juju-core/utils/exec"
2172@@ -106,7 +107,7 @@
2173 }} {
2174 c.Log(fmt.Sprintf("%v: %s", i, test.message))
2175 runCmd := &RunCommand{}
2176- testing.TestInit(c, runCmd, test.args, test.errMatch)
2177+ testing.TestInit(c, envcmd.Wrap(runCmd), test.args, test.errMatch)
2178 if test.errMatch == "" {
2179 c.Check(runCmd.all, gc.Equals, test.all)
2180 c.Check(runCmd.machines, gc.DeepEquals, test.machines)
2181@@ -142,7 +143,7 @@
2182 }} {
2183 c.Log(fmt.Sprintf("%v: %s", i, test.message))
2184 runCmd := &RunCommand{}
2185- testing.TestInit(c, runCmd, test.args, test.errMatch)
2186+ testing.TestInit(c, envcmd.Wrap(runCmd), test.args, test.errMatch)
2187 if test.errMatch == "" {
2188 c.Check(runCmd.timeout, gc.Equals, test.timeout)
2189 }
2190@@ -257,7 +258,7 @@
2191 jsonFormatted, err := cmd.FormatJson(unformatted)
2192 c.Assert(err, gc.IsNil)
2193
2194- context, err := testing.RunCommand(c, &RunCommand{}, []string{
2195+ context, err := testing.RunCommand(c, envcmd.Wrap(&RunCommand{}), []string{
2196 "--format=json", "--machine=0", "--unit=unit/0", "hostname",
2197 })
2198 c.Assert(err, gc.IsNil)
2199@@ -337,7 +338,7 @@
2200 args = append(args, "--format", test.format)
2201 }
2202 args = append(args, "--all", "ignored")
2203- context, err := testing.RunCommand(c, &RunCommand{}, args)
2204+ context, err := testing.RunCommand(c, envcmd.Wrap(&RunCommand{}), args)
2205 if test.errorMatch != "" {
2206 c.Check(err, gc.ErrorMatches, test.errorMatch)
2207 } else {
2208
2209=== modified file 'cmd/juju/set.go'
2210--- cmd/juju/set.go 2014-05-09 13:24:50 +0000
2211+++ cmd/juju/set.go 2014-05-12 11:08:32 +0000
2212@@ -39,14 +39,10 @@
2213 }
2214
2215 func (c *SetCommand) SetFlags(f *gnuflag.FlagSet) {
2216- c.EnvCommandBase.SetFlags(f)
2217 f.Var(&c.SettingsYAML, "config", "path to yaml-formatted service config")
2218 }
2219
2220 func (c *SetCommand) Init(args []string) error {
2221- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2222- return err
2223- }
2224 if len(args) == 0 || len(strings.Split(args[0], "=")) > 1 {
2225 return errors.New("no service name specified")
2226 }
2227
2228=== modified file 'cmd/juju/set_test.go'
2229--- cmd/juju/set_test.go 2013-10-09 13:55:14 +0000
2230+++ cmd/juju/set_test.go 2014-05-12 11:08:32 +0000
2231@@ -11,6 +11,7 @@
2232
2233 "launchpad.net/juju-core/charm"
2234 "launchpad.net/juju-core/cmd"
2235+ "launchpad.net/juju-core/cmd/envcmd"
2236 "launchpad.net/juju-core/juju/testing"
2237 "launchpad.net/juju-core/state"
2238 coretesting "launchpad.net/juju-core/testing"
2239@@ -73,7 +74,7 @@
2240 // assertSetSuccess sets configuration options and checks the expected settings.
2241 func assertSetSuccess(c *gc.C, dir string, svc *state.Service, args []string, expect charm.Settings) {
2242 ctx := coretesting.ContextForDir(c, dir)
2243- code := cmd.Main(&SetCommand{}, ctx, append([]string{"dummy-service"}, args...))
2244+ code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, args...))
2245 c.Check(code, gc.Equals, 0)
2246 settings, err := svc.ConfigSettings()
2247 c.Assert(err, gc.IsNil)
2248@@ -83,7 +84,7 @@
2249 // assertSetFail sets configuration options and checks the expected error.
2250 func assertSetFail(c *gc.C, dir string, args []string, err string) {
2251 ctx := coretesting.ContextForDir(c, dir)
2252- code := cmd.Main(&SetCommand{}, ctx, append([]string{"dummy-service"}, args...))
2253+ code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, args...))
2254 c.Check(code, gc.Not(gc.Equals), 0)
2255 c.Assert(ctx.Stderr.(*bytes.Buffer).String(), gc.Matches, err)
2256 }
2257
2258=== modified file 'cmd/juju/ssh.go'
2259--- cmd/juju/ssh.go 2014-05-09 13:24:50 +0000
2260+++ cmd/juju/ssh.go 2014-05-12 11:08:32 +0000
2261@@ -40,7 +40,6 @@
2262 }
2263
2264 func (c *SSHCommon) SetFlags(f *gnuflag.FlagSet) {
2265- c.EnvCommandBase.SetFlags(f)
2266 f.BoolVar(&c.proxy, "proxy", true, "proxy through the API server")
2267 f.BoolVar(&c.pty, "pty", true, "enable pseudo-tty allocation")
2268 }
2269@@ -94,9 +93,6 @@
2270 }
2271
2272 func (c *SSHCommand) Init(args []string) error {
2273- if err := c.EnsureEnvName(); err != nil {
2274- return err
2275- }
2276 if len(args) == 0 {
2277 return errors.New("no target name specified")
2278 }
2279
2280=== modified file 'cmd/juju/ssh_test.go'
2281--- cmd/juju/ssh_test.go 2014-05-09 07:41:52 +0000
2282+++ cmd/juju/ssh_test.go 2014-05-12 11:08:32 +0000
2283@@ -14,6 +14,7 @@
2284
2285 "launchpad.net/juju-core/charm"
2286 "launchpad.net/juju-core/cmd"
2287+ "launchpad.net/juju-core/cmd/envcmd"
2288 "launchpad.net/juju-core/instance"
2289 "launchpad.net/juju-core/juju/testing"
2290 "launchpad.net/juju-core/state"
2291@@ -113,7 +114,7 @@
2292 c.Logf("test %d: %s -> %s\n", i, t.about, t.args)
2293 ctx := coretesting.Context(c)
2294 jujucmd := cmd.NewSuperCommand(cmd.SuperCommandParams{})
2295- jujucmd.Register(&SSHCommand{})
2296+ jujucmd.Register(envcmd.Wrap(&SSHCommand{}))
2297
2298 code := cmd.Main(jujucmd, ctx, t.args)
2299 c.Check(code, gc.Equals, 0)
2300
2301=== modified file 'cmd/juju/status.go'
2302--- cmd/juju/status.go 2014-05-09 13:24:50 +0000
2303+++ cmd/juju/status.go 2014-05-12 11:08:32 +0000
2304@@ -50,7 +50,6 @@
2305 }
2306
2307 func (c *StatusCommand) SetFlags(f *gnuflag.FlagSet) {
2308- c.EnvCommandBase.SetFlags(f)
2309 c.out.AddFlags(f, "yaml", map[string]cmd.Formatter{
2310 "yaml": cmd.FormatYaml,
2311 "json": cmd.FormatJson,
2312@@ -58,9 +57,6 @@
2313 }
2314
2315 func (c *StatusCommand) Init(args []string) error {
2316- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2317- return err
2318- }
2319 c.patterns = args
2320 return nil
2321 }
2322
2323=== modified file 'cmd/juju/status_test.go'
2324--- cmd/juju/status_test.go 2014-05-01 17:56:04 +0000
2325+++ cmd/juju/status_test.go 2014-05-12 11:08:32 +0000
2326@@ -17,6 +17,7 @@
2327
2328 "launchpad.net/juju-core/charm"
2329 "launchpad.net/juju-core/cmd"
2330+ "launchpad.net/juju-core/cmd/envcmd"
2331 "launchpad.net/juju-core/constraints"
2332 "launchpad.net/juju-core/environs/network"
2333 "launchpad.net/juju-core/instance"
2334@@ -31,7 +32,7 @@
2335
2336 func runStatus(c *gc.C, args ...string) (code int, stdout, stderr []byte) {
2337 ctx := coretesting.Context(c)
2338- code = cmd.Main(&StatusCommand{}, ctx, args)
2339+ code = cmd.Main(envcmd.Wrap(&StatusCommand{}), ctx, args)
2340 stdout = ctx.Stdout.(*bytes.Buffer).Bytes()
2341 stderr = ctx.Stderr.(*bytes.Buffer).Bytes()
2342 return
2343
2344=== modified file 'cmd/juju/synctools.go'
2345--- cmd/juju/synctools.go 2014-05-09 13:24:50 +0000
2346+++ cmd/juju/synctools.go 2014-05-12 11:08:32 +0000
2347@@ -52,7 +52,6 @@
2348 }
2349
2350 func (c *SyncToolsCommand) SetFlags(f *gnuflag.FlagSet) {
2351- c.EnvCommandBase.SetFlags(f)
2352 f.BoolVar(&c.allVersions, "all", false, "copy all versions, not just the latest")
2353 f.StringVar(&c.versionStr, "version", "", "copy a specific major[.minor] version")
2354 f.BoolVar(&c.dryRun, "dry-run", false, "don't copy, just print what would be copied")
2355@@ -64,9 +63,6 @@
2356 }
2357
2358 func (c *SyncToolsCommand) Init(args []string) error {
2359- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2360- return err
2361- }
2362 if c.destination != "" {
2363 // Override localDir with destination as localDir now replaces destination
2364 c.localDir = c.destination
2365
2366=== modified file 'cmd/juju/synctools_test.go'
2367--- cmd/juju/synctools_test.go 2014-03-24 10:42:51 +0000
2368+++ cmd/juju/synctools_test.go 2014-05-12 11:08:32 +0000
2369@@ -12,6 +12,7 @@
2370 gc "launchpad.net/gocheck"
2371
2372 "launchpad.net/juju-core/cmd"
2373+ "launchpad.net/juju-core/cmd/envcmd"
2374 "launchpad.net/juju-core/environs"
2375 "launchpad.net/juju-core/environs/configstore"
2376 "launchpad.net/juju-core/environs/sync"
2377@@ -61,7 +62,7 @@
2378 }
2379
2380 func runSyncToolsCommand(c *gc.C, args ...string) (*cmd.Context, error) {
2381- return coretesting.RunCommand(c, &SyncToolsCommand{}, args)
2382+ return coretesting.RunCommand(c, envcmd.Wrap(&SyncToolsCommand{}), args)
2383 }
2384
2385 func wait(signal chan struct{}) error {
2386
2387=== modified file 'cmd/juju/unexpose.go'
2388--- cmd/juju/unexpose.go 2014-05-09 13:24:50 +0000
2389+++ cmd/juju/unexpose.go 2014-05-12 11:08:32 +0000
2390@@ -26,9 +26,6 @@
2391 }
2392
2393 func (c *UnexposeCommand) Init(args []string) error {
2394- if err := c.EnsureEnvName(); err != nil {
2395- return err
2396- }
2397 if len(args) == 0 {
2398 return errors.New("no service name specified")
2399 }
2400
2401=== modified file 'cmd/juju/unexpose_test.go'
2402--- cmd/juju/unexpose_test.go 2013-09-13 14:48:13 +0000
2403+++ cmd/juju/unexpose_test.go 2014-05-12 11:08:32 +0000
2404@@ -7,6 +7,7 @@
2405 gc "launchpad.net/gocheck"
2406
2407 "launchpad.net/juju-core/charm"
2408+ "launchpad.net/juju-core/cmd/envcmd"
2409 jujutesting "launchpad.net/juju-core/juju/testing"
2410 "launchpad.net/juju-core/testing"
2411 )
2412@@ -18,7 +19,7 @@
2413 var _ = gc.Suite(&UnexposeSuite{})
2414
2415 func runUnexpose(c *gc.C, args ...string) error {
2416- _, err := testing.RunCommand(c, &UnexposeCommand{}, args)
2417+ _, err := testing.RunCommand(c, envcmd.Wrap(&UnexposeCommand{}), args)
2418 return err
2419 }
2420
2421
2422=== modified file 'cmd/juju/unset.go'
2423--- cmd/juju/unset.go 2014-05-09 13:24:50 +0000
2424+++ cmd/juju/unset.go 2014-05-12 11:08:32 +0000
2425@@ -6,8 +6,6 @@
2426 import (
2427 "errors"
2428
2429- "launchpad.net/gnuflag"
2430-
2431 "launchpad.net/juju-core/cmd"
2432 "launchpad.net/juju-core/cmd/envcmd"
2433 "launchpad.net/juju-core/juju"
2434@@ -36,14 +34,7 @@
2435 }
2436 }
2437
2438-func (c *UnsetCommand) SetFlags(f *gnuflag.FlagSet) {
2439- c.EnvCommandBase.SetFlags(f)
2440-}
2441-
2442 func (c *UnsetCommand) Init(args []string) error {
2443- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2444- return err
2445- }
2446 if len(args) == 0 {
2447 return errors.New("no service name specified")
2448 }
2449
2450=== modified file 'cmd/juju/unset_test.go'
2451--- cmd/juju/unset_test.go 2013-11-28 15:53:00 +0000
2452+++ cmd/juju/unset_test.go 2014-05-12 11:08:32 +0000
2453@@ -10,6 +10,7 @@
2454
2455 "launchpad.net/juju-core/charm"
2456 "launchpad.net/juju-core/cmd"
2457+ "launchpad.net/juju-core/cmd/envcmd"
2458 "launchpad.net/juju-core/juju/testing"
2459 "launchpad.net/juju-core/state"
2460 coretesting "launchpad.net/juju-core/testing"
2461@@ -77,7 +78,7 @@
2462 // assertUnsetSuccess unsets configuration options and checks the expected settings.
2463 func assertUnsetSuccess(c *gc.C, dir string, svc *state.Service, args []string, expect charm.Settings) {
2464 ctx := coretesting.ContextForDir(c, dir)
2465- code := cmd.Main(&UnsetCommand{}, ctx, append([]string{"dummy-service"}, args...))
2466+ code := cmd.Main(envcmd.Wrap(&UnsetCommand{}), ctx, append([]string{"dummy-service"}, args...))
2467 c.Check(code, gc.Equals, 0)
2468 settings, err := svc.ConfigSettings()
2469 c.Assert(err, gc.IsNil)
2470@@ -87,7 +88,7 @@
2471 // assertUnsetFail unsets configuration options and checks the expected error.
2472 func assertUnsetFail(c *gc.C, dir string, args []string, err string) {
2473 ctx := coretesting.ContextForDir(c, dir)
2474- code := cmd.Main(&UnsetCommand{}, ctx, append([]string{"dummy-service"}, args...))
2475+ code := cmd.Main(envcmd.Wrap(&UnsetCommand{}), ctx, append([]string{"dummy-service"}, args...))
2476 c.Check(code, gc.Not(gc.Equals), 0)
2477 c.Assert(ctx.Stderr.(*bytes.Buffer).String(), gc.Matches, err)
2478 }
2479
2480=== modified file 'cmd/juju/upgradecharm.go'
2481--- cmd/juju/upgradecharm.go 2014-05-09 13:24:50 +0000
2482+++ cmd/juju/upgradecharm.go 2014-05-12 11:08:32 +0000
2483@@ -76,7 +76,6 @@
2484 }
2485
2486 func (c *UpgradeCharmCommand) SetFlags(f *gnuflag.FlagSet) {
2487- c.EnvCommandBase.SetFlags(f)
2488 f.BoolVar(&c.Force, "force", false, "upgrade all units immediately, even if in error state")
2489 f.StringVar(&c.RepoPath, "repository", os.Getenv("JUJU_REPOSITORY"), "local charm repository path")
2490 f.StringVar(&c.SwitchURL, "switch", "", "crossgrade to a different charm")
2491@@ -84,9 +83,6 @@
2492 }
2493
2494 func (c *UpgradeCharmCommand) Init(args []string) error {
2495- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2496- return err
2497- }
2498 switch len(args) {
2499 case 1:
2500 if !names.IsService(args[0]) {
2501
2502=== modified file 'cmd/juju/upgradecharm_test.go'
2503--- cmd/juju/upgradecharm_test.go 2014-03-18 05:08:25 +0000
2504+++ cmd/juju/upgradecharm_test.go 2014-05-12 11:08:32 +0000
2505@@ -13,6 +13,7 @@
2506
2507 "launchpad.net/juju-core/charm"
2508 charmtesting "launchpad.net/juju-core/charm/testing"
2509+ "launchpad.net/juju-core/cmd/envcmd"
2510 jujutesting "launchpad.net/juju-core/juju/testing"
2511 "launchpad.net/juju-core/state"
2512 "launchpad.net/juju-core/testing"
2513@@ -34,7 +35,7 @@
2514 var _ = gc.Suite(&UpgradeCharmErrorsSuite{})
2515
2516 func runUpgradeCharm(c *gc.C, args ...string) error {
2517- _, err := testing.RunCommand(c, &UpgradeCharmCommand{}, args)
2518+ _, err := testing.RunCommand(c, envcmd.Wrap(&UpgradeCharmCommand{}), args)
2519 return err
2520 }
2521
2522
2523=== modified file 'cmd/juju/upgradejuju.go'
2524--- cmd/juju/upgradejuju.go 2014-05-09 13:24:50 +0000
2525+++ cmd/juju/upgradejuju.go 2014-05-12 11:08:32 +0000
2526@@ -76,16 +76,12 @@
2527 }
2528
2529 func (c *UpgradeJujuCommand) SetFlags(f *gnuflag.FlagSet) {
2530- c.EnvCommandBase.SetFlags(f)
2531 f.StringVar(&c.vers, "version", "", "upgrade to specific version")
2532 f.BoolVar(&c.UploadTools, "upload-tools", false, "upload local version of tools")
2533 f.Var(newSeriesValue(nil, &c.Series), "series", "upload tools for supplied comma-separated series list")
2534 }
2535
2536 func (c *UpgradeJujuCommand) Init(args []string) error {
2537- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2538- return err
2539- }
2540 if c.vers != "" {
2541 vers, err := version.Parse(c.vers)
2542 if err != nil {
2543
2544=== modified file 'cmd/juju/upgradejuju_test.go'
2545--- cmd/juju/upgradejuju_test.go 2014-04-09 16:36:12 +0000
2546+++ cmd/juju/upgradejuju_test.go 2014-05-12 11:08:32 +0000
2547@@ -14,6 +14,7 @@
2548 jc "github.com/juju/testing/checkers"
2549 gc "launchpad.net/gocheck"
2550
2551+ "launchpad.net/juju-core/cmd/envcmd"
2552 "launchpad.net/juju-core/environs/config"
2553 "launchpad.net/juju-core/environs/filestorage"
2554 "launchpad.net/juju-core/environs/storage"
2555@@ -313,7 +314,7 @@
2556 // Set up apparent CLI version and initialize the command.
2557 version.Current = version.MustParseBinary(test.currentVersion)
2558 com := &UpgradeJujuCommand{}
2559- if err := coretesting.InitCommand(com, test.args); err != nil {
2560+ if err := coretesting.InitCommand(envcmd.Wrap(com), test.args); err != nil {
2561 if test.expectInitErr != "" {
2562 c.Check(err, gc.ErrorMatches, test.expectInitErr)
2563 } else {
2564
2565=== modified file 'cmd/plugins/juju-metadata/imagemetadata.go'
2566--- cmd/plugins/juju-metadata/imagemetadata.go 2014-05-09 13:24:50 +0000
2567+++ cmd/plugins/juju-metadata/imagemetadata.go 2014-05-12 11:08:32 +0000
2568@@ -53,7 +53,6 @@
2569 }
2570
2571 func (c *ImageMetadataCommand) SetFlags(f *gnuflag.FlagSet) {
2572- c.EnvCommandBase.SetFlags(f)
2573 f.StringVar(&c.Series, "s", "", "the charm series")
2574 f.StringVar(&c.Arch, "a", arch.AMD64, "the image achitecture")
2575 f.StringVar(&c.Dir, "d", "", "the destination directory in which to place the metadata files")
2576@@ -62,13 +61,6 @@
2577 f.StringVar(&c.Endpoint, "u", "", "the cloud endpoint (for Openstack, this is the Identity Service endpoint)")
2578 }
2579
2580-func (c *ImageMetadataCommand) Init(args []string) error {
2581- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2582- return err
2583- }
2584- return cmd.CheckEmpty(args)
2585-}
2586-
2587 // setParams sets parameters based on the environment configuration
2588 // for those which have not been explicitly specified.
2589 func (c *ImageMetadataCommand) setParams(context *cmd.Context) error {
2590
2591=== modified file 'cmd/plugins/juju-metadata/imagemetadata_test.go'
2592--- cmd/plugins/juju-metadata/imagemetadata_test.go 2014-05-09 21:54:06 +0000
2593+++ cmd/plugins/juju-metadata/imagemetadata_test.go 2014-05-12 11:08:32 +0000
2594@@ -15,6 +15,7 @@
2595 gc "launchpad.net/gocheck"
2596
2597 "launchpad.net/juju-core/cmd"
2598+ "launchpad.net/juju-core/cmd/envcmd"
2599 "launchpad.net/juju-core/environs/config"
2600 "launchpad.net/juju-core/provider/dummy"
2601 "launchpad.net/juju-core/testing"
2602@@ -116,7 +117,7 @@
2603 func (s *ImageMetadataSuite) TestImageMetadataFilesNoEnv(c *gc.C) {
2604 ctx := testing.Context(c)
2605 code := cmd.Main(
2606- &ImageMetadataCommand{}, ctx, []string{
2607+ envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
2608 "-d", s.dir, "-i", "1234", "-r", "region", "-a", "arch", "-u", "endpoint", "-s", "raring"})
2609 c.Assert(code, gc.Equals, 0)
2610 out := testing.Stdout(ctx)
2611@@ -130,7 +131,7 @@
2612 func (s *ImageMetadataSuite) TestImageMetadataFilesDefaultArch(c *gc.C) {
2613 ctx := testing.Context(c)
2614 code := cmd.Main(
2615- &ImageMetadataCommand{}, ctx, []string{
2616+ envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
2617 "-d", s.dir, "-i", "1234", "-r", "region", "-u", "endpoint", "-s", "raring"})
2618 c.Assert(code, gc.Equals, 0)
2619 out := testing.Stdout(ctx)
2620@@ -144,7 +145,7 @@
2621 func (s *ImageMetadataSuite) TestImageMetadataFilesLatestLts(c *gc.C) {
2622 ctx := testing.Context(c)
2623 code := cmd.Main(
2624- &ImageMetadataCommand{}, ctx, []string{
2625+ envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
2626 "-d", s.dir, "-i", "1234", "-r", "region", "-a", "arch", "-u", "endpoint"})
2627 c.Assert(code, gc.Equals, 0)
2628 out := testing.Stdout(ctx)
2629@@ -158,7 +159,7 @@
2630 func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnv(c *gc.C) {
2631 ctx := testing.Context(c)
2632 code := cmd.Main(
2633- &ImageMetadataCommand{}, ctx, []string{"-d", s.dir, "-e", "ec2", "-i", "1234"})
2634+ envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{"-d", s.dir, "-e", "ec2", "-i", "1234"})
2635 c.Assert(code, gc.Equals, 0)
2636 out := testing.Stdout(ctx)
2637 expected := expectedMetadata{
2638@@ -173,7 +174,7 @@
2639 func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvWithRegionOverride(c *gc.C) {
2640 ctx := testing.Context(c)
2641 code := cmd.Main(
2642- &ImageMetadataCommand{}, ctx, []string{
2643+ envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
2644 "-d", s.dir, "-e", "ec2", "-r", "us-west-1", "-u", "https://ec2.us-west-1.amazonaws.com", "-i", "1234"})
2645 c.Assert(code, gc.Equals, 0)
2646 out := testing.Stdout(ctx)
2647@@ -189,7 +190,7 @@
2648 func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvWithNoHasRegion(c *gc.C) {
2649 ctx := testing.Context(c)
2650 code := cmd.Main(
2651- &ImageMetadataCommand{}, ctx, []string{
2652+ envcmd.Wrap(&ImageMetadataCommand{}), ctx, []string{
2653 "-d", s.dir, "-e", "azure", "-r", "region", "-u", "endpoint", "-i", "1234"})
2654 c.Assert(code, gc.Equals, 0)
2655 out := testing.Stdout(ctx)
2656@@ -234,7 +235,7 @@
2657 for i, t := range errTests {
2658 c.Logf("test: %d", i)
2659 ctx := testing.Context(c)
2660- code := cmd.Main(&ImageMetadataCommand{}, ctx, t.args)
2661+ code := cmd.Main(envcmd.Wrap(&ImageMetadataCommand{}), ctx, t.args)
2662 c.Check(code, gc.Equals, 1)
2663 }
2664 }
2665
2666=== modified file 'cmd/plugins/juju-metadata/metadata.go'
2667--- cmd/plugins/juju-metadata/metadata.go 2014-03-21 14:28:36 +0000
2668+++ cmd/plugins/juju-metadata/metadata.go 2014-05-12 11:08:32 +0000
2669@@ -10,6 +10,7 @@
2670 "github.com/juju/loggo"
2671
2672 "launchpad.net/juju-core/cmd"
2673+ "launchpad.net/juju-core/cmd/envcmd"
2674 "launchpad.net/juju-core/juju"
2675 _ "launchpad.net/juju-core/provider/all"
2676 )
2677@@ -41,10 +42,10 @@
2678 Purpose: "tools for generating and validating image and tools metadata",
2679 Log: &cmd.Log{}})
2680
2681- metadatacmd.Register(&ValidateImageMetadataCommand{})
2682- metadatacmd.Register(&ImageMetadataCommand{})
2683- metadatacmd.Register(&ToolsMetadataCommand{})
2684- metadatacmd.Register(&ValidateToolsMetadataCommand{})
2685+ metadatacmd.Register(envcmd.Wrap(&ValidateImageMetadataCommand{}))
2686+ metadatacmd.Register(envcmd.Wrap(&ImageMetadataCommand{}))
2687+ metadatacmd.Register(envcmd.Wrap(&ToolsMetadataCommand{}))
2688+ metadatacmd.Register(envcmd.Wrap(&ValidateToolsMetadataCommand{}))
2689 metadatacmd.Register(&SignMetadataCommand{})
2690
2691 os.Exit(cmd.Main(metadatacmd, ctx, args[1:]))
2692
2693=== modified file 'cmd/plugins/juju-metadata/toolsmetadata.go'
2694--- cmd/plugins/juju-metadata/toolsmetadata.go 2014-05-09 13:24:50 +0000
2695+++ cmd/plugins/juju-metadata/toolsmetadata.go 2014-05-12 11:08:32 +0000
2696@@ -37,18 +37,10 @@
2697 }
2698
2699 func (c *ToolsMetadataCommand) SetFlags(f *gnuflag.FlagSet) {
2700- c.EnvCommandBase.SetFlags(f)
2701 f.StringVar(&c.metadataDir, "d", "", "local directory in which to store metadata")
2702 f.BoolVar(&c.public, "public", false, "tools are for a public cloud, so generate mirrors information")
2703 }
2704
2705-func (c *ToolsMetadataCommand) Init(args []string) error {
2706- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2707- return err
2708- }
2709- return cmd.CheckEmpty(args)
2710-}
2711-
2712 func (c *ToolsMetadataCommand) Run(context *cmd.Context) error {
2713 loggo.RegisterWriter("toolsmetadata", cmd.NewCommandLogWriter("juju.environs.tools", context.Stdout, context.Stderr), loggo.INFO)
2714 defer loggo.RemoveWriter("toolsmetadata")
2715
2716=== modified file 'cmd/plugins/juju-metadata/toolsmetadata_test.go'
2717--- cmd/plugins/juju-metadata/toolsmetadata_test.go 2014-04-09 16:36:12 +0000
2718+++ cmd/plugins/juju-metadata/toolsmetadata_test.go 2014-05-12 11:08:32 +0000
2719@@ -14,6 +14,7 @@
2720 gc "launchpad.net/gocheck"
2721
2722 "launchpad.net/juju-core/cmd"
2723+ "launchpad.net/juju-core/cmd/envcmd"
2724 "launchpad.net/juju-core/environs"
2725 "launchpad.net/juju-core/environs/configstore"
2726 envtesting "launchpad.net/juju-core/environs/testing"
2727@@ -100,7 +101,7 @@
2728 metadataDir := osenv.JujuHome() // default metadata dir
2729 ttesting.MakeTools(c, metadataDir, "releases", versionStrings)
2730 ctx := coretesting.Context(c)
2731- code := cmd.Main(&ToolsMetadataCommand{}, ctx, nil)
2732+ code := cmd.Main(envcmd.Wrap(&ToolsMetadataCommand{}), ctx, nil)
2733 c.Assert(code, gc.Equals, 0)
2734 output := ctx.Stdout.(*bytes.Buffer).String()
2735 c.Assert(output, gc.Matches, expectedOutputDirectory)
2736@@ -118,7 +119,7 @@
2737 metadataDir := c.MkDir()
2738 ttesting.MakeTools(c, metadataDir, "releases", versionStrings)
2739 ctx := coretesting.Context(c)
2740- code := cmd.Main(&ToolsMetadataCommand{}, ctx, []string{"-d", metadataDir})
2741+ code := cmd.Main(envcmd.Wrap(&ToolsMetadataCommand{}), ctx, []string{"-d", metadataDir})
2742 c.Assert(code, gc.Equals, 0)
2743 output := ctx.Stdout.(*bytes.Buffer).String()
2744 c.Assert(output, gc.Matches, expectedOutputDirectory)
2745@@ -139,7 +140,7 @@
2746 // Run the command with no local metadata.
2747 ctx := coretesting.Context(c)
2748 metadataDir := c.MkDir()
2749- code := cmd.Main(&ToolsMetadataCommand{}, ctx, []string{"-d", metadataDir})
2750+ code := cmd.Main(envcmd.Wrap(&ToolsMetadataCommand{}), ctx, []string{"-d", metadataDir})
2751 c.Assert(code, gc.Equals, 0)
2752 metadata := ttesting.ParseMetadataFromDir(c, metadataDir, false)
2753 c.Assert(metadata, gc.HasLen, len(versionStrings))
2754@@ -155,7 +156,7 @@
2755 metadataDir := c.MkDir()
2756 ttesting.MakeTools(c, metadataDir, "releases", versionStrings)
2757 ctx := coretesting.Context(c)
2758- code := cmd.Main(&ToolsMetadataCommand{}, ctx, []string{"--public", "-d", metadataDir})
2759+ code := cmd.Main(envcmd.Wrap(&ToolsMetadataCommand{}), ctx, []string{"--public", "-d", metadataDir})
2760 c.Assert(code, gc.Equals, 0)
2761 output := ctx.Stdout.(*bytes.Buffer).String()
2762 c.Assert(output, gc.Matches, expectedOutputMirrors)
2763@@ -171,7 +172,7 @@
2764
2765 func (s *ToolsMetadataSuite) TestNoTools(c *gc.C) {
2766 ctx := coretesting.Context(c)
2767- code := cmd.Main(&ToolsMetadataCommand{}, ctx, nil)
2768+ code := cmd.Main(envcmd.Wrap(&ToolsMetadataCommand{}), ctx, nil)
2769 c.Assert(code, gc.Equals, 1)
2770 stdout := ctx.Stdout.(*bytes.Buffer).String()
2771 c.Assert(stdout, gc.Matches, "Finding tools in .*\n")
2772@@ -189,7 +190,7 @@
2773 metadataDir := osenv.JujuHome() // default metadata dir
2774 ttesting.MakeTools(c, metadataDir, "releases", versionStrings)
2775 ctx := coretesting.Context(c)
2776- code := cmd.Main(&ToolsMetadataCommand{}, ctx, nil)
2777+ code := cmd.Main(envcmd.Wrap(&ToolsMetadataCommand{}), ctx, nil)
2778 c.Assert(code, gc.Equals, 0)
2779 output := ctx.Stdout.(*bytes.Buffer).String()
2780 expectedOutput := fmt.Sprintf(`
2781
2782=== modified file 'cmd/plugins/juju-metadata/validateimagemetadata.go'
2783--- cmd/plugins/juju-metadata/validateimagemetadata.go 2014-05-09 13:24:50 +0000
2784+++ cmd/plugins/juju-metadata/validateimagemetadata.go 2014-05-12 11:08:32 +0000
2785@@ -81,7 +81,6 @@
2786 }
2787
2788 func (c *ValidateImageMetadataCommand) SetFlags(f *gnuflag.FlagSet) {
2789- c.EnvCommandBase.SetFlags(f)
2790 c.out.AddFlags(f, "smart", cmd.DefaultFormatters)
2791 f.StringVar(&c.providerType, "p", "", "the provider type eg ec2, openstack")
2792 f.StringVar(&c.metadataDir, "d", "", "directory where metadata files are found")
2793@@ -92,9 +91,6 @@
2794 }
2795
2796 func (c *ValidateImageMetadataCommand) Init(args []string) error {
2797- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2798- return err
2799- }
2800 if c.providerType != "" {
2801 if c.series == "" {
2802 return fmt.Errorf("series required if provider type is specified")
2803
2804=== modified file 'cmd/plugins/juju-metadata/validateimagemetadata_test.go'
2805--- cmd/plugins/juju-metadata/validateimagemetadata_test.go 2014-05-08 09:27:50 +0000
2806+++ cmd/plugins/juju-metadata/validateimagemetadata_test.go 2014-05-12 11:08:32 +0000
2807@@ -11,6 +11,7 @@
2808 gc "launchpad.net/gocheck"
2809
2810 "launchpad.net/juju-core/cmd"
2811+ "launchpad.net/juju-core/cmd/envcmd"
2812 "launchpad.net/juju-core/environs/filestorage"
2813 "launchpad.net/juju-core/environs/imagemetadata"
2814 "launchpad.net/juju-core/environs/simplestreams"
2815@@ -27,7 +28,7 @@
2816 var _ = gc.Suite(&ValidateImageMetadataSuite{})
2817
2818 func runValidateImageMetadata(c *gc.C, args ...string) error {
2819- _, err := coretesting.RunCommand(c, &ValidateImageMetadataCommand{}, args)
2820+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&ValidateImageMetadataCommand{}), args)
2821 return err
2822 }
2823
2824@@ -50,7 +51,7 @@
2825 func (s *ValidateImageMetadataSuite) TestInitErrors(c *gc.C) {
2826 for i, t := range validateInitImageErrorTests {
2827 c.Logf("test %d", i)
2828- err := coretesting.InitCommand(&ValidateImageMetadataCommand{}, t.args)
2829+ err := coretesting.InitCommand(envcmd.Wrap(&ValidateImageMetadataCommand{}), t.args)
2830 c.Check(err, gc.ErrorMatches, t.err)
2831 }
2832 }
2833@@ -130,7 +131,7 @@
2834 s.setupEc2LocalMetadata(c, "us-east-1", stream)
2835 ctx := coretesting.Context(c)
2836 code := cmd.Main(
2837- &ValidateImageMetadataCommand{}, ctx, []string{"-e", "ec2", "-d", s.metadataDir, "-m", stream},
2838+ envcmd.Wrap(&ValidateImageMetadataCommand{}), ctx, []string{"-e", "ec2", "-d", s.metadataDir, "-m", stream},
2839 )
2840 c.Assert(code, gc.Equals, 0)
2841 errOut := ctx.Stdout.(*bytes.Buffer).String()
2842@@ -154,7 +155,7 @@
2843 s.setupEc2LocalMetadata(c, "us-east-1", "")
2844 ctx := coretesting.Context(c)
2845 code := cmd.Main(
2846- &ValidateImageMetadataCommand{}, ctx, []string{"-e", "ec2", "-d", s.metadataDir},
2847+ envcmd.Wrap(&ValidateImageMetadataCommand{}), ctx, []string{"-e", "ec2", "-d", s.metadataDir},
2848 )
2849 c.Assert(code, gc.Equals, 1)
2850 errOut := ctx.Stderr.(*bytes.Buffer).String()
2851@@ -166,7 +167,7 @@
2852 s.setupEc2LocalMetadata(c, "us-west-1", "")
2853 ctx := coretesting.Context(c)
2854 code := cmd.Main(
2855- &ValidateImageMetadataCommand{}, ctx, []string{
2856+ envcmd.Wrap(&ValidateImageMetadataCommand{}), ctx, []string{
2857 "-p", "ec2", "-s", "precise", "-r", "us-west-1",
2858 "-u", "https://ec2.us-west-1.amazonaws.com", "-d", s.metadataDir},
2859 )
2860@@ -182,13 +183,13 @@
2861 s.setupEc2LocalMetadata(c, "us-east-1", "")
2862 ctx := coretesting.Context(c)
2863 code := cmd.Main(
2864- &ValidateImageMetadataCommand{}, ctx, []string{
2865+ envcmd.Wrap(&ValidateImageMetadataCommand{}), ctx, []string{
2866 "-p", "ec2", "-s", "raring", "-r", "us-west-1",
2867 "-u", "https://ec2.us-west-1.amazonaws.com", "-d", s.metadataDir},
2868 )
2869 c.Assert(code, gc.Equals, 1)
2870 code = cmd.Main(
2871- &ValidateImageMetadataCommand{}, ctx, []string{
2872+ envcmd.Wrap(&ValidateImageMetadataCommand{}), ctx, []string{
2873 "-p", "ec2", "-s", "precise", "-r", "region",
2874 "-u", "https://ec2.region.amazonaws.com", "-d", s.metadataDir},
2875 )
2876@@ -202,7 +203,7 @@
2877 s.makeLocalMetadata(c, "1234", "region-2", "raring", "some-auth-url", "")
2878 ctx := coretesting.Context(c)
2879 code := cmd.Main(
2880- &ValidateImageMetadataCommand{}, ctx, []string{
2881+ envcmd.Wrap(&ValidateImageMetadataCommand{}), ctx, []string{
2882 "-p", "openstack", "-s", "raring", "-r", "region-2",
2883 "-u", "some-auth-url", "-d", s.metadataDir},
2884 )
2885@@ -218,7 +219,7 @@
2886 s.makeLocalMetadata(c, "1234", "region-2", "raring", "some-auth-url", "")
2887 ctx := coretesting.Context(c)
2888 code := cmd.Main(
2889- &ValidateImageMetadataCommand{}, ctx, []string{
2890+ envcmd.Wrap(&ValidateImageMetadataCommand{}), ctx, []string{
2891 "-p", "openstack", "-s", "precise", "-r", "region-2",
2892 "-u", "some-auth-url", "-d", s.metadataDir},
2893 )
2894@@ -227,7 +228,7 @@
2895 strippedOut := strings.Replace(errOut, "\n", "", -1)
2896 c.Check(strippedOut, gc.Matches, `.*Resolve Metadata:.*`)
2897 code = cmd.Main(
2898- &ValidateImageMetadataCommand{}, ctx, []string{
2899+ envcmd.Wrap(&ValidateImageMetadataCommand{}), ctx, []string{
2900 "-p", "openstack", "-s", "raring", "-r", "region-3",
2901 "-u", "some-auth-url", "-d", s.metadataDir},
2902 )
2903
2904=== modified file 'cmd/plugins/juju-metadata/validatetoolsmetadata.go'
2905--- cmd/plugins/juju-metadata/validatetoolsmetadata.go 2014-05-09 13:24:50 +0000
2906+++ cmd/plugins/juju-metadata/validatetoolsmetadata.go 2014-05-12 11:08:32 +0000
2907@@ -103,7 +103,6 @@
2908 }
2909
2910 func (c *ValidateToolsMetadataCommand) SetFlags(f *gnuflag.FlagSet) {
2911- c.EnvCommandBase.SetFlags(f)
2912 c.out.AddFlags(f, "smart", cmd.DefaultFormatters)
2913 f.StringVar(&c.providerType, "p", "", "the provider type eg ec2, openstack")
2914 f.StringVar(&c.metadataDir, "d", "", "directory where metadata files are found")
2915@@ -118,9 +117,6 @@
2916 }
2917
2918 func (c *ValidateToolsMetadataCommand) Init(args []string) error {
2919- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
2920- return err
2921- }
2922 if c.providerType != "" {
2923 if c.region == "" {
2924 return fmt.Errorf("region required if provider type is specified")
2925
2926=== modified file 'cmd/plugins/juju-metadata/validatetoolsmetadata_test.go'
2927--- cmd/plugins/juju-metadata/validatetoolsmetadata_test.go 2014-03-18 15:43:41 +0000
2928+++ cmd/plugins/juju-metadata/validatetoolsmetadata_test.go 2014-05-12 11:08:32 +0000
2929@@ -11,6 +11,7 @@
2930 gc "launchpad.net/gocheck"
2931
2932 "launchpad.net/juju-core/cmd"
2933+ "launchpad.net/juju-core/cmd/envcmd"
2934 "launchpad.net/juju-core/environs/filestorage"
2935 "launchpad.net/juju-core/environs/tools"
2936 coretesting "launchpad.net/juju-core/testing"
2937@@ -27,7 +28,7 @@
2938 var _ = gc.Suite(&ValidateToolsMetadataSuite{})
2939
2940 func runValidateToolsMetadata(c *gc.C, args ...string) error {
2941- _, err := coretesting.RunCommand(c, &ValidateToolsMetadataCommand{}, args)
2942+ _, err := coretesting.RunCommand(c, envcmd.Wrap(&ValidateToolsMetadataCommand{}), args)
2943 return err
2944 }
2945
2946@@ -56,7 +57,7 @@
2947 func (s *ValidateToolsMetadataSuite) TestInitErrors(c *gc.C) {
2948 for i, t := range validateInitToolsErrorTests {
2949 c.Logf("test %d", i)
2950- err := coretesting.InitCommand(&ValidateToolsMetadataCommand{}, t.args)
2951+ err := coretesting.InitCommand(envcmd.Wrap(&ValidateToolsMetadataCommand{}), t.args)
2952 c.Check(err, gc.ErrorMatches, t.err)
2953 }
2954 }
2955@@ -112,7 +113,7 @@
2956 s.setupEc2LocalMetadata(c, "us-east-1")
2957 ctx := coretesting.Context(c)
2958 code := cmd.Main(
2959- &ValidateToolsMetadataCommand{}, ctx, []string{"-e", "ec2", "-j", "1.11.4", "-d", s.metadataDir},
2960+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{"-e", "ec2", "-j", "1.11.4", "-d", s.metadataDir},
2961 )
2962 c.Assert(code, gc.Equals, 0)
2963 errOut := ctx.Stdout.(*bytes.Buffer).String()
2964@@ -126,7 +127,7 @@
2965 s.setupEc2LocalMetadata(c, "us-east-1")
2966 ctx := coretesting.Context(c)
2967 code := cmd.Main(
2968- &ValidateToolsMetadataCommand{}, ctx, []string{"-e", "ec2", "-j", "1.11.4"},
2969+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{"-e", "ec2", "-j", "1.11.4"},
2970 )
2971 c.Assert(code, gc.Equals, 1)
2972 errOut := ctx.Stderr.(*bytes.Buffer).String()
2973@@ -138,7 +139,7 @@
2974 s.setupEc2LocalMetadata(c, "us-west-1")
2975 ctx := coretesting.Context(c)
2976 code := cmd.Main(
2977- &ValidateToolsMetadataCommand{}, ctx, []string{
2978+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{
2979 "-p", "ec2", "-s", "precise", "-r", "us-west-1", "-j", "1.11.4",
2980 "-u", "https://ec2.us-west-1.amazonaws.com", "-d", s.metadataDir},
2981 )
2982@@ -152,13 +153,13 @@
2983 s.setupEc2LocalMetadata(c, "us-east-1")
2984 ctx := coretesting.Context(c)
2985 code := cmd.Main(
2986- &ValidateToolsMetadataCommand{}, ctx, []string{
2987+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{
2988 "-p", "ec2", "-s", "raring", "-r", "us-west-1",
2989 "-u", "https://ec2.us-west-1.amazonaws.com", "-d", s.metadataDir},
2990 )
2991 c.Assert(code, gc.Equals, 1)
2992 code = cmd.Main(
2993- &ValidateToolsMetadataCommand{}, ctx, []string{
2994+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{
2995 "-p", "ec2", "-s", "precise", "-r", "region",
2996 "-u", "https://ec2.region.amazonaws.com", "-d", s.metadataDir},
2997 )
2998@@ -172,7 +173,7 @@
2999 s.makeLocalMetadata(c, "1.11.4", "region-2", "raring", "some-auth-url")
3000 ctx := coretesting.Context(c)
3001 code := cmd.Main(
3002- &ValidateToolsMetadataCommand{}, ctx, []string{
3003+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{
3004 "-p", "openstack", "-s", "raring", "-r", "region-2", "-j", "1.11.4",
3005 "-u", "some-auth-url", "-d", s.metadataDir},
3006 )
3007@@ -186,13 +187,13 @@
3008 s.makeLocalMetadata(c, "1.11.4", "region-2", "raring", "some-auth-url")
3009 ctx := coretesting.Context(c)
3010 code := cmd.Main(
3011- &ValidateToolsMetadataCommand{}, ctx, []string{
3012+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{
3013 "-p", "openstack", "-s", "precise", "-r", "region-2",
3014 "-u", "some-auth-url", "-d", s.metadataDir},
3015 )
3016 c.Assert(code, gc.Equals, 1)
3017 code = cmd.Main(
3018- &ValidateToolsMetadataCommand{}, ctx, []string{
3019+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{
3020 "-p", "openstack", "-s", "raring", "-r", "region-3",
3021 "-u", "some-auth-url", "-d", s.metadataDir},
3022 )
3023@@ -206,7 +207,7 @@
3024 s.makeLocalMetadata(c, version.Current.Number.String(), "region-2", "raring", "some-auth-url")
3025 ctx := coretesting.Context(c)
3026 code := cmd.Main(
3027- &ValidateToolsMetadataCommand{}, ctx, []string{
3028+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{
3029 "-p", "openstack", "-s", "raring", "-r", "region-2",
3030 "-u", "some-auth-url", "-d", s.metadataDir},
3031 )
3032@@ -220,7 +221,7 @@
3033 s.makeLocalMetadata(c, "1.11.4", "region-2", "raring", "some-auth-url")
3034 ctx := coretesting.Context(c)
3035 code := cmd.Main(
3036- &ValidateToolsMetadataCommand{}, ctx, []string{
3037+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{
3038 "-p", "openstack", "-s", "raring", "-r", "region-2",
3039 "-u", "some-auth-url", "-d", s.metadataDir, "-m", "1"},
3040 )
3041@@ -234,7 +235,7 @@
3042 s.makeLocalMetadata(c, "1.12.1", "region-2", "raring", "some-auth-url")
3043 ctx := coretesting.Context(c)
3044 code := cmd.Main(
3045- &ValidateToolsMetadataCommand{}, ctx, []string{
3046+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{
3047 "-p", "openstack", "-s", "raring", "-r", "region-2",
3048 "-u", "some-auth-url", "-d", s.metadataDir, "-m", "1.12"},
3049 )
3050@@ -248,7 +249,7 @@
3051 s.makeLocalMetadata(c, version.Current.Number.String(), "region-2", "raring", "some-auth-url")
3052 ctx := coretesting.Context(c)
3053 code := cmd.Main(
3054- &ValidateToolsMetadataCommand{}, ctx, []string{"-s", "raring", "-d", s.metadataDir},
3055+ envcmd.Wrap(&ValidateToolsMetadataCommand{}), ctx, []string{"-s", "raring", "-d", s.metadataDir},
3056 )
3057 c.Assert(code, gc.Equals, 0)
3058 errOut := ctx.Stdout.(*bytes.Buffer).String()
3059
3060=== modified file 'cmd/plugins/juju-restore/restore.go'
3061--- cmd/plugins/juju-restore/restore.go 2014-05-09 13:24:50 +0000
3062+++ cmd/plugins/juju-restore/restore.go 2014-05-12 11:08:32 +0000
3063@@ -48,7 +48,7 @@
3064 fmt.Fprintf(os.Stderr, "error: %s\n", err)
3065 os.Exit(2)
3066 }
3067- os.Exit(cmd.Main(&restoreCommand{}, ctx, args[1:]))
3068+ os.Exit(cmd.Main(envcmd.Wrap(&restoreCommand{}), ctx, args[1:]))
3069 }
3070
3071 var logger = loggo.GetLogger("juju.plugins.restore")
3072@@ -82,16 +82,12 @@
3073 }
3074
3075 func (c *restoreCommand) SetFlags(f *gnuflag.FlagSet) {
3076- c.EnvCommandBase.SetFlags(f)
3077 f.Var(constraints.ConstraintsValue{Target: &c.Constraints}, "constraints", "set environment constraints")
3078 f.BoolVar(&c.showDescription, "description", false, "show the purpose of this plugin")
3079 c.Log.AddFlags(f)
3080 }
3081
3082 func (c *restoreCommand) Init(args []string) error {
3083- if err := c.EnvCommandBase.EnsureEnvName(); err != nil {
3084- return err
3085- }
3086 if c.showDescription {
3087 return cmd.CheckEmpty(args)
3088 }

Subscribers

People subscribed via source and target branches

to status/vote changes: