Think Deep,Work Lean

go mod使用

Posted on By zack

  • content

包操作

列出当前module及依赖包

go list -m all  

升级某一个依赖

go get golang.org/x/text

列出某一个可用的依赖的版本

go list -m -versions rsc.io/sampler

将某个包升级至指定版本

go get rsc.io/sampler@v1.3.1

列出某一系列包(匹配该前缀所有的包):

go list -m rsc.io/q...

go mod有坑,如果要看一个包的当前版本是什么,很容易直接去看go.mod 中定义的版本是多少,而没有去看replace中是否还有重定向;如果要看包的最终版本,一定义要搜索下是否有replace,或是直接用命令来看下最终版本,如:

$ go list -m github.com/prometheus/...
github.com/prometheus/client_golang v1.8.0 => github.com/prometheus/client_golang v0.9.4
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 => github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90
github.com/prometheus/common v0.14.0 => github.com/prometheus/common v0.4.0
github.com/prometheus/procfs v0.0.2 => github.com/prometheus/procfs v0.0.2
github.com/prometheus/prometheus v1.8.2 => github.com/prometheus/prometheus v1.8.2

查看包中可以使用的方法:

go doc rsc.io/quote/v3

关于go mod

v.大版本.小版本.patch版本

大版本一般是对外函数发生了变化,有不兼容的包

小版本一般是兼容的,如只是增加了一些function,此时只用改变小版本

patch版本,一般是有bug fix

若:大版本为0或是有后缀,则不是不稳定版本,如 v0.2.0 may not be compatible with v0.1.0, and v1.5.0-beta may not be compatible with v1.5.0.v1.2.3-pre

若:如果要使用v2或是以上版本,需要使用 /v2 /v3 这种形式进行区分。参考

在更新的时候,会查看Module的最近一次tag,如果没有tag,会使用最近一次的+提交记录

go list -m all
example.com/hello
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
rsc.io/quote v1.5.2
rsc.io/sampler v1.3.0

版本分两种:Pseudo-versions 和 semantic versions

A module version like v1.2.3 is introduced by tagging a revision in the underlying source repository. Untagged revisions can be referred to using a “pseudo-version” like v0.0.0-yyyymmddhhmmss-abcdefabcdef, where the time is the commit time in UTC and the final suffix is the prefix of the commit hash. The time portion ensures that two pseudo-versions can be compared to determine which happened later, the commit hash identifes the underlying commit, and the prefix (v0.0.0- in this example) is derived from the most recent tagged version in the commit graph before this commit.

时间是为了方便在比较两个版本时候,确定输出先后顺序;

go build打包时参数: -mod=mod 不使用vendor -mod=vendor,使用vendor

go get github.com/gorilla/mux@latest    # same (@latest is default for 'go get')
go get github.com/gorilla/mux@v1.6.2    # records v1.6.2
go get github.com/gorilla/mux@e3702bed2 # records v1.6.2
go get github.com/gorilla/mux@c856192   # records v0.0.0-20180517173623-c85619274f5d
go get github.com/gorilla/mux@master    # records current meaning of master

In semantic versioning, major version v0 is for initial development, indicating no expectations of stability or backwards compatibility. Major version v0 does not appear in the module path, because those versions are preparation for v1.0.0, and v1 does not appear in the module path either.

v0开头的不需要包含主版本,原因是v0是开发版本,接下来的稳定版本是v1。

关于go.sum

The form of each line in go.sum is three fields:

Each known module version results in two lines in the go.sum file. The first line gives the hash of the module version’s file tree. The second line appends “/go.mod” to the version and gives the hash of only the module version’s (possibly synthesized) go.mod file. The go.mod-only hash allows downloading and authenticating a module version’s go.mod file, which is needed to compute the dependency graph, without also downloading all the module’s source code.

The hash begins with an algorithm prefix of the form “h:". The only defined algorithm prefix is "h1:", which uses SHA-256.

In day-to-day development, the checksum of a given module version should never change. Each time a dependency is used by a given main module, the go command checks its local cached copy, freshly downloaded or not, against the main module’s go.sum. If the checksums don’t match, the go command reports the mismatch as a security error and refuses to run the build.

When this happens, proceed with caution: code changing unexpectedly means today’s build will not match yesterday’s, and the unexpected change may not be beneficial.

关于如何更新包

This default version selection can be overridden by adding an @version suffix to the package argument, as in ‘go get golang.org/x/text@v0.3.0’. The version may be a prefix: @v1 denotes the latest available version starting with v1. See ‘go help modules’ under the heading ‘Module queries’ for the full query syntax.

For modules stored in source control repositories, the version suffix can also be a commit hash, branch identifier, or other syntax known to the source control system, as in ‘go get golang.org/x/text@master’. Note that branches with names that overlap with other module query syntax cannot be selected explicitly. For example, the suffix @v2 means the latest version starting with v2, not the branch named v2.

If a module under consideration is already a dependency of the current development module, then get will update the required version. Specifying a version earlier than the current required version is valid and downgrades the dependency. The version suffix @none indicates that the dependency should be removed entirely, downgrading or removing modules depending on it as needed.

