go mod详细使用教程

目录
  • 前言
  • 使用go path问题
  • govendor
  • go mod介绍
  • 如何使用go mod
  • GO111MODULE
  • go mod命令
  • 使用go mod管理一个新项目
    • 1. 初始化项目
    • 2. 添加依赖
  • go get升级
  • 使用replace替换无法直接获取的package
  • go mod发布和使用
    • Creating a Module
    • module versioning
    • making a release
    • use our module
    • Making a bugfix release
    • Updating modules
    • Major versions
    • Updating to a major version
    • Vendoring
  • IDEA下开发GO
  • 总结

前言

最近由于换工作,开始交接工作。整理以前的工作内容,由于组内就我一个在做go和大数据。 所以开发没有规划,当时是怎么快怎么来。go也是使用最传统的go path的方式管理的。都是手动管理依赖的。现在交接给他人,需要多人开发,发现很多问题。比如版本问题,各种依赖的问题等等。

由于工作原因,几乎所有主流语言都写过。所以,对应语言包管理工具也都了解和使用过。我前面有写过maven的使用。
maven是使用过的功能最强大的包管理工具了,maven定位是项目管理工具。pip和npm都是及格的产品。

我个人觉得,一个包管理工具应该有以下功能:

基本功能

  • 依赖管理
  • 依赖包版本控制
  • 对应的包管理平台
  • 可以私有化部署

加分:

  • 代码包是否可以复用
  • 构建,测试,打包
  • 发布上线

对比上面几点:

目前做的最好的也就 maven了,gradle没有使用过,不知道。

今天主角是go mod,先来谈谈没有使用go mod之前的问题。

使用go path问题

  • 代码开发必须在go path src目录下,不然,就有问题。
  • 依赖手动管理
  • 依赖包没有版本可言

从这个看, go path不算包管理工具

govendor

  • 解决了包依赖,一个配置文件就管理
  • 依赖包全都下载到项目vendor下,每个项目都把有一份。拉取项目时,开始怀疑人生。

go mod介绍

go modules 是 golang 1.11 新加的特性。现在1.12 已经发布了,是时候用起来了。Modules官方定义为:

模块是相关Go包的集合。modules是源代码交换和版本控制的单元。 go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用哪些源文件。

如何使用go mod

首先,必须升级go到1.11,目前版本是1.14

下面我以我自己升级演示:

### 卸载旧版本,删除对应文件
brew uninstall -f go

### 更新一下brew

brew update

### 安装go
brew install go

上面升级完了,使用 go version看下版本

go version go1.14.1 darwin/amd64

下面设置go mod和go proxy

go env -w GOBIN=/Users/youdi/go/bin
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct // 使用七牛云的

注意: go env -w会将配置写到 GOENV="/Users/youdi/Library/Application Support/go/env"

下面看下我的配置

GO111MODULE="on"
GOARCH="amd64"
GOBIN="/Users/youdi/go/bin"
GOCACHE="/Users/youdi/Library/Caches/go-build"
GOENV="/Users/youdi/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/youdi/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn,direct"
GOROOT="/usr/local/go"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/8m/v_1j4dgs7rzgqq4p_4_8k_nr0000gn/T/go-build221113671=/tmp/go-build -gno-record-gcc-switches -fno-common"

我们看一下,我修改的内容

cat /Users/youdi/Library/Application Support/go/env

GO111MODULE=on
GOBIN=/Users/youdi/go/bin
GOPROXY=https://goproxy.cn,direct
GOSUMDB=off

GO111MODULE

GO111MODULE 有三个值:off, on和auto(默认值)。

  • GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
  • GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
  • GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:

当前目录在GOPATH/src之外且该目录包含go.mod文件
当前文件在包含go.mod文件的目录下面。

当modules功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的 module

我们看下目录:

cd /Users/youdi/go/pkg

├── darwin_amd64
│   ├── github.com
│   ├── go.etcd.io
│   ├── golang
│   ├── golang.org
│   ├── gopkg.in
│   ├── quickstart
│   └── uc.a
├── mod
│   ├── cache
│   ├── github.com
│   ├── golang.org
│   ├── google.golang.org
│   └── gopkg.in
└── sumdb
    └── sum.golang.org

go mod命令

golang 提供了 go mod命令来管理包。

go help mod

Go mod provides access to operations on modules.

Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality.

Usage:

    go mod <command> [arguments]

