gopkg.in/tools/godep.v56@v56.0.0-20160226230103-b32db8cfcaad/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 log.SetFlags(0) 92 log.SetPrefix("godep: ") 93 log.SetOutput(os.Stderr) 94 95 flag.Usage = usageExit 96 flag.Parse() 97 args := flag.Args() 98 if len(args) < 1 { 99 usageExit() 100 } 101 102 if args[0] == "help" { 103 help(args[1:]) 104 return 105 } 106 107 var err error 108 majorGoVersion, err = goVersion() 109 if err != nil { 110 log.Fatal(err) 111 } 112 113 VendorExperiment = determineVendor(majorGoVersion) 114 115 // sep is the signature set of path elements that 116 // precede the original path of an imported package. 117 sep = defaultSep(VendorExperiment) 118 119 for _, cmd := range commands { 120 if cmd.Name == args[0] { 121 cmd.Flag.BoolVar(&verbose, "v", false, "enable verbose output") 122 cmd.Flag.BoolVar(&debug, "d", false, "enable debug output") 123 cmd.Flag.StringVar(&cpuprofile, "cpuprofile", "", "Write cpu profile to this file") 124 cmd.Flag.Usage = func() { cmd.UsageExit() } 125 cmd.Flag.Parse(args[1:]) 126 127 debugln("versionString()", versionString()) 128 debugln("majorGoVersion", majorGoVersion) 129 debugln("VendorExperiment", VendorExperiment) 130 debugln("sep", sep) 131 132 if cpuprofile != "" { 133 f, err := os.Create(cpuprofile) 134 if err != nil { 135 log.Fatal(err) 136 } 137 pprof.StartCPUProfile(f) 138 defer pprof.StopCPUProfile() 139 } 140 cmd.Run(cmd, cmd.Flag.Args()) 141 return 142 } 143 } 144 145 fmt.Fprintf(os.Stderr, "godep: unknown command %q\n", args[0]) 146 fmt.Fprintf(os.Stderr, "Run 'godep help' for usage.\n") 147 os.Exit(2) 148 } 149 150 var usageTemplate = ` 151 Godep is a tool for managing Go package dependencies. 152 153 Usage: 154 155 godep command [arguments] 156 157 The commands are: 158 {{range .}} 159 {{.Name | printf "%-8s"}} {{.Short}}{{end}} 160 161 Use "godep help [command]" for more information about a command. 162 ` 163 164 var helpTemplate = ` 165 Args: godep {{.Name}} [-v] [-d] {{.Args}} 166 167 {{.Long | trim}} 168 169 If -v is given, verbose output is enabled. 170 171 If -d is given, debug output is enabled (you probably don't want this, see -v). 172 173 ` 174 175 func help(args []string) { 176 if len(args) == 0 { 177 printUsage(os.Stdout) 178 return 179 } 180 if len(args) != 1 { 181 fmt.Fprintf(os.Stderr, "usage: godep help command\n\n") 182 fmt.Fprintf(os.Stderr, "Too many arguments given.\n") 183 os.Exit(2) 184 } 185 for _, cmd := range commands { 186 if cmd.Name == args[0] { 187 tmpl(os.Stdout, helpTemplate, cmd) 188 return 189 } 190 } 191 } 192 193 func usageExit() { 194 printUsage(os.Stderr) 195 os.Exit(2) 196 } 197 198 func printUsage(w io.Writer) { 199 tmpl(w, usageTemplate, commands) 200 } 201 202 // tmpl executes the given template text on data, writing the result to w. 203 func tmpl(w io.Writer, text string, data interface{}) { 204 t := template.New("top") 205 t.Funcs(template.FuncMap{ 206 "trim": strings.TrimSpace, 207 }) 208 template.Must(t.Parse(strings.TrimSpace(text) + "\n\n")) 209 if err := t.Execute(w, data); err != nil { 210 panic(err) 211 } 212 }