Original text: https://mp.weixin.qq.com/s/Q28LwtYfU7KH_Zy0VbHvOA
https://zhuanlan.zhihu.com/p/420764860
----------------------
Hello, I'm polarisxu.
A friend asked a question:
Netizen consultation
In actual projects, when using Go Module, it is inevitable to have some own libraries to reference. These libraries are managed by self built Git services, such as GitLab. In view of this situation, many tutorials let you set GOPRIVATE, that is, do not go to GOPROXY.
However, sometimes, not only is the library private, but the address is likely not "compliant". What is "non-compliance"?
- Not HTTPS
- Non 443 or 80 ports
- Use IP address directly
It's not HTTPS. It's mainly non 443 or 80, and the problem of direct IP address is relatively large. Because Go does not support the following syntax:
import "studygolang.com:8081/polarisxu/util"
import "192.168.1.1:80/polarisxu/util"
Generally, we should avoid such a situation. After all, it's disgusting and there's no need to ask for trouble.
But what if it happens? This paper discusses this problem.
01 simulation environment
Because I haven't encountered such a problem before, in order to better solve it, this friend directly provided his environment for me to experiment. I registered my account and created a warehouse testgo: http://vitogo.tpddns.cn:9000/polarisxu/testgo . (for convenience, this warehouse is public)
Tip: if you want to experiment, you can register an account yourself. Of course, you can also build one locally through gitlab.
Create a file testgo.go in the warehouse, as follows:
package testgo
func MyName() string {
return "polarisxu"
}
The key is how to write the go.mod of this library?
Obviously, we can't use it directly vitogo.tpddns.cn:9000/polarisxu/testgo Such a module name.
02 module name
What can we do?
We can use the function of git to vitogo.tpddns.cn:9000 Replace: (can also be modified directly) ~/. gitconfig (file)
git config --global url."http://vitogo.tpddns.cn:9000/".insteadof "https://{{gitlab_url}}/"
Here are two points to note:
1) The content behind the url and the specific value need to be determined according to your situation.
You can view it through your self built warehouse:
View clone
HTTP is selected here (because I have created a public repository). You can also choose to use ssh mode, so that you can Pull normally even if you configure your own SSH KEY in a private warehouse. (you can easily find the tutorial on how to configure SSH KEY on the Internet, which is available on GitHub)
We use it here http://vitogo.tpddns.cn:9000/ , indicating all contents under this domain name.
2) The content after insteadOf indicates that when accessing this link, it will be replaced by the link after the above url.
What does this value say? Obviously, it must be a compliant domain name. Let's try using any domain name, such as https://studygolang.com/ .
At this time, we try to execute the following command:
$ git config --global url."http://vitogo.tpddns.cn:9000/".insteadof "https://studygolang.com/"
# Give Way studygolang.com Don't go GOPROXY
$ go env -w GOPRIVATE=studygolang.com
$ go get -v studygolang.com/polarisxu/testgo
go get: unrecognized import path "studygolang.com/polarisxu/testgo": parsing studygolang.com/polarisxu/testgo: XML syntax error on line 15: unescaped < inside quoted string
It's easy to understand. go get finally needs to download the code. How can I download it? This picture illustrates:
go get process
How do you know that the current warehouse is hosted by VCS? For the domain name studygolang.com, it will try to request and determine the CVS type. Obviously, studygolang.com does not do any processing. It is not a CVS type, so an error is reported.
For those interested in this process, please refer to this article: https://studygolang.com/articles/35235
Netizens want to use vitogo.tpddns.cn, his domain name, but they also have this problem. If you want to make it normal, you need to do special treatment. Refer to the above article for details.
Therefore, we use a very useful off the shelf Git public hosting service, such as gitea.com. (polarisxu/testgo I typed a tag: v0.0.1)
$ git config --global url."http://vitogo.tpddns.cn:9000/".insteadof "https://gitea.com/"
$ go env -w GOPRIVATE=gitea.com
$ go get -v gitea.com/polarisxu/testgo
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
go: downloading gitea.com/polarisxu/testgo v0.0.1
gitea.com/polarisxu/testgo
succeed! You can go there $ GOPATH/pkg/mod Let's see if there is a corresponding package.
Note among them ? go-get=1 This parameter can be accessed by your browser https://gitea.com/polarisxu/testgo?go-get=1, and then check the source code to see what is inside:
<!doctype html>
<html>
<head>
<meta name="go-import" content="gitea.com/polarisxu/testgo git https://gitea.com/polarisxu/testgo.git">
<meta 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}">
</head>
<body>
go get gitea.com/polarisxu/testgo
</body>
</html>
Therefore, we can add the go.mod file in polarisxu/testgo:
go mod init gitea.com/polarisxu/testgo
Then type the second tag: v0.0.2 and get the following again:
$ go get -v gitea.com/polarisxu/testgo
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
go: downloading gitea.com/polarisxu/testgo v0.0.2
gitea.com/polarisxu/testgo
03 use this package
Create a project locally and reference the package defined above:
$ mkdir ~/testprivate
$ cd ~/testprivate
$ go mod init testprivate
$ touch main.go
Enter the following in main.go:
package main
import (
"fmt"
"gitea.com/polarisxu/testgo"
)
func main() {
fmt.Println("Hello", testgo.MyName())
}
After executing go mod tidy, run:
$ go run main.go
Hello polarisxu
Normally output the results we expect.
04 summary
By understanding the basic principle of go get, know some processing methods of git and the role of GOPRIVATE. I believe you can solve similar problems yourself.
Note that if you actually use gitea.com, you can choose gitee.com, try.gogs.io, etc.
In addition, Go has several issue s related to this article:
- https://github.com/golang/go/issues/34436
- https://github.com/golang/go/issues/38213
Reference articles
- Use practice of GO module in privatized warehouse: https://studygolang.com/articles/35235
- go modules uses local libraries, compliance libraries, and private libraries: https://studygolang.com/articles/35234