├── README.md ├── README_CN.md ├── got.go ├── got_test.go ├── install.go └── list.go /README.md: -------------------------------------------------------------------------------- 1 | 2 | **Got is A binary install tool for Go executable package via gobuild.io.** 3 | 4 | ** Heavily development, contributings are welcome!** 5 | 6 | [中文版(Chinese)](https://github.com/lunny/got/blob/master/README_CN.md) 7 | 8 | # Why we need a binary install tool 9 | 10 | Since we have `go install`, do we need a binary install tool? I think YES, because I think we are BOTH consumer AND developer. When we decide to test or use some command, we just a consumer, why we need install git or hg, why we need download the source codes and build? Our requirement is only install and use it. 11 | 12 | So I make got. Let's got it. 13 | 14 | # Install 15 | 16 | You can download got from gobuild.io 17 | 18 | wget http://gobuild.io/github.com/lunny/got/master/darwin/amd64 -O output.zip 19 | unzip output.zip 20 | cp got /usr/local/bin/ 21 | 22 | or if you have installed go tool 23 | 24 | go get github.com/lunny/got 25 | 26 | # How to use 27 | 28 | Use got is simple, say we need gopm tool, then 29 | 30 | got github.com/gpmgo/gopm 31 | 32 | more simpler, for github.com go package we can ignore the domain name 33 | 34 | got gpmgo/gopm 35 | 36 | and then type `gopm help` 37 | 38 | # Well known Go Packages tested 39 | 40 | got dotcloud/docker/docker 41 | got nsf/gocode 42 | got beego/bee 43 | got gpmgo/gopm 44 | got go-xorm/cmd/xorm 45 | got revel/cmd/revel 46 | got cznic/ql/ql 47 | got go-xweb/xrun 48 | got bradfitz/goimports 49 | got mitchellh/gox 50 | got wendal/gor 51 | got laher/goxc 52 | got parkghost/gohttpbench 53 | got shxsun/fswatch 54 | got tools/godep 55 | got mattn/gom 56 | got codegangsta/gin 57 | got codeskyblue/gobuild 58 | got zachlatta/postman 59 | got coreos/etcd 60 | got hashicorp/serf 61 | got FiloSottile/Heartbleed 62 | got cyfdecyf/cow 63 | got apcera/gnatsd 64 | got shenfeng/http-watcher 65 | got nf/goplayer 66 | got piranha/goreplace 67 | got mtourne/gurl 68 | 69 | Wish you like. -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | 2 | **Got 是一个基于gobuild.io的Go二进制包管理工具** 3 | 4 | ** 当前正在紧张开发中,欢迎贡献代码** 5 | 6 | [English(英文版)](https://github.com/lunny/got/blob/master/README.md) 7 | 8 | # 为什么我们需要一个二进制的Go包管理工具 9 | 10 | 对于开发者,其实一直在使用`go install`,那我们还需要一个二进制的Go包管理工具吗?我认为需要。因为开发者也是使用者,当你在使用别人的成熟的工具时,并不需要去查看他的代码,更不需要为此而安装Go,安装git,hg,也不需要编译。这个时候开发者变成了使用者。 11 | 12 | 因此我基于gobuild.io创建了got。让我们开始吧。 13 | 14 | # 安装 15 | 16 | 你可以从gobuild.io获得 got: 17 | 18 | wget http://gobuild.io/github.com/lunny/got/master/darwin/amd64 -O output.zip 19 | unzip output.zip 20 | cp got /usr/local/bin/ 21 | 22 | 或者如果你有安装go的话,那么直接 23 | 24 | go get github.com/lunny/got 25 | 26 | # 如何使用 27 | 28 | 使用got非常简单,比如我们需要安装gopm,那么只需要 29 | 30 | got github.com/gpmgo/gopm 31 | 32 | 就好了,对于github.com的包还有更简单的方式,可以省去域名: 33 | 34 | got gpmgo/gopm 35 | 36 | 然后,就可以直接使用 `gopm help` 37 | 38 | # 已经经过测试的包如下,从此可以删除掉这些包对应的源码了。 39 | 40 | got dotcloud/docker/docker 41 | got nsf/gocode 42 | got beego/bee 43 | got gpmgo/gopm 44 | got go-xorm/cmd/xorm 45 | got revel/cmd/revel 46 | got cznic/ql/ql 47 | got go-xweb/xrun 48 | got bradfitz/goimports 49 | got mitchellh/gox 50 | got wendal/gor 51 | got laher/goxc 52 | got parkghost/gohttpbench 53 | got shxsun/fswatch 54 | got tools/godep 55 | got mattn/gom 56 | got codegangsta/gin 57 | got codeskyblue/gobuild 58 | got zachlatta/postman 59 | got coreos/etcd 60 | got hashicorp/serf 61 | got FiloSottile/Heartbleed 62 | got cyfdecyf/cow 63 | got apcera/gnatsd 64 | got shenfeng/http-watcher 65 | got nf/goplayer 66 | got piranha/goreplace 67 | got mtourne/gurl 68 | 69 | 希望大家喜欢。 -------------------------------------------------------------------------------- /got.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "archive/zip" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "runtime" 12 | "strings" 13 | ) 14 | 15 | const APP_VER = "0.1.0523" 16 | 17 | func init() { 18 | runtime.GOMAXPROCS(runtime.NumCPU()) 19 | } 20 | 21 | var ( 22 | verbore = flag.Bool("v", false, "show the detail info") 23 | ) 24 | 25 | var downTempl = "http://gobuild.io/%s/%s/%s/%s" 26 | 27 | func vPrintln(args ...interface{}) { 28 | if *verbore { 29 | fmt.Println(args...) 30 | } 31 | } 32 | 33 | func vPrintf(format string, args ...interface{}) { 34 | if *verbore { 35 | fmt.Printf(format, args...) 36 | } 37 | } 38 | 39 | func help() { 40 | /*fmt.Printf(`NAME: 41 | got - Go Binary Package Manager 42 | 43 | USAGE: 44 | got [global options] [command] [package path] [arguments...] 45 | 46 | VERSION: 47 | %s 48 | 49 | COMMANDS: 50 | list list all packages 51 | install download and install binary of package 52 | run install and run the command 53 | down download only 54 | rm remove package 55 | update update one package 56 | upgrade update self 57 | help Shows a list of commands or help for one command 58 | 59 | GLOBAL OPTIONS: 60 | -v print the version 61 | `, APP_VER)*/ 62 | fmt.Printf(`NAME: 63 | got - Go Binary Package Manager 64 | 65 | USAGE: 66 | got [global options] [command] [package path] [arguments...] 67 | 68 | VERSION: 69 | %s 70 | 71 | COMMANDS: 72 | list list all packages 73 | install download and install binary of package 74 | help Shows a list of commands or help for one command 75 | 76 | GLOBAL OPTIONS: 77 | -v print verbose detail 78 | `, APP_VER) 79 | } 80 | 81 | // exePath returns the executable path. 82 | func exePath() (string, error) { 83 | file, err := exec.LookPath(os.Args[0]) 84 | if err != nil { 85 | return "", err 86 | } 87 | return filepath.Abs(file) 88 | } 89 | 90 | func getPath() string { 91 | path := os.Getenv("PATH") 92 | gPath := os.Getenv("GOPATH") 93 | if gPath != "" { 94 | bin := filepath.Join(gPath, "bin") 95 | if strings.Contains(path, bin) { 96 | return bin 97 | } 98 | } 99 | 100 | rootPath := os.Getenv("GOROOT") 101 | if rootPath != "" { 102 | bin := filepath.Join(rootPath, "bin") 103 | if strings.Contains(path, bin) { 104 | return bin 105 | } 106 | } 107 | 108 | p, err := exePath() 109 | if err == nil { 110 | return filepath.Dir(p) 111 | } 112 | 113 | //TODO: where is the default binary path? 114 | if runtime.GOOS == "windows" { 115 | ret := "C:\\" 116 | return ret 117 | } 118 | return "/usr/local/bin" 119 | } 120 | 121 | func findPara(start int) int { 122 | if start >= len(os.Args) { 123 | return -1 124 | } 125 | 126 | for i := start; i < len(os.Args); i++ { 127 | if !strings.HasPrefix(os.Args[i], "-") { 128 | return i 129 | } 130 | } 131 | return -1 132 | } 133 | 134 | func unzip(dest, fPath string) error { 135 | r, err := zip.OpenReader(fPath) 136 | if err != nil { 137 | return err 138 | } 139 | defer r.Close() 140 | 141 | // Iterate through the files in the archive, 142 | // printing some of their contents. 143 | for _, f := range r.File { 144 | vPrintf("Extracting %s:\n", f.Name) 145 | rc, err := f.Open() 146 | if err != nil { 147 | return err 148 | } 149 | defer rc.Close() 150 | 151 | newPath := filepath.Join(dest, f.Name) 152 | os.MkdirAll(filepath.Dir(newPath), os.ModePerm) 153 | nf, err := os.OpenFile(newPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, f.Mode()) 154 | if err != nil { 155 | return err 156 | } 157 | defer nf.Close() 158 | 159 | _, err = io.Copy(nf, rc) 160 | if err != nil { 161 | return err 162 | } 163 | } 164 | return nil 165 | } 166 | 167 | func download() { 168 | 169 | } 170 | 171 | func remove() { 172 | 173 | } 174 | 175 | func update() { 176 | 177 | } 178 | 179 | func upgrade() { 180 | 181 | } 182 | 183 | func search() { 184 | 185 | } 186 | 187 | func main() { 188 | flag.Parse() 189 | 190 | l := len(os.Args) 191 | if l == 1 { 192 | help() 193 | return 194 | } 195 | 196 | idx := findPara(1) 197 | if idx == -1 { 198 | help() 199 | return 200 | } 201 | 202 | switch strings.ToLower(os.Args[idx]) { 203 | case "list": 204 | list() 205 | case "help": 206 | help() 207 | case "rm": 208 | remove() 209 | case "download": 210 | download() 211 | case "search": 212 | search() 213 | case "upgrade": 214 | upgrade() 215 | case "update": 216 | update() 217 | case "install": 218 | install() 219 | default: 220 | install() 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /got_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | var ( 6 | testPackages = []string{ 7 | "nsf/gocode", 8 | "beego/bee", 9 | "go-xorm/cmd/xorm", 10 | "gpmgo/gopm", 11 | "bradfitz/goimports", 12 | "mitchellh/gox", 13 | "wendal/gor", 14 | "cznic/ql/ql", 15 | } 16 | ) 17 | 18 | func TestGet(t *testing.T) { 19 | for _, p := range testPackages { 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /install.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "os" 8 | "path/filepath" 9 | "runtime" 10 | "strings" 11 | ) 12 | 13 | func install() { 14 | idx := findPara(1) 15 | if idx == -1 { 16 | fmt.Println("need a go package path") 17 | return 18 | } 19 | 20 | if os.Args[idx] == "install" { 21 | idx = findPara(idx + 1) 22 | } 23 | if idx == -1 { 24 | fmt.Println("need a go package path") 25 | return 26 | } 27 | 28 | var ver, pkgPath = "master", os.Args[idx] 29 | 30 | idx = findPara(idx + 1) 31 | if idx != -1 { 32 | ver = os.Args[idx] 33 | } 34 | 35 | ss := strings.Split(pkgPath, "/") 36 | if len(ss) < 2 { 37 | fmt.Println("not a go package path") 38 | return 39 | } 40 | if !strings.Contains(ss[0], ".") { 41 | pkgPath = "github.com/" + pkgPath 42 | } 43 | 44 | url := fmt.Sprintf(downTempl, pkgPath, ver, runtime.GOOS, runtime.GOARCH) 45 | vPrintln("getting from", url) 46 | resp, err := http.Get(url) 47 | if err != nil { 48 | fmt.Println(err) 49 | return 50 | } 51 | if resp.StatusCode != 200 { 52 | fmt.Println("error status code:", resp.StatusCode) 53 | return 54 | } 55 | 56 | dir, bin := getPath(), ss[len(ss)-1] 57 | binPath := filepath.Join(dir, bin+".zip") 58 | vPrintln("writting to", binPath) 59 | f, err := os.OpenFile(binPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777) 60 | if err != nil { 61 | fmt.Println(err) 62 | return 63 | } 64 | defer f.Close() 65 | 66 | _, err = io.Copy(f, resp.Body) 67 | if err != nil { 68 | fmt.Println(err) 69 | return 70 | } 71 | 72 | extractDir := filepath.Join(dir, "temp") 73 | os.MkdirAll(extractDir, os.ModePerm) 74 | vPrintln("unzip to", extractDir) 75 | err = unzip(extractDir, binPath) 76 | if err != nil { 77 | fmt.Println(err) 78 | return 79 | } 80 | 81 | dst := filepath.Join(dir, bin) 82 | src := filepath.Join(extractDir, bin) 83 | vPrintln("moving", src, "to", dst) 84 | if runtime.GOOS == "windows" { 85 | err = os.Rename(src+".exe", dst+".exe") 86 | } else { 87 | err = os.Rename(src, dst) 88 | } 89 | if err != nil { 90 | fmt.Println(err) 91 | return 92 | } 93 | 94 | vPrintln("clear", extractDir) 95 | os.RemoveAll(extractDir) 96 | 97 | vPrintln("clear", binPath) 98 | os.Remove(binPath) 99 | } 100 | -------------------------------------------------------------------------------- /list.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func list() { 6 | fmt.Println(`There are 22 packages: 7 | go-xorm/cmd/xorm 8 | revel/cmd/revel 9 | cznic/ql/ql 10 | go-xweb/xrun 11 | nsf/gocode 12 | beego/bee 13 | gpmgo/gopm 14 | bradfitz/goimports 15 | mitchellh/gox 16 | wendal/gor 17 | laher/goxc 18 | parkghost/gohttpbench 19 | shxsun/fswatch 20 | tools/godep 21 | mattn/gom 22 | codegangsta/gin 23 | zachlatta/postman 24 | coreos/etcd 25 | hashicorp/serf 26 | FiloSottile/Heartbleed 27 | cyfdecyf/cow 28 | apcera/gnatsd 29 | shenfeng/http-watcher 30 | nf/goplayer 31 | piranha/goreplace 32 | mtourne/gurl 33 | `) 34 | } 35 | --------------------------------------------------------------------------------