1// Copyright 2012 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package main 6 7import ( 8 "flag" 9 "fmt" 10 "os" 11 "strconv" 12) 13 14// cmdtab records the available commands. 15var cmdtab = []struct { 16 name string 17 f func() 18}{ 19 {"banner", cmdbanner}, 20 {"bootstrap", cmdbootstrap}, 21 {"clean", cmdclean}, 22 {"env", cmdenv}, 23 {"install", cmdinstall}, 24 {"list", cmdlist}, 25 {"test", cmdtest}, 26 {"version", cmdversion}, 27} 28 29// The OS-specific main calls into the portable code here. 30func xmain() { 31 if len(os.Args) < 2 { 32 usage() 33 } 34 cmd := os.Args[1] 35 os.Args = os.Args[1:] // for flag parsing during cmd 36 for _, ct := range cmdtab { 37 if ct.name == cmd { 38 flag.Usage = func() { 39 fmt.Fprintf(os.Stderr, "usage: go tool dist %s [options]\n", cmd) 40 flag.PrintDefaults() 41 os.Exit(2) 42 } 43 ct.f() 44 return 45 } 46 } 47 48 xprintf("unknown command %s\n", cmd) 49 usage() 50} 51 52func xflagparse(maxargs int) { 53 flag.Var((*count)(&vflag), "v", "verbosity") 54 flag.Parse() 55 if maxargs >= 0 && flag.NArg() > maxargs { 56 flag.Usage() 57 } 58} 59 60// count is a flag.Value that is like a flag.Bool and a flag.Int. 61// If used as -name, it increments the count, but -name=x sets the count. 62// Used for verbose flag -v. 63type count int 64 65func (c *count) String() string { 66 return fmt.Sprint(int(*c)) 67} 68 69func (c *count) Set(s string) error { 70 switch s { 71 case "true": 72 *c++ 73 case "false": 74 *c = 0 75 default: 76 n, err := strconv.Atoi(s) 77 if err != nil { 78 return fmt.Errorf("invalid count %q", s) 79 } 80 *c = count(n) 81 } 82 return nil 83} 84 85func (c *count) IsBoolFlag() bool { 86 return true 87} 88