文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Go Module:私有不合规库怎么解决引用问题

2024-12-02 21:52

关注

大家好,我是 polarisxu。

有一个朋友咨询一个问题:

网友咨询

实际项目中,使用 Go Module 难免会有一些自己的库要引用,这些库使用自建的 Git 服务管理,比如 GitLab 等。针对这样的情况,不少教程都是让设置 GOPRIVATE,即不走 GOPROXY。

然而,有些时候,不仅库是私有的,而且地址很可能不是「合规」的。什么是「不合规」的?

不是 HTTPS 问题不大,主要是非 443 或 80,以及直接 IP 地址的问题比较大。因为 Go 不支持下面的语法:

  1. import "studygolang.com:8081/polarisxu/util" 
  2. import "192.168.1.1:80/polarisxu/util" 

一般地,我们应该避免出现这样的情况,毕竟太恶心,而且没必要自讨苦吃。

但万一遇到了,怎么办?本文就探讨这个问题。

01 模拟环境

因为之前没遇到这样的问题,为了我更好的解决,这位朋友直接提供了他的环境供我试验。我注册了账号,并创建了一个仓库 testgo:http://vitogo.tpddns.cn:9000/polarisxu/testgo。(为了方便,这个仓库是 public)

提示:你想试验,可以自己注册一个账号试试。当然,也可以通过 gitlab 本地搭建一个。

仓库中创建文件 testgo.go,内容如下:

  1. package testgo 
  2.  
  3. func MyName() string { 
  4.  return "polarisxu" 

关键是这个库的 go.mod 如何写?

很显然,我们不能直接用 vitogo.tpddns.cn:9000/polarisxu/testgo 这样的 module 名称。

02 module 名称

那怎么办?

我们可以借助 git 的功能,将 vitogo.tpddns.cn:9000 替换掉:(也可以直接修改 ~/.gitconfig 文件)

  1. git config --global url."http://vitogo.tpddns.cn:9000/".insteadof "https://{{gitlab_url}}/" 

这里有两点需要注意:

1)url 后面的内容,具体什么值,需要根据你的情况定。

可以通过你的自建仓库查看:

查看 clone

这里选择 HTTP 方式(因为我创建了一个 public 仓库)。也可以选择使用 ssh 方式,这样即使私有仓库,你配置上自己的 SSH KEY 也可正常 Pull。(如何配置 SSH KEY,网上很容易查到教程,GitHub 上就有)

我们这里使用了 http://vitogo.tpddns.cn:9000/,表示这个域名下所有的内容。

2)insteadOf 后面的内容,表示访问这个链接时,将替换为上面 url 后的链接。

这个值写什么?很显然,必须是合规的域名。我们任意使用一个域名试试,比如使用 https://studygolang.com/。

这时,我们尝试执行如下命令:

  1. $ git config --global url."http://vitogo.tpddns.cn:9000/".insteadof "https://studygolang.com/" 
  2. # 让 studygolang.com 不走 GOPROXY 
  3. $ go env -w GOPRIVATE=studygolang.com 
  4. $ go get -v studygolang.com/polarisxu/testgo 
  5. go get: unrecognized import path "studygolang.com/polarisxu/testgo": parsing studygolang.com/polarisxu/testgo: XML syntax error on line 15: unescaped < inside quoted string 

很好理解,go get 最终需要将代码下载下来,怎么下载?这张图很好的说明了:

go get 过程

那 go get 怎么知道当前仓库使用 VCS 托管的呢?对于 studygolang.com 这种域名,它会尝试请求,判断 CVS 类型。很显然,studygolang.com 没有做任何处理,不是 CVS 类型,所以报错。

关于这个过程感兴趣的,可以参考该文:https://studygolang.com/articles/35235

网友希望使用 vitogo.tpddns.cn 这个他的域名,但同样有这个问题。如果要让它正常,需要做特殊处理,具体参考上面的文章。

所以,我们使用一个非常用的现成 Git 公开托管服务,比如 gitea.com。(polarisxu/testgo 我打了一个 tag:v0.0.1)

  1. $ git config --global url."http://vitogo.tpddns.cn:9000/".insteadof "https://gitea.com/" 
  2. $ go env -w GOPRIVATE=gitea.com 
  3. $ go get -v gitea.com/polarisxu/testgo 
  4. get "gitea.com/polarisxu/testgo": found meta tag vcs.metaImport{Prefix:"gitea.com/polarisxu/testgo", VCS:"git", RepoRoot:"https://gitea.com/polarisxu/testgo.git"at //gitea.com/polarisxu/testgo?go-get=1 
  5. go: downloading gitea.com/polarisxu/testgo v0.0.1 
  6. gitea.com/polarisxu/testgo 

成功了!你可以到 $GOPATH/pkg/mod 下面看是否有对应的包。

注意其中 ?go-get=1 这个参数,你可以浏览器访问 https://gitea.com/polarisxu/testgo?go-get=1,然后查看源码,看看里面是什么内容:

  1.  
  2.  
  3.   
  4.   name="go-import" content="gitea.com/polarisxu/testgo git https://gitea.com/polarisxu/testgo.git"
  5.   name="go-source" content="gitea.com/polarisxu/testgo _ https://gitea.com/polarisxu/testgo/src/branch/master{/dir} https://gitea.com/polarisxu/testgo/src/branch/master{/dir}/{file}#L{line}"
  6.   
  7.   
  8.   go get gitea.com/polarisxu/testgo 
  9.   
  10.  

因此,我们可以在 polarisxu/testgo 中增加 go.mod 文件:

  1. go mod init gitea.com/polarisxu/testgo 

然后打上第二个 tag:v0.0.2,再次获取:

  1. $ go get -v gitea.com/polarisxu/testgo 
  2. get "gitea.com/polarisxu/testgo": found meta tag vcs.metaImport{Prefix:"gitea.com/polarisxu/testgo", VCS:"git", RepoRoot:"https://gitea.com/polarisxu/testgo.git"at //gitea.com/polarisxu/testgo?go-get=1 
  3. go: downloading gitea.com/polarisxu/testgo v0.0.2 
  4. gitea.com/polarisxu/testgo 

03 使用该包

本地创建一个项目,引用上面定义的包:

  1. $ mkdir ~/testprivate 
  2. $ cd ~/testprivate 
  3. $ go mod init testprivate 
  4. $ touch main.go 

在 main.go 中输入如下内容:

  1. package main 
  2.  
  3. import ( 
  4.     "fmt" 
  5.     "gitea.com/polarisxu/testgo" 
  6.  
  7. func main() { 
  8.     fmt.Println("Hello", testgo.MyName()) 

执行 go mod tidy 后,运行:

  1. $ go run main.go 
  2. Hello polarisxu 

正常输出我们期望的结果。

04 总结

通过了解 go get 的基本原理,知晓 git 的一些处理方式,以及 GOPRIVATE 的作用。我相信遇到类似的问题,你自己也能够解决了。

注意,如果 gitea.com 你有实际使用,可以选择 gitee.com、try.gogs.io 等。

另外,关于本文的问题,Go 有几个相关 issue 讨论:

https://github.com/golang/go/issues/34436

https://github.com/golang/go/issues/38213

 

来源: polarisxu内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