gopkg.in/tools/godep.v54@v54.0.0-20160222173036-53bf4cf4341d/main.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "io" 7 "log" 8 "os" 9 "path/filepath" 10 "runtime/pprof" 11 "strings" 12 "text/template" 13 ) 14 15 var ( 16 cpuprofile string 17 verbose bool // Verbose flag for commands that support it 18 debug bool // Debug flag for commands that support it 19 majorGoVersion string 20 VendorExperiment bool 21 sep string 22 ) 23 24 // Command is an implementation of a godep command 25 // like godep save or godep go. 26 type Command struct { 27 // Run runs the command. 28 // The args are the arguments after the command name. 29 Run func(cmd *Command, args []string) 30 31 // Name of the command 32 Name string 33 34 // Args the command would expect 35 Args string 36 37 // Short is the short description shown in the 'godep help' output. 38 Short string 39 40 // Long is the long message shown in the 41 // 'godep help <this-command>' output. 42 Long string 43 44 // Flag is a set of flags specific to this command. 45 Flag flag.FlagSet 46 } 47 48 // UsageExit prints usage information and exits. 49 func (c *Command) UsageExit() { 50 fmt.Fprintf(os.Stderr, "Args: godep %s [-v] [-d] %s\n\n", c.Name, c.Args) 51 fmt.Fprintf(os.Stderr, "Run 'godep help %s' for help.\n", c.Name) 52 os.Exit(2) 53 } 54 55 // Commands lists the available commands and help topics. 56 // The order here is the order in which they are printed 57 // by 'godep help'. 58 var commands = []*Command{ 59 cmdSave, 60 cmdGo, 61 cmdGet, 62 cmdPath, 63 cmdRestore, 64 cmdUpdate, 65 cmdDiff, 66 cmdVersion, 67 } 68 69 // VendorExperiment is the Go 1.5 vendor directory experiment flag, see 70 // https://github.com/golang/go/commit/183cc0cd41f06f83cb7a2490a499e3f9101befff 71 // Honor the env var unless the project already has an old school godep workspace 72 func determineVendor(v string) bool { 73 go15ve := os.Getenv("GO15VENDOREXPERIMENT") 74 ev := (v == "go1.5" && go15ve == "1") || 75 (v == "go1.6" && go15ve != "0") || 76 (v == "devel" && go15ve != "0") 77 78 ws := filepath.Join("Godeps", "_workspace") 79 s, err := os.Stat(ws) 80 if err == nil && s.IsDir() { 81 if ev { 82 log.Printf("WARNING: Go version (%s) & $GO15VENDOREXPERIMENT=%s wants to enable the vendor experiment, but disabling because a Godep workspace (%s) exists\n", v, go15ve, ws) 83 } 84 return false 85 } 86 87 return ev 88 } 89 90 func main() { 91 flag.Usage = usageExit 92 flag.Parse() 93 log.SetFlags(0) 94 log.SetPrefix("godep: ") 95 args := flag.Args() 96 if len(args) < 1 { 97 usageExit() 98 } 99 100 if args[0] == "help" { 101 help(args[1:]) 102 return 103 } 104 105 var err error 106 majorGoVersion, err = goVersion() 107 if err != nil { 108 log.Fatal(err) 109 } 110 111 VendorExperiment = determineVendor(majorGoVersion) 112 113 // sep is the signature set of path elements that 114 // precede the original path of an imported package. 115 sep = defaultSep(VendorExperiment) 116 117 for _, cmd := range commands { 118 if cmd.Name == args[0] { 119 cmd.Flag.BoolVar(&verbose, "v", false, "enable verbose output") 120 cmd.Flag.BoolVar(&debug, "d", false, "enable debug output") 121 cmd.Flag.StringVar(&cpuprofile, "cpuprofile", "", "Write cpu profile to this file") 122 cmd.Flag.Usage = func() { cmd.UsageExit() } 123 cmd.Flag.Parse(args[1:]) 124 125 debugln("majorGoVersion", majorGoVersion) 126 debugln("VendorExperiment", VendorExperiment) 127 debugln("sep", sep) 128 129 if cpuprofile != "" { 130 f, err := os.Create(cpuprofile) 131 if err != nil { 132 log.Fatal(err) 133 } 134 pprof.StartCPUProfile(f) 135 defer pprof.StopCPUProfile() 136 } 137 cmd.Run(cmd, cmd.Flag.Args()) 138 return 139 } 140 } 141 142 fmt.Fprintf(os.Stderr, "godep: unknown command %q\n", args[0]) 143 fmt.Fprintf(os.Stderr, "Run 'godep help' for usage.\n") 144 os.Exit(2) 145 } 146 147 var usageTemplate = ` 148 Godep is a tool for managing Go package dependencies. 149 150 Usage: 151 152 godep command [arguments] 153 154 The commands are: 155 {{range .}} 156 {{.Name | printf "%-8s"}} {{.Short}}{{end}} 157 158 Use "godep help [command]" for more information about a command. 159 ` 160 161 var helpTemplate = ` 162 Args: godep {{.Name}} [-v] [-d] {{.Args}} 163 164 {{.Long | trim}} 165 166 If -v is given, verbose output is enabled. 167 168 If -d is given, debug output is enabled (you probably don't want this, see -v). 169 170 ` 171 172 func help(args []string) { 173 if len(args) == 0 { 174 printUsage(os.Stdout) 175 return 176 } 177 if len(args) != 1 { 178 fmt.Fprintf(os.Stderr, "usage: godep help command\n\n") 179 fmt.Fprintf(os.Stderr, "Too many arguments given.\n") 180 os.Exit(2) 181 } 182 for _, cmd := range commands { 183 if cmd.Name == args[0] { 184 tmpl(os.Stdout, helpTemplate, cmd) 185 return 186 } 187 } 188 } 189 190 func usageExit() { 191 printUsage(os.Stderr) 192 os.Exit(2) 193 } 194 195 func printUsage(w io.Writer) { 196 tmpl(w, usageTemplate, commands) 197 } 198 199 // tmpl executes the given template text on data, writing the result to w. 200 func tmpl(w io.Writer, text string, data interface{}) { 201 t := template.New("top") 202 t.Funcs(template.FuncMap{ 203 "trim": strings.TrimSpace, 204 }) 205 template.Must(t.Parse(strings.TrimSpace(text) + "\n\n")) 206 if err := t.Execute(w, data); err != nil { 207 panic(err) 208 } 209 }