在 Go 语言模块化编程 ( 四 ) - go module proxies ( 代理 ) ( 上 ) 章节中我们阐述了 go module proxy 的一些协议细节,其实就是一个简单的 Web 服务器
既然很简单,我们就用 Go 来实现一遍吧,刚好可以演示下如何使用 go module 的开发方式
确定 go 版本
因为 go module 需要 go 1.11 及以上版本 ( 当前最新的稳定版本为 go 1.11 ),所以你需要确保你系统上的 go 是当前最新的版本
可以在命令行 ( 终端 \ 命令提示符 \ PowerShell ) 上输入以下命令查看当前 go 版本,例如我的 MBP
[yufei@www.twle.cn ~]$ go version go version go1.11 darwin/amd64
创建一个测试模块 demomod
为了继续下面的 go module proxy ,我们需要先准备一个 go module ,我们为将要创建的 go module 命名为 demomod
,且完全限定名称为 github.com/ijoywan/demomod
创建 go module 最重要的是 「 模块 ( module ) 必须在 GOPATH
路径之外 」,因为,极有可能就是下一个版本,就会移除 GOPATH
- 首先,在工作目录中使用下面的命令创建一个模块目录,比如
demomod
mkdir demomod
如果你的是 Windows 电脑,就直接右键创建目录吧
-
然后,使用
cd demomod
进入demomod
目录并创建一个 Go 文件demomod.go
package demomod import "fmt" // Hi returns a friendly greeting func Hi(name string) string { return fmt.Sprintf("Hi, %s", name) }
当然了,这样创建好了之后,还不是一个 go module
-
我们需要使用下面的命令来创建一个 go module ,假设我们的
demomod
的完全路径为github.com/ijoywan/demomod
,那么可以使用下面的命令来创建[yufei@www.twle.cn demomod]$ go mod init github.com/ijoywan/demomod go: creating new go.mod: module github.com/ijoywan/demomod
go: creating new go.mod: module github.com/ijoywan/demomod
的意思就是成功了创建成功后,可以使用
tree
命令查看目录结构,如下[yufei@www.twle.cn demomod]$ tree . . ├── demomod.go └── go.mod 0 directories, 2 files
就两个文件,很简单的,打开
go.mod
文件,可以看到如下内容module github.com/ijoywan/demomod
这样就成功创建了一个包,但是,它还不能用,不能被 go get
识别
版本化 demomod
如果需要能被 go get
识别且下载,我们需要上传到 github.com
并打上版本 tag
其实传到任何地方都可以,但是,需要说明的是,go get 命令使用路径前缀,也就是第一个
/
之前的域名来识别存储的地方,比如github.com
就是从github.com
上下载
-
首先使用下面的命令创建 git 本地仓库
[yufei@www.twle.cn demomod]$ git init . Initialized empty Git repository in /Users/yufei/Downloads/curl_mail/go/mod/demomod/.git/ [yufei@www.twle.cn demomod]$ git add --all [yufei@www.twle.cn demomod]$ git commit -m "first commit" [master (root-commit) 4f60e21] first commit 2 files changed, 9 insertions(+) create mode 100644 demomod.go create mode 100644 go.mod
-
使用
git tag
命令先打标签v0.0.1
创建一个版本v0.0.1
[yufei@www.twle.cn demomod]$ git tag v0.0.1
-
我们就不做过多修改了,直接多打几个标签
[yufei@www.twle.cn demomod]$ git tag v0.0.2 [yufei@www.twle.cn demomod]$ git tag v0.1.3 [yufei@www.twle.cn demomod]$ git tag v1.0.0
-
然后使用
git push
命令提交到远程github.com
上git push -u origin master
这样,我们的 go module 就制作好了,你可以访问 https://github.com/ijoywan/demomod 访问详情
创建一个本地的 go module proxy
因为 go module proxy 其实可以是一个简单的静态文件服务器,所以,我们就将就将就,创建一个最为简单的呗
其实上面的版本化目前我们要做的东西一点关系都没有,有用的只是刚刚创建的模块而已
-
首先,我们创建一个目录,存储我们的依赖项的副本,比如
$HOME/devel/proxy
-
然后,在
go-proxy
中创建多级目录github.com/ijoywan/demomod/@v
-
最后在
github.com/ijoywan/demomod/@v
中分别创建以下文件[yufei@www.twle.cn proxy]$ tree . └── github.com └── ijoywan └── demomod └── @v ├── list ├── v0.0.1.info ├── v0.0.1.mod ├── v0.0.1.zip ├── v0.0.2.info ├── v0.0.2.mod ├── v0.0.2.zip ├── v0.1.3.info ├── v0.1.3.mod ├── v0.1.3.zip ├── v1.0.0.info ├── v1.0.0.mod └── v1.0.0.zip 4 directories, 13 files
.mod
文件的内容都为module github.com/ijoywan/demomod
v0.0.1.info
的内容为{"Version": "v0.0.1", "Time": "2018-09-05T22:58:46.436183+08:00"}
v0.0.2.info
的内容为{"Version": "v0.0.2", "Time": "2018-09-05T22:58:46.436183+08:00"}
v0.1.3.info
的内容为{"Version": "v0.1.3", "Time": "2018-09-05T22:58:46.436183+08:00"}
v1.0.0.info
的内容为{"Version": "v1.0.0", "Time": "2018-09-05T22:58:46.436183+08:00"}
只是每个文件的版本号不一样
.zip
就需要注意了,.zip
的解压结果目录格式为github.com/ijoywan/demomod@v0.0.1/
也就是说最后一级的目录需要加上版本好,目录结构如下
├── github │ └── ijoywan │ └── demomod@v0.0.1 │ ├── demomod.go │ └── go.mod
-
有了这些文件后,我们就可以创建一个 Go Server 了,在另一个目录,比如
$HOME/devel/
下创建一个 go 文件proxy.go
,内容如下package main import ( "flag" "log" "net/http" ) func main() { addr := flag.String("http", ":8080", "address to bind to") flag.Parse() dir := "." if flag.NArg() > 0 { dir = flag.Arg(0) } log.Printf("Serving files from %s on %s\n", dir, *addr) h := handler{http.FileServer(http.Dir(dir))} panic(http.ListenAndServe(*addr, h)) } type handler struct { h http.Handler } func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Println("New request:", r.URL.Path) h.h.ServeHTTP(w, r) }
代码很简单,都不用解释,如果你写过 web 程序,一看就懂
-
然后我们就可以使用下面的命令来运行这个
proxy.go
[yufei@www.twle.cn devel]$ go run proxy.go -http :8080 $Home/devel/proxy 2018/09/05 23:14:08 Serving files from ./proxy on :8080
然后打开浏览器访问 http://localhost:8080/github.com/ijoywan/demomod/@v/ 可以看到结果如下
-
最后我们可以使用
curl
命令来测试下list
这个文件[yufei@www.twle.cn devel]$ curl http://localhost:8080/github.com/ijoywan/demomod/@v/list v1.0.0 v0.1.3 v0.0.2 v0.0.1
代理就这样搭建完成了
设置代理
使用代理之前,我们需要先设置环境变量,如果永久性的使用,可以编辑 .bash_profile
或 .bashrc
或 .zshrc
文件添加以下内容
export GOPROXY=http://localhost:8080
如果在命令行临时使用,就直接输入以上内容然后回车
[yufei@www.twle.cn devel]$ export GOPROXY=http://localhost:8080 [yufei@www.twle.cn devel]$
测试代理
假设我们现在要启用一个项目 test
,项目位置为 $HOME/devel/test
,那么
-
使用
mkdir -p $HOME/devel/test
创建项目目录, Windows 用户你就在自己的工作目录创建test
即可 -
然后在
test
目录下新建一个文件test.go
,内容如下package main import ( "github.com/ijoywan/demomod" ) func main() { demomod.Hi("world") }
-
然后在
test
目录下输入以下命令开启 go module 支持[yufei@www.twle.cn test]$ go mod init test go: creating new go.mod: module test
-
接下来最终要的,就是构建了,输入以下命令
[yufei@www.twle.cn test]$ go build go: finding github.com/ijoywan/demomod v1.0.0 go: downloading github.com/ijoywan/demomod v1.0.0
然后我们就可以看到代理输出内容如下
2018/09/05 23:43:48 New request: /github.com/ijoywan/demomod/@v/list 2018/09/05 23:43:48 New request: /github.com/ijoywan/demomod/@v/v1.0.0.info 2018/09/05 23:43:48 New request: /github.com/ijoywan/demomod/@v/v1.0.0.zip