当前位置:网站首页>Go's package management learning notes

Go's package management learning notes

2022-06-24 05:29:00 Johns

One .Go Package management history

Most languages have version management tools , such as nodejs Of npm,python Medium pip,java Inside maven, however go Language version management has gone through a long evolution :

image.png
  • Go1.5 before ,golang Use GOPATH Way to manage code .
    • Code development must be in go path src Under the table of contents .
    • There is no version for dependent packages , All refer to master The latest code . At this stage, you can only manage dependencies manually .

Start Golang There is a reason for this design , because Google It's a practice Mono Repo( Put all relevant projects in one warehouse ) The company . But more companies and organizations use Multi Repo( Divided into multiple warehouses by module ),GOPATH At least it solves the problem of third-party source code dependency , Although it is not perfect .

  • Go1.5 after , It was proposed external packages The concept of , So there was Go Vendor
    • Solved package dependency , Use a configuration file to manage
    • All dependent packages are downloaded to the project vendor Next , Each project will have a copy of , You can't boast that projects share public dependencies .
    • The dependent package lookup path becomes src/vendor ===> GOPATH.
    • In this mode , Will download the source code that the third party depends on to the local , Different projects can have their own different vendor, The versioning problem is still not solved .
    • The default is to ignore vendor Of , If you want to have vendor It can be executed go vendor command . Of course , If you build a program , Want to use vendor Dependency in go build -mod vendor
  • Go1.12 After version , Use go modules Package management
    • No more with gopath For project space , Use Modules Enable a new file go.mod Record module Meta information of , It contains the version information of the dependent package .
    • A will be generated within the project go.mod file , List package dependencies . All incoming third-party packages will accurately specify the version number for the transferred packages , It can be used replace Declaration replacement , No need to change code .
    • adopt GO111MODULE control ,GO111MODULE There are three values off/on/auto( The default value is ), The definition is as follows : off :go The command line will not support module function , Looking for dependency packages will follow the old version through vendor Catalog or GOPATH Pattern to find . on:go The command line will use modules, And not at all GOPATH Directory lookup . auto: The default value is , When the project is in $GOPATH/src Outside , And the root directory of the project has go.mod When you file , Enable module support . When modules When the function is enabled , The storage location of the dependency package is changed to $GOPATH/pkg, Allow the same package Multiple versions coexist , And multiple projects can share the cache module.

Two .GO Module An introduction to the

stay go1.12 before , We know golang The dependency package management of is only available .go1.12 after ,go mod It really solves several core problems of dependent package management .

go adopt go mod Command to manage dependent packages . The following commands are provided , I usually use more go mod tidy

download

download modules to local cache( Download dependency package )

edit

edit go.mod from tools or scripts( edit go.mod)

graph

print module requirement graph ( Print module dependency graph )

verify

initialize new module in current directory( Initialize... In the current directory mod)

tidy

add missing and remove unused modules( Pull the missing module , Remove unused modules )

vendor

make vendored copy of dependencies( Copy dependency to vendor Next )

verify

verify dependencies have expected content ( Verify that the dependency is correct )

why

explain why packages or modules are needed( Explain why you need to rely )

Go module most important of all go.mod Definition of documents , It is used to mark a module And its dependent libraries and their versions . It's kind of like Maven Inside pom.xml file .

Go module follow Semantic version specification 2.0.0. Semantic version specification 2.0.0 Specifies the format of the version number , The version format is defined as : The major version number . Sub version number . Revision number , The rules for increasing version number are as follows :

  1. The major version number : When you do incompatible API modify ,
  2. Sub version number : When you do a downward compatible feature add ,
  3. Revision number : When you do a downward compatibility problem fix .

The previous version number and version compilation information can be added to “ The major version number . Sub version number . Revision number ” Behind , As an extension .

So let's see go.mod What exactly does your file look like :

module github.com/panicthis/modfile

go 1.15

require (
github.com/cenk/backoff v2.2.1+incompatible
github.com/coreos/bbolt v1.3.3
github.com/edwingeng/doublejump v0.0.0-20200330080233-e4ea8bd1cbed
github.com/stretchr/objx v0.3.0 // indirect
github.com/stretchr/testify v1.7.0
go.etcd.io/bbolt v1.3.6 // indirect
go.etcd.io/etcd/client/v2 v2.305.0-rc.1
go.etcd.io/etcd/client/v3 v3.5.0-rc.1
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b // indirect
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 // indirect
)

exclude (
go.etcd.io/etcd/client/v2 v2.305.0-rc.0
go.etcd.io/etcd/client/v3 v3.5.0-rc.0
)

go.mod There will be another go.sum file , It contains the expected cryptographic hash of the specific module version content ,go Command to use go.sum The file ensures that the future download retrieval of these modules is the same bit as the first download , To ensure that the modules on which the project depends are not accidentally changed , Whether it's out of malice 、 Accidents or other reasons .

