当前位置: 首页 > 工具软件 > goproxy-shell > 使用案例 >

go语言依赖管理的多种方式-goget包管理工具被墙办法

吴浩博
2023-12-01

依赖管理以及goget包管理工具被墙办法

其实我是很喜欢golang这门语言的,易开发,易维护,社区庞大且相对成熟,不过可惜它是谷歌的.

其实谷歌也没什么,主要是谷歌的东西容易用着用着就不能用了.

最早之前用golang的时候,就发现go get这个命令安装东西时如果有golang官方的依赖就会发现被墙了,用起来非常的麻烦.不过当时服务器部署在海外,一切都还好.

今天就记录一下在国内使用包时免FQ的办法 gopm(gopem项目已经下了,推荐使用go mod)

goproxy的使用以及依赖管理#

使用go modgo proxy来做依赖管理go 1.13>=版本推荐使用#

依赖管理三个阶段GOPATH,GOVENDOR,go mod

  • GOPATH 需要多个版本的时候,GOPATH无法做到,而且所有项目都必须放到这里的话多了之后会很要命.
  • GOVENDOR 什么都要放进去,非常费劲和臃肿.所以社区出了glide等第三方工具帮我们
  • go mod 推荐使用,非常完美,go命令统一管理,用户不必关心目录结构,项目也不再必须放在~/go/src/下了
  • go mod下载的包都在~/go/pkg/mod/下存储

go mod常用命令和设置#

go mod download 下载依赖
go mod tidy 同步依赖包,添加需要的,移除多余的
go mod vendor 将依赖包放入项目下的vendor目录
go get 下载/升级依赖,go mod不再下载源码进$GOPATH/src,而是在$GOPATH/pkg/mod

注意:
go mod模式不推荐使用vendor目录,而是直接从cache使用下载的包.

go mod模式默认忽略vendor目录,可以通过flag-mod=vendor设置为GOFLAGS=-mod=vendor来设置为vendor模式.但是该模式下无法正常使用go get

只通过goproxy来下载依赖使用go 1.13以下版本推荐使用#

    1. 仅设置当前窗口本次生效.
      开启GOPOXY地址即可,go 1.13一下版本没有GO111MODULE这个变量
export GOPROXY=https://goproxy.cn
    1. 此时就可以直接使用go get命令而不会被墙了,下载的内容还是存储在GOPATH中

这个包有一个golang.org的依赖如果直接go get是无法下载的.

go get -u -v github.com/aliyun/aliyun-oss-go-sdk/oss

完成

设置GOPROXY地址,开启go mod#

  • 当前窗口生效
export GO111MODULE=on

export GOPROXY=https://goproxy.cn
  • 永久修改
go env -w GO111MODULE=on

go env -w GOPROXY=https://goproxy.cn,direct



# 或者使用下面这个, https://goproxy.cn是七牛云的项目

go env -w GOPROXY=https://goproxy.io,direct



GOPROXY=https://goproxy.cn,direct 配置`GOPROXY`的地址`direct`代表当`go`在抓取目标模块时直接去目标模块的源头(比如 GitHub) 去抓取

GO111MODULE=on  开启`go mod`依赖管理功能

如果有不想走proxy的可以这样设置

# 设置不走 proxy 的私有仓库,多个用逗号相隔

go env -w GOPRIVATE=*.corp.example.com

# 例如:来自码云,gitlab,阿里云的的代码不走proxy

go env -w GOPRIVATE=*.gitee.com,code.aliyun.com


此时已可以获取包了

# 这时候使用go get 去获取之前下不到的包,会发现非常的快.

 go get -u -v go.uber.org/zap 
  • 后面我们用goland创建项目时会自动在项目下生成一个go.mod文件

go.mod文件内容

module awesome-project  项目名称



go 1.13  语言的版本
  • awesome-project项目目录下go get下载所需要的包

此时我们就可以为不同的项目下载不同的包了

# 这时候使用go get 去获取之前下不到的包,会发现非常的快.

 go get -u -v go.uber.org/zap 

 # 如果要下载指定版本的包只需要在后面@版本号即可

 go get -u -v go.uber.org/zap@v1.11

 # 如果要升级,不指定版本号即可

  go get -u -v go.uber.org/zap

 # 清洁依赖,删除`go.mod`中没有被使用的包的条目(不会删除包文件)

 go mod tidy

 
  • 下载完毕之后会发现go.mod文件已有改变,并且多了一个go.sum文件

go.mod文件内容

module awesome-project 项目名



go 1.13	语言版本

 

require (  

   go.uber.org/atomic v1.5.1 // indirect 代表没有被用到

  go.uber.org/multierr v1.4.0 // indirect  

  go.uber.org/zap v1.13.0 // indirect  

  golang.org/x/lint v0.0.0-20200130185559-910be7a94367 // indirect  

  golang.org/x/tools v0.0.0-20200206050830-dd0d5d485177 // indirect  

)

go.sum文件的部分内容,里面有各个包的hash和版本号

github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=

github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=

github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=

github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=

......
  • 直接在代码中import没有下载的包

首次直接编译会失败(goland没事).但同时也会将包下载下来, 再次编译的时候就没问题了
.

package main



import "github.com/astaxie/beego"



func main()  {

	beego.Run()

}
  • 再次查看go.mod

发现多了一条beego的记录,可见go会帮我们自动下载需要的依赖

module awesome-project



