What is Go Mod

Go Modules is a new feature in Golang 1.11.

So the question is, what problem does it solve? Actually, the core problem is that it can be convenient without the concept of GoPath, but when you don’t know how to use it, you find it very difficult to use.

Once the PS: go.mod file is created, its contents will be fully controlled by Go Toolchain. Go Toolchain modifies and maintains go.mod files while executing various commands, such as Go Get, Go Build, and Go Mod.

Simple to use

For example, if we have a requirement that we want to create a new project called Go-Kit-demo, and we need the Go-Kit dependencies, what do we do

The first step

% mkdir go-kit-demo

% cd go-kit-demo

% go mod init go-kit-demo // Initialize a project named go-kit-demo. This path is actually your path relative to GOPATH. Later your package will import "go-kit-demo/util" or something like that

% ls
go.mod // There is an extra file

% cat go.mod
module go-kit-demo // Module name

go 1.13 / / go version

% go mod edit -require=github.com/go-kit/kit@latest // Add a go-kit dependency

% go mod download // Download dependencies

% cat go.mod
module go-kit-demo

go 1.13

require github.com/go-kit/kit v010.. 0 // indirect

% ls
go.mod    go.sum/ / check package
Copy the code

The second step, in fact, is to need the code, so that the editor can find, obviously, currently go official does not support, need a third party.

But you can’t use go-Kit directly here because Goland doesn’t support this module dependency, so you have to import it into vendor.

Here is a recommended tool that can package dependencies into vendor, which is quite nice

https://github.com/nomad-software/vend
Copy the code

Just follow the instructions

go get github.com/nomad-software/vend
Copy the code

It looks something like this

~ /go/code/mode-test % vend
vend: copying cloud.google.com/go (v034.. 0)
vend: copying github.com/BurntSushi/toml (v03.1.)
vend: copying github.com/Knetic/govaluate (v3. 01.0.201710220036109 -aa49832a739+incompatible)
vend: copying github.com/Shopify/sarama (v119.. 0)
vend: copying github.com/Shopify/toxiproxy (v21.4.+incompatible)
vend: copying github.com/VividCortex/gohistogram (v1. 0. 0)
vend: copying github.com/afex/hystrix-go (v0. 0. 0- 20180502004556.-fa1af6a1f4f5)
vend: copying github.com/alecthomas/template (v0. 0. 0- 20190718012654.-fb15b899a751)
vend: copying github.com/alecthomas/units (v0. 0. 0- 20190717042225.-c3de453c63f4)
vend: copying github.com/apache/thrift (v013.. 0)
vend: copying github.com/armon/circbuf (v0. 0. 0- 20150827004946.-bbbad097214e)
Copy the code

Therefore, it is very convenient. You can copy all the dependencies to vendor, and then you can use them happily.

Other commands

For example, the problem of domestic source needs to be modified

export GOPROXY=https://goproxy.cn
Copy the code

The second is that, for example, earlier versions of Go may require the Go mod to be forcibly enabled

export GO111MODULE=on
Copy the code

I will not introduce other commands, for example, there is a common may be go mod vendor, will rely on copy to the vendor directory, but the problem is that it will only copy the code depends on things, so we sometimes inconvenient, therefore, need to use the tool I recommended above.

For instance

go get github.com/go-kit/kit // The dependency will be added to the go.mod file, which means there is no need to manually execute go mod edit-require =github.com/go-kit/kit@latest
Copy the code

There are other orders

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/ / download
	edit        edit go.mod from tools or scripts/ / edit go. Mod
	graph       print module requirement graph// Print dependencies
	init        initialize new module in current directory / / initialization
	tidy        add missing and remove unused modules // Delete useless dependencies
	vendor      make vendored copy of dependencies / / copy to the vendor
	verify      verify dependencies have expected content / / check
	why         explain why packages or modules are needed

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

Mod provides four commands: module, require, replace, and exclude

  • moduleStatement specifies the name of the package
  • requireStatement specifies the dependency module
  • replaceStatement can replace dependency modules
  • excludeStatement can ignore dependency modules

In fact, these do not need care

How to solve the local warehouse

Requirements, we now have another project that we need to introduce.

PS: When you enter a company, you usually put the company code under the same directory, that is, the upper directory is the same, so we also follow this specification, the reason is actually very simple, because it is convenient environment.

Initialize A\B project, named demo-1, demo-2

~ /go/code/test % cd demo- 1~ /go/code/test/demo- 1 % ls
~/go/code/test/demo- 1 % go mod init demo- 1
go: creating new go.mod: module demo- 1
Copy the code

Our current directory structure looks like this:

~ /go/ Code/Test % Tree.. ├──- 1│ └ ─ ─goThe mod └ ─ ─ the demo2 -├─ API │ ├─ userServicego└ ─ ─go.mod

3 directories, 3 files
Copy the code

For the demo-1 project, we need to use the user-service interface

package api

type UserService interface{
	GetUserInfo()*UserInfo
}

type UserInfo struct{
	Name string `json:"name"`
	Age  int  `json:"age"`
}
Copy the code

All you need to do is make a substitution in Demo-1, as shown in the following figure

module demo- 1

go 1.13

require demo_2 v0. 0. 0replace demo_2 => .. /demo2 -
Copy the code

And then we can have fun with Demo-1

package main

import (
	"demo_2/api"
	"fmt"
)

func main(a) {
	info := api.UserInfo{
		Name: "tom",
		Age:  18,
	}
	fmt.Println(info)
}
Copy the code

So in reality, depending on the package to update, need to timely pull the master, how to do this update, very simple, just need to run the go mod vendor to pull again

One thing to note is that local packages do not validate hash

Why do I have to use the vendor directory

  • 1, the dependency may be local, may be private warehouse, cannot be resolved
  • 2. The production environment may slow down
  • 3. There is no universal solution, let go develop later

Where “go build-mod =vendor” means that the vendor mode is forcibly enabled, and dependencies will only be found in the vendor directory, and other dependencies will not be cared, nor will they be found in the network environment.

How to solve the private warehouse

All public warehouses, no big deal, but what about private

All three are theoretically feasible, but all have flaws.

Goproxy itself does not solve the problem of obtaining private project code from GitLab server, nor does it have a mature authentication mechanism. Therefore, static public code is preferable.

For example: goproxy.cn/

Nginx proxy, also does not solve the problem of authentication, I configured a proxy, SSL authentication failed (weak), in theory this solution is the best solution.

Go Replace, which needs to be added in every project, is complicated with update dependencies.

So the solution is, again, local dependency.

At present, online solutions are to modify the local Git, configuration, through the configuration of some information, baidu, but there are still problems. It is better to set up a proxy and solve the problem from the proxy layer, for example, go Proxy.