github.com/creachadair/vocab@v0.0.4-0.20190826174139-2654f99cba48/example_test.go (about) 1 package vocab_test 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "os" 8 "strings" 9 10 "bitbucket.org/creachadair/shell" 11 "github.com/creachadair/vocab" 12 ) 13 14 func Example() { 15 v, err := vocab.New("tool", &tool{ 16 WorkDir: "/tmp", 17 }) 18 if err != nil { 19 log.Fatalf("New failed: %v", err) 20 } 21 v.SetOutput(os.Stdout) // default is os.Stderr 22 23 ctx := context.Background() 24 for _, cmd := range []string{ 25 "", // simple help, short form 26 "help", // global help, long form 27 "help file", // group help 28 "help file ls", // subcommand help 29 "file list", // execute 30 31 "-workdir /var/log file list", // global flags 32 "file list -a", // local flags 33 34 `text echo "all your base" are "belong to us"`, 35 } { 36 args, _ := shell.Split(cmd) 37 fmt.Printf("------ %q\n", args) 38 if err := v.Dispatch(ctx, args); err != nil { 39 log.Fatalf("ERROR: %q: %v", cmd, err) 40 } 41 } 42 // Output: 43 // ------ [] 44 // tool: A trivial command-line shell 45 // 46 // Subcommands: 47 // file Subcommands pertaining to files (alias: files) 48 // help Show help for a command (alias: wtf) 49 // text Subcommands pertaining to text 50 // ------ ["help"] 51 // tool: A trivial command-line shell 52 // 53 // Demonstrate the use of the vocab package by wiring up 54 // a simple command-line with nested commands. 55 // 56 // Flags: 57 // -workdir string 58 // Set working directory to this path (default "/tmp") 59 // 60 // Subcommands: 61 // file Subcommands pertaining to files (alias: files) 62 // help Show help for a command (alias: wtf) 63 // text Subcommands pertaining to text 64 // ------ ["help" "file"] 65 // file: Subcommands pertaining to files 66 // 67 // Subcommands: 68 // ls List file metadata (alias: dir, list) 69 // ------ ["help" "file" "ls"] 70 // ls: List file metadata 71 // 72 // Flags: 73 // -a List all files, including dotfiles 74 // ------ ["file" "list"] 75 // src 76 // docs 77 // ------ ["-workdir" "/var/log" "file" "list"] 78 // src 79 // docs 80 // ------ ["file" "list" "-a"] 81 // .config 82 // src 83 // docs 84 // ------ ["text" "echo" "all your base" "are" "belong to us"] 85 // all your base are belong to us 86 } 87 88 type list struct { 89 All bool `flag:"a,List all files, including dotfiles"` 90 } 91 92 func (ls list) Run(ctx context.Context, args []string) error { 93 if ls.All { 94 fmt.Println(".config") 95 } 96 fmt.Println("src") 97 fmt.Println("docs") 98 return nil 99 } 100 101 type echo struct{} 102 103 func (echo) Run(ctx context.Context, args []string) error { 104 fmt.Println(strings.Join(args, " ")) 105 return nil 106 } 107 108 type tool struct { 109 WorkDir string `flag:"workdir,Set working directory to this path"` 110 111 // tool files ls <path> ... 112 Files struct { 113 List list `vocab:"ls,list,dir" help-summary:"List file metadata"` 114 115 _ struct{} `help-summary:"Subcommands pertaining to files"` 116 } `vocab:"file,files"` 117 118 // tool text echo <args> ... 119 Text struct { 120 Echo echo `vocab:"echo,print,type" help-summary:"Concatenate and print arguments"` 121 122 _ struct{} `help-summary:"Subcommands pertaining to text"` 123 } `vocab:"text"` 124 125 // tool help [command] 126 Help vocab.Help `vocab:"help,wtf"` 127 128 _ struct{} `help-summary:"A trivial command-line shell"` 129 _ struct{} `help-long:"Demonstrate the use of the vocab package by wiring up\na simple command-line with nested commands."` 130 } 131 132 var _ vocab.Initializer = (*tool)(nil) 133 134 // Init sets up the context for subcommands run via t. In this case, it ensures 135 // the specified working directory exists and that $PWD points to it. 136 func (t tool) Init(ctx context.Context, name string, args []string) (context.Context, error) { 137 if err := os.MkdirAll(t.WorkDir, 0755); err != nil { 138 return nil, err 139 } 140 return ctx, os.Chdir(t.WorkDir) 141 }