The commands are:

    download    download modules to local cache
    edit        edit go.mod from tools or scripts
    graph       print module requirement graph
    init        initialize new module in current directory
    tidy        add missing and remove unused modules
    vendor      make vendored copy of dependencies
    verify      verify dependencies have expected content
    why         explain why packages or modules are needed

Use "go help mod <command>" for more information about a command.

go mod 有以下命令:

命令 说明
download download modules to local cache(下载依赖包)
edit edit go.mod from tools or scripts(编辑go.mod)
graph print module requirement graph (打印模块依赖图)
verify initialize new module in current directory(在当前目录初始化mod)
tidy add missing and remove unused modules(拉取缺少的模块,移除不用的模块)
vendor make vendored copy of dependencies(将依赖复制到vendor下)
verify verify dependencies have expected content (验证依赖是否正确)
why explain why packages or modules are needed(解释为什么需要依赖)

比较常用的是 init,tidy, edit

使用go mod管理一个新项目

1. 初始化项目

可以随便找一个目录创建项目,我使用习惯用IDEA进行创建

mkdir Gone
cd Gone
go mod init Gone

查看一下 go.mod文件

module Gone

go 1.14

go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。

go.mod 提供了module, require、replace和exclude 四个命令

  • module 语句指定包的名字(路径)
  • require 语句指定的依赖项模块
  • replace 语句可以替换依赖项模块
  • exclude 语句可以忽略依赖项模块

2. 添加依赖

创建 main.go文件

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

执行 go run main.go 运行代码会发现 go mod 会自动查找依赖自动下载

再查看 go.mod

module Gone

go 1.14

require github.com/gin-gonic/gin v1.6.3

go module 安装 package 的原則是先拉最新的 release tag,若无tag则拉最新的commit

go 会自动生成一个 go.sum 文件来记录 dependency tree

再次执行脚本 go run main.go发现跳过了检查并安装依赖的步骤。

可以使用命令 go list -m -u all 来检查可以升级的package,使用go get -u need-upgrade-package 升级后会将新的依赖版本更新到go.mod * 也可以使用 go get -u 升级所有依赖

去mod包缓存下看看

/Users/youdi/go/pkg/mod/github.com/gin-gonic/gin@v1.6.3

go get升级

  • 运行 go get -u 将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号)
  • 运行 go get -u=patch 将会升级到最新的修订版本
  • 运行 go get package@version 将会升级到指定的版本号version
  • 运行go get如果有版本的更改,那么go.mod文件也会更改

使用replace替换无法直接获取的package

由于某些已知的原因,并不是所有的package都能成功下载,比如:golang.org下的包。

modules 可以通过在 go.mod 文件中使用 replace 指令替换成github上对应的库,比如:

replace (
    golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a
)

go mod发布和使用

参考Roberto Selbach写的go mod入门文章,文末,我给出链接

Creating a Module

如果你设置好go mod了,那你就可以在任何目录下随便创建

$mkdir gomodone
$cd gomodone

在这个目录下创建一个文件say.go

package gomodone

import "fmt" 

// say Hi to someone
func SayHi(name string) string {
   return fmt.Sprintf("Hi, %s", name)
}

初始化一个 go.mod文件

$ go mod init github.com/jacksonyoudi/gomodone
go: creating new go.mod: module github.com/jacksonyoudi/gomodone

查看 go.mod内容如下:

github.com/jacksonyoudi/gomodone
go 1.14

下面我们要将这个module发布到github上,然后在另外一个程序使用

$git init
$vim .gitiiignore
$git commit -am "init"
// github创建对应的repo
$git remote add origin git@github.com:jacksonyoudi/gomodone.git
$git push -u origin master

执行完,上面我们就相当于发布完了。

如果有人需要使用,就可以使用

go get github.com/jacksonyoudi/gomodone

这个时候没有加tag,所以,没有版本的控制。默认是v0.0.0后面接上时间和commitid。如下:

gomodone@v0.0.0-20200517004046-ee882713fd1e

官方不建议这样做,没有进行版本控制管理。

module versioning

使用tag,进行版本控制

making a release

git tag v1.0.0
git push --tags

操作完,我们的module就发布了一个v1.0.0的版本了。

推荐在这个状态下,再切出一个分支,用于后续v1.0.0的修复推送,不要直接在master分支修复

$git checkout -b v1
$git push -u origin v1

use our module

