Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(649)

Delta Between Two Patch Sets: cmd/command.go

Issue 5901058: cmd/juju: working bootstrap and destroy commands
Left Patch Set: cmd/juju: working bootstrap and destroy commands Created 13 years ago
Right Patch Set: cmd/juju: working bootstrap and destroy commands Created 12 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « [revision details] ('k') | cmd/context.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 package cmd 1 package cmd
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "launchpad.net/gnuflag" 5 "launchpad.net/gnuflag"
6 "launchpad.net/juju/go/log"
7 "os"
8 "strings"
9 ) 6 )
10 7
11 // Info holds everything necessary to describe a Command's intent and usage. 8 // Info holds everything necessary to describe a Command's intent and usage.
12 type Info struct { 9 type Info struct {
13 // Name is the Command's name. 10 // Name is the Command's name.
14 Name string 11 Name string
15 12
16 // Args describes the command's expected arguments. 13 // Args describes the command's expected arguments.
17 Args string 14 Args string
18 15
19 // Purpose is a short explanation of the Command's purpose. 16 // Purpose is a short explanation of the Command's purpose.
20 Purpose string 17 Purpose string
21 18
22 // Doc is the long documentation for the Command. 19 // Doc is the long documentation for the Command.
23 Doc string 20 Doc string
24
25 // Intersperse controls whether the Command will accept interspersed
26 // options and positional args.
27 Intersperse bool
28 } 21 }
29 22
30 // Usage combines Name and Args to describe the Command's intended usage. 23 // Usage combines Name and Args to describe the Command's intended usage.
31 func (i *Info) Usage() string { 24 func (i *Info) Usage() string {
25 if i.Args == "" {
26 return i.Name
27 }
32 return fmt.Sprintf("%s %s", i.Name, i.Args) 28 return fmt.Sprintf("%s %s", i.Name, i.Args)
33 } 29 }
34 30
35 // Command is implemented by types that interpret any command-line arguments 31 // Command is implemented by types that interpret command-line arguments.
36 // passed to the "juju" command.
37 type Command interface { 32 type Command interface {
38 » // Info returns information about the command. 33 » // Info returns information about the Command.
39 Info() *Info 34 Info() *Info
40 35
41 » // InitFlagSet prepares a FlagSet such that Parsing that FlagSet will 36 » // Init initializes the Command before running. The command may add opti ons
42 » // initialize the Command's options. 37 » // to f before processing args.
43 » InitFlagSet(f *gnuflag.FlagSet) 38 » Init(f *gnuflag.FlagSet, args []string) error
44 39
45 » // ParsePositional is called by Parse to allow the Command to handle 40 » // Run will execute the Command as directed by the options and positiona l
46 » // positional command-line arguments. 41 » // arguments passed to Init.
47 » ParsePositional(args []string) error 42 » Run(ctx *Context) error
48
49 » // Run will execute the command according to the options and positional
50 » // arguments interpreted by a call to Parse.
51 » Run() error
52 }
53
54 // NewFlagSet returns a FlagSet initialized for use with c.
55 func NewFlagSet(c Command) *gnuflag.FlagSet {
56 » f := gnuflag.NewFlagSet(c.Info().Name, gnuflag.ExitOnError)
57 » f.Usage = func() { PrintUsage(c) }
58 » c.InitFlagSet(f)
59 » return f
60 }
61
62 // PrintUsage prints usage information for c to stderr.
63 func PrintUsage(c Command) {
64 » i := c.Info()
65 » fmt.Fprintf(os.Stderr, "usage: %s\n", i.Usage())
66 » fmt.Fprintf(os.Stderr, "purpose: %s\n", i.Purpose)
67 » fmt.Fprintf(os.Stderr, "\noptions:\n")
68 » NewFlagSet(c).PrintDefaults()
69 » if i.Doc != "" {
70 » » fmt.Fprintf(os.Stderr, "\n%s\n", strings.TrimSpace(i.Doc))
71 » }
72 }
73
74 // Parse parses args on c. This must be called before c is Run.
75 func Parse(c Command, args []string) error {
76 » f := NewFlagSet(c)
77 » if err := f.Parse(c.Info().Intersperse, args); err != nil {
78 » » return err
79 » }
80 » return c.ParsePositional(f.Args())
81 } 43 }
82 44
83 // CheckEmpty is a utility function that returns an error if args is not empty. 45 // CheckEmpty is a utility function that returns an error if args is not empty.
84 func CheckEmpty(args []string) error { 46 func CheckEmpty(args []string) error {
85 if len(args) != 0 { 47 if len(args) != 0 {
86 return fmt.Errorf("unrecognised args: %s", args) 48 return fmt.Errorf("unrecognised args: %s", args)
87 } 49 }
88 return nil 50 return nil
89 } 51 }
90
91 // Main will Parse and Run a Command, and exit appropriately.
92 func Main(c Command, args []string) {
93 if err := Parse(c, args[1:]); err != nil {
94 fmt.Fprintf(os.Stderr, "%v\n", err)
95 PrintUsage(c)
96 os.Exit(2)
97 }
98 if err := c.Run(); err != nil {
99 log.Debugf("%s command failed: %s\n", c.Info().Name, err)
100 fmt.Fprintf(os.Stderr, "%v\n", err)
101 os.Exit(1)
102 }
103 os.Exit(0)
104 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b