github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/src/cmd/dist/main.go (about) 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 5 package main 6 7 import ( 8 "flag" 9 "fmt" 10 "os" 11 "strconv" 12 ) 13 14 // cmdtab records the available commands. 15 var 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. 30 func 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 52 func 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. 63 type count int 64 65 func (c *count) String() string { 66 return fmt.Sprint(int(*c)) 67 } 68 69 func (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 85 func (c *count) IsBoolFlag() bool { 86 return true 87 }