上面已经发布了一个v1.0.0的版本,我们可以在另一个项目中使用,创建一个go的项目

$mkdir Gone
$cd Gone
$vim main.go
package main

import (
    "fmt"
    "github.com/jacksonyoudi/gomodone"
)

func main() {
    fmt.Println(gomodone.SayHi("Roberto"))
}

代码写好了,我们生成 go mod文件

go mod init Gone

上面命令执行完,会生成 go mod文件

看下mod文件:

module Gone

go 1.14

require (
    github.com/jacksonyoudi/gomodone v1.0.0
)
$go mod tidy
go: finding module for package github.com/jacksonyoudi/gomodone
go: found github.com/jacksonyoudi/gomodone in github.com/jacksonyoudi/gomodone v1.0.0

同时还生成了go.sum, 其中包含软件包的哈希值,以确保我们具有正确的版本和文件。

github.com/jacksonyoudi/gomodone v1.0.1 h1:jFd+qZlAB0R3zqrC9kwO8IgPrAdayMUS0rSHMDc/uG8=
github.com/jacksonyoudi/gomodone v1.0.1/go.mod h1:XWi+BLbuiuC2YM8Qz4yQzTSPtHt3T3hrlNN2pNlyA94=
github.com/jacksonyoudi/gomodone/v2 v2.0.0 h1:GpzGeXCx/Xv2ueiZJ8hEhFwLu7xjxLBjkOYSmg8Ya/w=
github.com/jacksonyoudi/gomodone/v2 v2.0.0/go.mod h1:L8uFPSZNHoAhpaePWUfKmGinjufYdw9c2i70xtBorSw=

这个内容是下面的,需要操作执行的结果

go run main.go就可以运行了

Making a bugfix release

假如fix一个bug,我们在v1版本上进行修复

修改代码如下:

// say Hi to someone
func SayHi(name string) string {
-       return fmt.Sprintf("Hi, %s", name)
+       return fmt.Sprintf("Hi, %s!", name)
}

修复好,我们开始push

$ git commit -m "Emphasize our friendliness" say.go
$ git tag v1.0.1
$ git push --tags origin v1

Updating modules

刚才fix bug,所以要在我们使用项目中更新

这个需要我们手动执行更新module操作