go 1.13



require (

	github.com/astaxie/beego v1.12.0 // indirect

	github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect

)
  • 之前没有用go mod现在想用怎么办?

  • 使用go mod命令来创建go.mod然后再编译

go mod init module名称(会自动命名为项目名称, 一般和项目名保持一致即可)

go build ./...

build过程中每次遇到import都会触发go modules通过镜像帮我们拉去所需要的包

# 将当前目录下所有的go文件全部编译

go build ./...



# 编译案例,可以看到build后都已经在下载所需要的包了

go build ./...

go: finding github.com/go-sql-driver/mysql v1.5.0

go: finding github.com/go-xorm/xorm v0.7.9

go: downloading github.com/go-sql-driver/mysql v1.5.0

go: downloading github.com/go-xorm/xorm v0.7.9

go: finding gopkg.in/fatih/set.v0 v0.2.1

go: finding github.com/gorilla/websocket v1.4.1

go: finding github.com/pkg/errors v0.9.1

go: downloading github.com/gorilla/websocket v1.4.1

go: downloading github.com/pkg/errors v0.9.1

go: downloading gopkg.in/fatih/set.v0 v0.2.1

go: extracting github.com/go-sql-driver/mysql v1.5.0

go: extracting github.com/gorilla/websocket v1.4.1

go: extracting github.com/pkg/errors v0.9.1

go: extracting github.com/go-xorm/xorm v0.7.9

go: extracting gopkg.in/fatih/set.v0 v0.2.1

完成

使用vendor#

这是一个很短暂的项目,官方在推出vendor支持以后很快就推出了go mod,不建议再用,费劲.

即在项目目录下新建一个vendor目录, 将所有依赖的第三方包全部放在vendor下.

go语言会优先在此目录寻找依赖.

可以看到vendor下面还有vendor,不管有我们的vendor,还有我们引用第三方时,他们自己的vendor



├── vendor

│   ├── config

│   └── github.com

│       ├── aliyun

│       │   └── aliyun-oss-go-sdk

│       │       ├── oss

│       │       └── sample

│       ├── go-sql-driver

│       │   └── mysql

│       ├── julienschmidt

│       │   └── httprouter

│       └── tencentyun

│           └── cos-go-sdk-v5

│               ├── costesting

│               ├── debug

│               ├── example

│               │   ├── batch

│               │   ├── bucket

│               │   ├── object

│               │   ├── service

│               │   └── sts

│               └── vendor

│                   └── github.com

│                       ├── google

│                       │   └── go-querystring

│                       │       └── query

│                       ├── mozillazg

│                       │   └── go-httpheader

│                       └── stretchr

│                           └── testify

│                               ├── _codegen

│                               ├── assert

│                               ├── http

│                               ├── mock

│                               ├── require

│                               ├── suite

│                               └── vendor

│                                   └── github.com

│                                       ├── davecgh

│                                       │   └── go-spew

│                                       │       └── spew

│                                       ├── pmezard

│                                       │   └── go-difflib

│                                       │       └── difflib

│                                       └── stretchr

│                                           └── objx

直接从github下载需要的包到$GOPATH下#

没网的时候可以这么干,但是要注意依赖的依赖,这个问题.

gopm 包管理工具使用(2019年底的开始已经不能用了)#

gopm官方文档#

GitHub地址

GitHub中文文档

官网地址

gopm安装#

go get -v -u github.com/gpmgo/gopm

gopm常用命令#

# 查看当前工程依赖

gopm list

# 显示依赖详细信息

gopm list -v

# 列出文件依赖

gopm list -t [file]

# 拉取依赖到缓存目录

gopm get -r xxx

# 仅下载当前指定的包

gopm get -d xxx

# 拉取依赖到$GOPATH

gopm get -g xxx

# 检查更新所有包

gopm get -u xxx

# 拉取到当前所在目录

gopm get -l xxx

# 运行当前目录程序

gopm run

# 生成当前工程的 gopmfile 文件用于包管理

gopm gen -v

# 根据当前项目 gopmfile 链接依赖并执行 go install

gopm install -v

# 更新当前依赖

gopm update -v

# 清理临时文件

gopm clean

# 编译到当前目录

gopm bin

gopm使用案例#



安装gopm

go get -v -u github.com/gpmgo/gopm



这是我们回到~/go 中的我们自己的GOPATH的目录 ls一下



可以看到$GOPATH下的src下多了一个github.com 的目录,和我们的目录放在一起

```shell

    ~/go ⌚ 2:06:05

    $ tree -L 2

    .

    ├── bin

    │   └── gopm

    └── src

        ├── github.com

        └── learnGo

这时候我们到~/go/bin/gopm 运行该文件

~/go/bin/gopm get -g -v -u golang.org/x/tools/cmd/goimports

这是安装成功之后, $GOPATH 下的src中会多一个golang.org的目录和我们的目录放在一起

~/go ⌚ 2:19:31

$ tree -L 2

.

├── bin

│   └── gopm

└── src

    ├── github.com

    ├── golang.org

    └── learnGo

很显然我们在编码时的目录也是在src中运行的, bin是可执行文件

在~/go/bin 目录下执行 go install 安装goimports 安装之后会在~/go/bin目录下生成一个可执行的文件

~/go/bin ⌚ 2:26:38

$ go install  ../src/golang.org/x/tools/cmd/goimports
 类似资料: