github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/commands/helptool.go (about) 1 // Copyright 2013, 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package commands 5 6 import ( 7 "fmt" 8 "time" 9 10 "github.com/juju/cmd" 11 "github.com/juju/errors" 12 "github.com/juju/gnuflag" 13 "gopkg.in/juju/charm.v6-unstable" 14 15 "github.com/juju/juju/network" 16 "github.com/juju/juju/storage" 17 "github.com/juju/juju/worker/uniter/runner/jujuc" 18 ) 19 20 // dummyHookContext implements jujuc.Context, 21 // as expected by jujuc.NewCommand. 22 type dummyHookContext struct{ jujuc.Context } 23 24 func (dummyHookContext) AddMetrics(_, _ string, _ time.Time) error { 25 return nil 26 } 27 func (dummyHookContext) UnitName() string { 28 return "" 29 } 30 func (dummyHookContext) PublicAddress() (string, error) { 31 return "", errors.NotFoundf("PublicAddress") 32 } 33 func (dummyHookContext) PrivateAddress() (string, error) { 34 return "", errors.NotFoundf("PrivateAddress") 35 } 36 func (dummyHookContext) AvailabilityZone() (string, error) { 37 return "", errors.NotFoundf("AvailabilityZone") 38 } 39 func (dummyHookContext) OpenPort(protocol string, port int) error { 40 return nil 41 } 42 func (dummyHookContext) ClosePort(protocol string, port int) error { 43 return nil 44 } 45 func (dummyHookContext) OpenedPorts() []network.PortRange { 46 return nil 47 } 48 func (dummyHookContext) ConfigSettings() (charm.Settings, error) { 49 return charm.NewConfig().DefaultSettings(), nil 50 } 51 func (dummyHookContext) HookRelation() (jujuc.ContextRelation, error) { 52 return nil, errors.NotFoundf("HookRelation") 53 } 54 func (dummyHookContext) RemoteUnitName() (string, error) { 55 return "", errors.NotFoundf("RemoteUnitName") 56 } 57 func (dummyHookContext) Relation(id int) (jujuc.ContextRelation, error) { 58 return nil, errors.NotFoundf("Relation") 59 } 60 func (dummyHookContext) RelationIds() ([]int, error) { 61 return []int{}, errors.NotFoundf("RelationIds") 62 } 63 64 func (dummyHookContext) RequestReboot(prio jujuc.RebootPriority) error { 65 return nil 66 } 67 68 func (dummyHookContext) HookStorageInstance() (*storage.StorageInstance, error) { 69 return nil, errors.NotFoundf("HookStorageInstance") 70 } 71 72 func (dummyHookContext) HookStorage() (jujuc.ContextStorageAttachment, error) { 73 return nil, errors.NotFoundf("HookStorage") 74 } 75 76 func (dummyHookContext) StorageInstance(id string) (*storage.StorageInstance, error) { 77 return nil, errors.NotFoundf("StorageInstance") 78 } 79 80 func (dummyHookContext) UnitStatus() (*jujuc.StatusInfo, error) { 81 return &jujuc.StatusInfo{}, nil 82 } 83 84 func (dummyHookContext) SetStatus(jujuc.StatusInfo) error { 85 return nil 86 } 87 88 func (dummyHookContext) Component(name string) (jujuc.ContextComponent, error) { 89 return nil, nil 90 } 91 92 func newHelpToolCommand() cmd.Command { 93 return &helpToolCommand{} 94 } 95 96 type helpToolCommand struct { 97 cmd.CommandBase 98 tool string 99 } 100 101 func (t *helpToolCommand) Info() *cmd.Info { 102 return &cmd.Info{ 103 Name: "help-tool", 104 Args: "[tool]", 105 Purpose: "Show help on a Juju charm tool.", 106 } 107 } 108 109 func (t *helpToolCommand) Init(args []string) error { 110 tool, err := cmd.ZeroOrOneArgs(args) 111 if err == nil { 112 t.tool = tool 113 } 114 return err 115 } 116 117 func (c *helpToolCommand) Run(ctx *cmd.Context) error { 118 var hookctx dummyHookContext 119 if c.tool == "" { 120 // Ripped from SuperCommand. We could Run() a SuperCommand 121 // with "help commands", but then the implicit "help" command 122 // shows up. 123 names := jujuc.CommandNames() 124 cmds := make([]cmd.Command, 0, len(names)) 125 longest := 0 126 for _, name := range names { 127 if c, err := jujuc.NewCommand(hookctx, name); err == nil { 128 if len(name) > longest { 129 longest = len(name) 130 } 131 cmds = append(cmds, c) 132 } 133 } 134 for _, c := range cmds { 135 info := c.Info() 136 fmt.Fprintf(ctx.Stdout, "%-*s %s\n", longest, info.Name, info.Purpose) 137 } 138 } else { 139 c, err := jujuc.NewCommand(hookctx, c.tool) 140 if err != nil { 141 return err 142 } 143 info := c.Info() 144 f := gnuflag.NewFlagSet(info.Name, gnuflag.ContinueOnError) 145 c.SetFlags(f) 146 ctx.Stdout.Write(info.Help(f)) 147 } 148 return nil 149 }