我们通过使用我们的好朋友来做到这一点go get:

  • 运行 go get -u 以使用最新的 minor 版本或修补程序版本(即它将从1.0.0更新到例如1.0.1,或者,如果可用,则更新为1.1.0)
  • 运行 go get -u=patch 以使用最新的 修补程序 版本(即,将更新为1.0.1但不更新 为1.1.0)
  • 运行go get package@version 以更新到特定版本(例如github.com/jacksonyoudi/gomodone@v1.0.1

目前module最新的也是v1.0.1

// 更新最新
$go get -u
$go get -u=patch
//指定包,指定版本
$go get github.com/jacksonyoudi/gomodone@v1.0.1

操作完,go.mod文件会修改如下:

module Gone

go 1.14

require (
    github.com/jacksonyoudi/gomodone v1.0.1
)

Major versions

根据语义版本语义,主要版本与次要版本 不同。主要版本可能会破坏向后兼容性。从Go模块的角度来看,主要版本是 完全不同的软件包。乍一看这听起来很奇怪,但这是有道理的:两个不兼容的库版本是两个不同的库。

比如下面修改,完全破坏了兼容性。

package gomodone

import (
    "errors"
    "fmt"
)

// Hi returns a friendly greeting
// Hi returns a friendly greeting in language lang
func SayHi(name, lang string) (string, error) {
    switch lang {
    case "en":
        return fmt.Sprintf("Hi, %s!", name), nil
    case "pt":
        return fmt.Sprintf("Oi, %s!", name), nil
    case "es":
        return fmt.Sprintf("¡Hola, %s!", name), nil
    case "fr":
        return fmt.Sprintf("Bonjour, %s!", name), nil
    default:
        return "", errors.New("unknown language")
    }
}

如上,我们需要不同的大版本,这种情况下

修改 go.mod如下

module github.com/jacksonyoudi/gomodone/v2

go 1.14

然后,重新tag,push

$ git commit say.go -m "Change Hi to allow multilang"
$ git checkout -b v2 # 用于v2版本,后续修复v2
$ git commit go.mod -m "Bump version to v2"
$ git tag v2.0.0
$ git push --tags origin v2

Updating to a major version

即使发布了库的新不兼容版本,现有软件 也不会中断,因为它将继续使用现有版本1.0.1。go get -u 将不会获得版本2.0.0。

如果想使用v2.0.0,代码改成如下:

package main

import (
    "fmt"
    "github.com/jacksonyoudi/gomodone/v2"
)

func main() {
    g, err := gomodone.SayHi("Roberto", "pt")
    if err != nil {
        panic(err)
    }
    fmt.Println(g)
}

执行 go mod tidy

go: finding module for package github.com/jacksonyoudi/gomodone/v2
go: downloading github.com/jacksonyoudi/gomodone/v2 v2.0.0
go: found github.com/jacksonyoudi/gomodone/v2 in github.com/jacksonyoudi/gomodone/v2 v2.0.0

当然,两个版本都可以同时使用, 使用别名

如下:

package main

import (
    "fmt"
    "github.com/jacksonyoudi/gomodone"
    mv2 "github.com/jacksonyoudi/gomodone/v2"
)

func main() {
    g, err := mv2.SayHi("Roberto", "pt")
    if err != nil {
        panic(err)
    }
    fmt.Println(g)

    fmt.Println(gomodone.SayHi("Roberto"))
}

执行一下 go mod tidy

Vendoring

默认是忽略vendor的,如果想在项目目录下有vendor可以执行下面命令

$go vendor

当然,如果构建程序的时候,希望使用vendor中的依赖,

$ go build -mod vendor

IDEA下开发GO

  • 创建go项目

  • 创建完项目,会自动生成go mod文件
    如果需要修改,可以手动修改,加入git等操作
  • 写业务逻辑代码

  • 解决依赖,更新go.mod

  • go build

总结

到此这篇关于go mod详细使用教程的文章就介绍到这了,更多相关go mod使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解决go mod私有仓库拉取的问题

    用go mod的时候应该会遇到无法拉取私有仓库的问题 从你gitlab平台生成一个token,在~/.gitcoinfig中 [http]下增加extraheader = PRIVATE-TOKEN: 你的token [url]下增加 insteadOf = https://gitlab.你的gitlab服务器.com 如果还不生效则增加环境变量后尝试: export GOPRIVATE=gitlab.你的gitlab服务器.cn 补充:go module 引用码云(或其他私有仓库)的配置 go

  • win10下go mod配置方式

    这是因为获取golang.org/x/...时需要翻墙,而我这里没有翻墙,不过没关系 设置下代理即可: // bash mac export GOPROXY=https://goproxy.io // powershell windows $env:GOPROXY = https://goproxy.io 然后再当前目录下 用powershell 执行命令: go mod download 相关命令: go mod init:初始化modules go mod download:下载module

  • go mod的使用方法小结

    目录 前言 1.go modules的基本介绍 1.1 提供的命令 1.2 提供的环境变量 1.2.1 说明 2.go modules的基本使用 2.1 初始化项目 3.使用go mod发布自己的包 3.1 发布公开的包 3.2 发布私有包 前言 对于多个项目来说,把所有的源码都放在GOPATH下的src目录下非常的不方便.golang给我们提供了一个叫go mod的命令来脱离src目录,方便我们管理go项目.go mod 是go官方提供的go版本管理的一个方案,目前1.15已经可用于生产环境.

  • go mod 使用旧版本 版本号指定方式

    在使用go mod的过程中,发现不容易指定版本号 尤其是没有打tag的,不知道怎么指定版本号, 不知道有哪版本号 正常使用都没有问题,但是当引用的项目用了旧的代码, 这时候必须使用旧的版本,无法指定版本,不知道如何入手 尤其是k8s.io不知道是什么鬼, 从哪里看它的代码,只知道github.com 这个时候在 go.mod文件中 require 里面加上 github.com/kubernetes/cloud-provider 2bf8e45 此时会自动生成版本号, 其中 2bf8e45 这个

  • go mod详细使用教程

    目录 前言 使用go path问题 govendor go mod介绍 如何使用go mod GO111MODULE go mod命令 使用go mod管理一个新项目 1. 初始化项目 2. 添加依赖 go get升级 使用replace替换无法直接获取的package go mod发布和使用 Creating a Module module versioning making a release use our module Making a bugfix release Updating m

  • ftp服务器FileZilla Server详细配置教程

    FileZilla Server下载安装完成后,必须启动软件进行设置,由于此软件是英文,本来就是一款陌生的软件,再加上英文,配置难度可想而知,小编从网上找到一篇非常详细的教程进行整理了一番,确保读到这篇教程的同学都能够进行免费ftp服务器FileZilla Server配置. 运行FileZilla Server Interface.exe,得到以上界面,如果是第一次进入,直接点击ok即可.我们可以在「Administrator password:」栏位中输入本服务器Filezilla服务的密码

  • ORACLE 11g从 11.2.0.1升级到11.2.0.4 详细实战教程

     1.准备安装 查看当前oracle版本,确定是比较旧的11.2.0.1 [oracle@hch_test_121_90 ~]$ rlwrap sqlplus / as sysdba SQL*Plus: Release 11.2.0.1.0 Production on Fri Mar 17 15:20:45 2017 Copyright (c) 1982, 2009, Oracle. All rights reserved. Connected to: Oracle Database 11g E

  • win10 下安装 mysql 5.7.14 详细图文教程

    1. 下载:http://dev.mysql.com/downloads/mysql/ 2.解压zip文件夹到指定的目录 3.添加环境变量 右击我的电脑->属性->高级系统设置->高级->环境变量-> 在系统变量中找到变量Path,点击编辑,在变量值最后面添加解压路径,路径要到bin文件夹下的路径,如: 4.进入解压路径,修改路径下的my-default配置文件: 5.以管理员权限运行cmd,初始化mysql数据库,这时会创建刚刚配置的data目录和一些数据库系统用的基本表

  • MySQL(win7x64 5.7.16版本)下载、安装、配置与使用的详细图文教程

    结合网上的资料,自己亲自的去安装了一次MySQL,安装版本是win7x64 5.7.16. 在安装过程中出现并解决了如下问题: 1."MySQL 服务无法启动 服务没报告任何错误" 2.启动MySQL服务的时候,提示"发生系统错误 2,系统找不到指定的文件". 3.TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_d... 4.initialize specified

  • Mybatis的详细使用教程

    Mybatis所需要的jar包: 需要引用两个jar包,一个是mybatis,另一个是MySQL-connector-Java,如果是maven工程的话,pom里如下添加依赖就可以了. <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.3</version> </dependency>

  • Yii2组件之多图上传插件FileInput的详细使用教程

    在前面给大家写个有关文件上传的文章,包括最基本的yii2文件上传.异步上传到又拍云以及百度编辑器图片上传的问题,貌似不说点多图上传的就不完美. 今天介绍一款多图上传的插件 FileInput,至于为什么选中了TA作为我们上传的插件,一来这货跟Yii2有一腿,用起来方便:二来嘛,用这个插件不仅添加的时候好操作,修改的时候也可以直接通过异步的方式将图片悄无声息的删掉:最值得一提的是,界面效果融合了bootstrap,清爽简洁美观,看起来舒服. 说重点,看具体步骤 首先还是先安装组件 复制代码 代码如

  • MySQL 5.7.20绿色版安装详细图文教程

    首先大家了解一下什么是MySQL? MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle旗下产品.它是一种关系数据库管理系统,使用的SQL语言是用于访问数据库的最常用标准化语言.MySQL软件采用了双授权政策,分为社区版和商业版,由于其体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库. 下面本文已MySQL Community Server 5.7.20为例,主要讲述一下mysql-5.7.20-wi

  • VMware下CentOS静默安装oracle12.2详细图文教程

    环境准备: VMware+CentOS,jdk 一.校验系统磁盘大小 1.命令 df -h 保证可用磁盘大小15GB(包括oracle安装时需要空间7.5GB + oracle安装zip包接近3G+安装包解压文件3G) 如果磁盘不满足,安装会失败,需要扩容! 二.安装准备 1.创建运行oracle数据库的系统用户和用户组 groupadd oinstall groupadd dba useradd -g oinstall -g dba -m oracle passwd oracle #不用管提示

  • Centos7.3安装Redis4.0.6详细图文教程

    首先进入待安装的目录: wget获取安装包 解压安装包 安装gcc环境编译依赖 对解压的安装包进行编译 编译后产生src文件夹,里面包含常用的redis-cli,redis-server,redis-check-aof,redis-check-rdb,redis-sentinel等,需要将这些常用的放到/usr/local/bin下 编译安装 启动redis 修改redis.conf的后台启动 查看redis进程 总结 以上所述是小编给大家介绍的Centos7.3安装Redis4.0.6详细图文

随机推荐