【1】module path

go.mod The first line is module path, Warehouse is generally used +module name Method definition of . So we get a module When , You can go to its warehouse to query , Or let go proxy Query in the warehouse .

If your version is greater than or equal to 2.0.0, according to Go The specification of , You should add major The suffix ,module path Change to the following way :

module github.com/panicthis/modfile/v2
module github.com/panicthis/modfile/v3

And when you reference code , Plus v2v3vx suffix , For and others major Version to distinguish . This is a very strange agreement , The benefit is that you can use different types of dependent libraries in a project major edition , They can coexist .

【2】go directive

The second line is go directive. The format is go 1.xx, It doesn't mean what you're currently using Go edition , But name what your code needs Go The minimum version of .

require Section lists the dependent libraries required by the project and their versions , Except formal v1.3.0 Outside this version , There are also some strange versions and comments , So what do they mean ?

We don't need to introduce the official version number , We all know :

github.com/coreos/bbolt v1.3.3
【3】 Pseudo version number
github.com/edwingeng/doublejump v0.0.0-20200330080233-e4ea8bd1cbed

The version number in the above library is a pseudo version number v0.0.0-20200330080233-e4ea8bd1cbed, This is a go module A similar semantic compliant version is generated for it 2.0.0 edition , In fact, this library has not released this version . Officially, there is no release version of this dependency Library , and go module You need to specify a certain version of this library , That's why I created such a pseudo version number .

go module The goal is to go.mod Mark all the dependencies of the project and the version they determine .

there 20200330080233 This is the time of submission , The format is yyyyMMddhhmmss, and e4ea8bd1cbed This is the version commit id, Through this field , You can determine the specific version of the library .

And the front v0.0.0 There may be multiple generation methods , It mainly depends on you commit Of base version:

  • vX.0.0-yyyymmddhhmmss-abcdefabcdef: without base version, So that is vX.0.0 In the form of
  • vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef: If base version Is a pre release version , such as vX.Y.Z-pre, Then it uses vX.Y.Z-pre.0 In the form of
  • vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef: If base version Is an officially released version , Then it is patch Sign plus 1, Such as vX.Y.(Z+1)-0

The pseudo version number exists mainly because the submitted record is not marked tag, I hit tag You can use it directly tag Version number of .

【4】indirect Indirect reference
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b // indirect
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 // indirect

Some libraries are added to the back indirect suffix , What does that mean .

To sum up in one sentence , Used this library indirectly , But it's not listed in one go.mod in , Of course, this sentence is not too accurate , To be more precise, one of the following situations will affect this Kuga indirect suffix :

  • Current project dependency A, however A Of go.mod Omitted B, Then it will be in the current project go.mod Add B, Add indirect notes
  • Current project dependency A, however A No, go.mod, It will also be in the current project go.mod Add B, Add indirect notes
  • Current project dependency A,A Depend on B, When the A When demoted , Degraded A No longer dependent on B, This is the time B Just mark indirect notes
【5】incompatible Nonstandard dependency

Some libraries are added to the back incompatible suffix , But if you look at these projects , They're just released v2.2.1 Of tag, did not +incompatible suffix .

github.com/cenk/backoff v2.2.1+incompatible

These libraries use go.mod Management of , But unfortunately , Although the versions of these libraries major Version is greater than or equal to 2 了 , But their module path Still not added in v2, v3 This suffix .

therefore go module Mark them as incompatible Of , Although you can quote , But in fact, they do not meet the specifications .

【6】exclude Exclude dependence

If you want to skip a version of a dependent Library in your project , You can use this paragraph .

exclude (
go.etcd.io/etcd/client/v2 v2.305.0-rc.0
go.etcd.io/etcd/client/v3 v3.5.0-rc.0
)

such ,Go When selecting the version , Will actively skip these versions , For example, you use go get -u ...... perhaps go get github.com/xxx/[email protected] When ordered , Will execute version query The action of , These versions are not under consideration .

【7】replace Replace dependency

replace It is also a common means , It is used to solve some wrong dependent library references or debug dependent Libraries .

replace github.com/coreos/bbolt => go.etcd.io/bbolt v1.3.3
replace github.com/panicthis/A v1.1.0 => github.com/panicthis/R v1.8.0
replace github.com/coreos/bbolt => ../R

such as etcd v3.3.x Incorrect use in version of github.com/coreos/bbolt As bbolt Of module path, In fact, this library is in its own go.mod Declarative module path yes go.etcd.io/bbolt, And such as etcd The use of grpc There is a problem with the version , You can also pass replace Replace with the required grpc edition . Even if you think there is a problem with a dependency Library , own fork Modify locally , Want to debug , You can also replace it with a local folder .

replace You can replace all versions of a library with a specific version of another library , You can also replace a specific version of one library with a specific version of another .

原网站

版权声明
本文为[Johns]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/08/20210811142710886D.html