Loading

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

依赖管理以及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
posted @ 2021-07-30 15:28  我爱吃炒鸡  阅读(528)  评论(0编辑  收藏  举报