The version suffix @latest explicitly requests the latest minor release of the module named by the given path. The suffix @upgrade is like @latest but will not downgrade a module if it is already required at a revision or pre-release version newer than the latest released version. The suffix @patch requests the latest patch release: the latest released version with the same major and minor version numbers as the currently required version. Like @upgrade, @patch will not downgrade a module already required at a newer version. If the path is not already required, @upgrade and @patch are equivalent to @latest.

Although get defaults to using the latest version of the module containing a named package, it does not use the latest version of that module’s dependencies. Instead it prefers to use the specific dependency versions requested by that module. For example, if the latest A requires module B v1.2.3, while B v1.2.4 and v1.3.1 are also available, then ‘go get A’ will use the latest A but then use B v1.2.3, as requested by A. (If there are competing requirements for a particular module, then ‘go get’ resolves those requirements by taking the maximum requested version.)

The -u flag instructs get to update modules providing dependencies of packages named on the command line to use newer minor or patch releases when available.

The -u flag instructs get to update modules providing dependencies of packages named on the command line to use newer minor or patch releases when available. Continuing the previous example, ‘go get -u A’ will use the latest A with B v1.3.1 (not B v1.2.3). If B requires module C, but C does not provide any packages needed to build packages in A (not including tests), then C will not be updated.

区分module与package

go get modulego get package有区别

If an argument names a module but not a package (because there is no Go source code in the module’s root directory), then the install step is skipped for that argument, instead of causing a build failure. For example ‘go get golang.org/x/perf’ succeeds even though there is no code corresponding to that import path.

Note that package patterns are allowed and are expanded after resolving the module versions. For example, ‘go get golang.org/x/perf/cmd/…’ adds the latest golang.org/x/perf and then installs the commands in that latest version.

The -d flag instructs get to download the source code needed to build the named packages, including downloading necessary dependencies, but not to build and install them.

go get -d 只下载包不build包

安装包和依赖

go install

位于$GOPATH/bin下面

Executables are installed in the directory named by the GOBIN environment variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set. Executables in $GOROOT are installed in $GOROOT/bin or $GOTOOLDIR instead of $GOBIN.

go mod download

go mod graph

go mod edit

go mod vendor

go mod init

go mod tidy

go mod verify

Verify checks that the dependencies of the current module, which are stored in a local downloaded source cache, have not been modified since being downloaded. If all the modules are unmodified, verify prints “all modules verified.” Otherwise it reports which modules have been changed and causes ‘go mod’ to exit with a non-zero status.

go mod why

https://golang.org/cmd/go/#hdr-Pseudo_versions

内部包

Code in or below a directory named “internal” is importable only by code in the directory tree rooted at the parent of “internal”. Here’s an extended version of the directory layout above:

/home/user/go/
    src/
        crash/
            bang/              (go code in package bang)
                b.go
        foo/                   (go code in package foo)
            f.go
            bar/               (go code in package bar)
                x.go
            internal/
                baz/           (go code in package baz)
                    z.go
            quux/              (go code in package main)
                y.go

The code in z.go is imported as “foo/internal/baz”, but that import statement can only appear in source files in the subtree rooted at foo. The source files foo/f.go, foo/bar/x.go, and foo/quux/y.go can all import “foo/internal/baz”, but the source file crash/bang/b.go cannot.

更新到最新的修订版(只改bug的版本)

go get -u=patch github.com/gogf/gf

替代只能翻墙下载的库

go mod edit -replace=golang.org/x/crypto@v0.0.0=github.com/golang/crypto@latest
go mod edit -replace=golang.org/x/sys@v0.0.0=github.com/golang/sys@latest

go mod edit -replace=github.com/prometheus/client_golang@v0.9.4=github.com/prometheus/client_golang@latest

实战

更新包,如现在要更新这个包

#go.mod
github.com/kiali/kiali => github.com/kubesphere/kiali v0.15.1-0.20200213040359-608aece2aa66

步骤为:在开发时,首先把它替换为自己仓库的包

github.com/kiali/kiali => github.com/kubesphere/kiali v0.15.1-0.20200213040359-608aece2aa66

直接获取commitID后,替换后更新

go get -d github.com/kiali/kiali 

go get -d xxx: 只下载源码包,不 go install go get xxx: 下载源码包后,go install成二进制(会有go build操作),放到$PATH/bin

只要有commitID,其余信息不对会有提示,如时间/commitID长度等,对于最前面的版本,因为是在0.15.0的基础上改的,因此只要大于这个tag号就行。

上面的方法太复杂了。

如果要更新每个版本,采用以下的步骤:

拿到commit对应的版本号:

go get github.com/kubesphere/kiali@0c2b977257d46755d8b6bdd6d6a91ad5a5338630

包更新没有问题后,执行同步到vendor

go mod vendor

参考:

https://blog.golang.org/using-go-modules

https://golang.org/ref/mod

https://golang.org/ref/mod#non-module-compat