Go Module 工程化实践(三):工程实践篇

栏目: 编程工具 · 发布时间: 4年前

内容简介:以本人以往所在公司的实际现状作为样例,说明具体的原有Go项目均采用单一

3. 工程实践篇

如何实现企业内项目的 Go Module 工程化迁移?

以本人以往所在公司的实际现状作为样例,说明具体的 Go Module 工程化迁移过程。

原有 Go 项目均采用单一 vendor 的模式进行依赖控制,即企业内所有Go项目的第三方依赖均引用该统一的 vendor 仓库,由专人专组独立维护。这样做的好处就是依赖包不会随实际开发者的版本变更而变更,企业内部维护一套相对稳定的版本,缺点就是缺少了依赖包的版本控制。

Go Module 工程化迁移的 目标 就是保持本地版本的稳定的同时兼顾版本控制功能。

3.1 modules 仓库

在非 Go Module 项目中,所有项目的依赖包,使用了 vendor 仓库,在迁移到 Go Module 模式下,同样需要相应的 modules 仓库, 来保证本地开发包依赖版本的稳定。

modules 仓库的依赖包从何而来。不妨看看:

$: tree -L 1 $GOPATH/pkg/mod/cache/download
├── cloud.google.com
├── git.apache.org
├── git.yixindev.net
├── github.com
├── go.opencensus.io
├── go.uber.org
├── golang.org
├── gonum.org
├── google.golang.org
├── gopkg.in
├── gotest.tools
├── honnef.co
├── k8s.io
└── layeh.com

这就是我们要维护的 modules 仓库依赖包。在开发过程中,新的依赖包都会下载到这个路径。将新的依赖包版本复制到 modules 仓库相应的路径。就完成了 modules 仓库依赖包的版本维护。

需要注意的点是:

我们是从 $GOPATH/pkg/mod/cache/download 目录中复制新的依赖包到 modules 仓库中。但并不是所有的文件都需要进行维护,特别是本地下载过程中的一些临时文件。

$: tree -L 1 $GOPATH/pkg/mod/cache/download/github.com/x-mod/httpclient/@v/
├── list
├── list.lock
├── v0.1.2.info
├── v0.1.2.lock
├── v0.1.2.mod
├── v0.1.2.zip
├── v0.1.2.ziphash
├── v0.2.0.info
├── v0.2.0.lock
├── v0.2.0.mod
├── v0.2.0.zip
├── v0.2.0.ziphash
├── v0.2.1.info
├── v0.2.1.lock
├── v0.2.1.mod
├── v0.2.1.zip
└── v0.2.1.ziphash

在这个 github.com/x-mod/httpclient 依赖包中,我们仅仅需要具体版本的四个类型文件:

  • info
  • mod
  • zip
  • ziphash

其它类型的文件,是不需要进行 modules 仓库维护的。所以可以在 modules 仓库中通过 .gitignore 进行忽略。

3.2 CI 过程更新

完成了 modules 仓库的维护后,我们就可以对原有项目的 CI 过程进行更新了。在 CI 编译机或者容器上

  • git clone modules repo 到指定位置 path/to/modules
  • 开启 GoModule 编译选项, 设置 export GO111MODULE=on
  • 设置 GoProxy 环境变量, 设置通过本地文件代理: export GOPROXY=file:///path/to/modules

现在所有GO项目就会开启 GoModule 选项同时,可以完成依赖包的版本控制。如何缺少依赖包,只需要从本地将新增依赖包的版本添加到 modules 仓库即可。

3.3 企业仓库 GoGet 代理优化

如果阅读了 Go Get 原理之后,针对企业依赖包的 GoGet ,我们可以写一个简单的 http 代理程序, 这样就设定自己的:

// Example
// code server http://aaa.com:888/user/repo.git
// code import path: bbb.com/user/repo
// 
// host => aaa.com:888
// vcs  => git
// root => bbb.com

type Getter struct {
    host    string //gitlab address
    vcs     string //git
    root    string //git
}

func NewGetter(host string, vcs string, root string) *Getter {
    return &Getter{
        host: host,
        vcs:  vcs,
        root: root,
    }
}

func (x *Getter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if r.URL.Query().Get("go-get") == "1" {
        sp := strings.Split(r.URL.Path[1:], "/")
        if len(sp) < 2 {
            http.Error(w, fmt.Errorf("unsupport path: %s", r.URL.Path).Error(), http.StatusBadRequest)
            return
        }
        prefix := fmt.Sprintf("%s/%s/%s", x.host, sp[0], sp[1])
        repository := fmt.Sprintf("%s/%s/%s.%s", x.root, sp[0], sp[1], x.vcs)
        fmt.Fprintf(w, `<html><head><meta name="go-import" content="%s %s %s" /></head></html>`, prefix, x.vcs, repository)
        log.Println("go get [", prefix, "] from repository [", repository, "].")
        return
    }
    http.Error(w, fmt.Errorf("unsupport request: %s", r.URL.Path).Error(), http.StatusBadRequest)
}

通过这个简单的代理,你就可以实现:

code server http://aaa.com :888/user/repo.git

code import path: bbb.com/user/repo

host => aaa.com:888

vcs => git

root => bbb.com

这样的非标依赖包的拉取了。

这一篇拖了好久,花一个小时完结掉这个系列。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Developer's Guide to Social Programming

Developer's Guide to Social Programming

Mark D. Hawker / Addison-Wesley Professional / 2010-8-25 / USD 39.99

In The Developer's Guide to Social Programming, Mark Hawker shows developers how to build applications that integrate with the major social networking sites. Unlike competitive books that focus on a s......一起来看看 《Developer's Guide to Social Programming》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具