Давайте разбираться в зависимости Go Modues/GOPATH вместе

Go

Давайте вместе разберемся с управлением зависимостями Go Модули Go/GOPATH

Не скупитесь на критику и идеи, пожалуйста, оставьте сообщение, и мы добьемся прогресса вместе.

Если у вас есть следующие вопросы, добро пожаловать, чтобы прочитать статью и внести замечания и предложения

  1. Как использовать го мод?
  2. Что такое ГОПАТ?
  3. GO111MODULE="" Что определяет этот параметр?
  4. В чем разница между go getи go download?
  5. Что именно импортирует импорт?

Инструмент управления зависимостями

Студенты, которые использовали Java, знают, что управление зависимостями прошлоОригинальная вручную импортированная банкапакет, использоватьИнструменты автоматизированного управления, такие как mavenПроцесс внедрения сторонних зависимостей, чтобы вы могли использовать отличные инструменты, разработанные другими. Если вы использовали Python, возможно, вы умеете использовать сторонние наборы инструментов pip install. Сторонние наборы инструментов Java и Python управляются централизованно, а использование maven или pip заключается в загрузке и обновлении зависимостей из соответствующего центра управления. Конечно, есть также инструменты версий зависимостей для других языков, таких как npm, yarn, gradle и т. д.

В языке go инструменты управления сторонними зависимостями прошли долгий процесс разработки. До выпуска GO1.11 такие инструменты, как govendor и dep, были в полном расцвете. Пока не появился мод го, стал доминировать в мире. Зависимости go очень просты и грубы, если вы полагаетесь на исходный код. Например:

import  "github.com/jinzhu/gorm"

github.com/jinzhu/gormЭто путь проекта GitHub для gorm.

GOPATH период

Go использовался до 1.11GOPATH模式Управление зависимостями. Установите и разверните среду go, при использовании go для разработки обязательно требуется установитьGOPATH(Конечно, он также будет указан по умолчанию в процессе установки.$GOPATH=~/go). быть вGOPATHновый путьsrc /bin /pkgпапка.

➜ ~/go
├── bin  # 存储go编译生成的二进制可执行文件,一般会把该路径配置到PATH中,PATH=$PATH:$GOPATH/bin
├── pkg  # 存储预编译的目标文件,以加快后续的编译速度 
└── src  # 存储Go的源代码,一般以$GOPATH/src/github.com/foo/bar的路径存放
➜  go go env |grep GOPATH
GOPATH="/Users/bytedance/go"

В этом режиме, если вы используетеgo getВытягивание внешних зависимостей автоматически загрузит и установит на$GOPATH/srcПод содержанием.

В этом режимеgo getБез концепции управления версиями невозможно решить проблему зависимости от разных версий, потому что одна и та же зависимость существует по одному и тому же пути.

Когда Go официально не запустил Go Modules, инструменты управления зависимостями Go можно описать как сто цветущих цветов, таких какgovendor,dep, но в конце концов Go Modules был выпущен, подавив ситуацию сепаратизма.

GO Modules

Go1.11 начал вводить модули Go, а Go1.13 начал осуждать использование GOPATH. Это означает, что вы можете хранить исходные файлы Go по любому пути без необходимости размещать их так же, как раньше.$GOPATH/srcсередина. Каждый проект go представляет собой модули. vgo является предшественником Go Modules.

В среде Go Modules появляется очень важная переменная среды.GO111MODULE

➜ ~ go env
GO111MODULE="auto"
GOPROXY="https://proxy.golang.org,direct"
GONOPROXY=""
GOSUMDB="sum.golang.org"
GONOSUMDB=""
GOPRIVATE=""

Если вы хотите установить переменные среды go, вы можете использовать

go env -w GO111MODULE=on  # 设置go 环境变量
go env -u # 恢复初始设置

GO111MODULE

GO111MODULEЭта переменная среды используется как переключатель для использования модулей Go. Можно сказать, что эта переменная является историческим продуктом и, вероятно, будет удалена в новой версии Go в будущем.

GO111MODULE="auto" # 只要项目包含了go.mod 文件的话就启用Go modules, 在Go1.11-1.14 中是默认值
GO111MODULE="on"   # 启用Go Modules
GO111MODULE="off"  # 禁用Go Modules, 对老的项目进行兼容

GOPROXY

GOPROXY — это агент для модулей Go, который можно быстро получить через зеркальные сайты (концепция централизованного?), и можно настроить несколько агентов.

GOPROXY="https://proxy.golang.org,direct"

directЭто означает, что если go get не может быть получен через прокси, он будет получен напрямую через исходный адрес.

go mod

Основные команды для создания модулей Go

➜  ~ go 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.
# 所有的go commands 都支持 modules。
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 init

Инициализировать новый модуль в текущем каталоге, то есть инициализировать файл проекта в каталоге наGo Module.

Если текущий каталог находится в GOPATH, этой команде не нужно передавать параметры, параметры по умолчанию равныGOPATH/srcв этот каталог相对路径.

➜  demo pwd
/Users/bytedance/go/src/github.com/airren/demo
➜  demo go mod init
go: creating new go.mod: module github.com/airren/demo
➜  demo ls
go.mod
➜  demo cat go.mod
module github.com/airren/demo

go 1.14
➜  demo

Если текущий каталог не находится в GOPATH, для手动指定имя модуля

➜  gotest pwd                                 
/Users/bytedance/Desktop/gotest
➜  gotest go mod init       # 如果不在GOPATH路径下                  
go: cannot determine module path for source directory /Users/bytedance/Desktop/gotest (outside GOPATH, module path must be specified)

Example usage:
        'go mod init example.com/m' to initialize a v0 or v1 module
        'go mod init example.com/m/v2' to initialize a v2 module

Run 'go help mod init' for more information.
➜  gotest go mod init github.com/airren/gotest 
go: creating new go.mod: module github.com/airren/gotest
➜  gotest cat go.mod 
module github.com/airren/gotest

go 1.14

go mod download

go mod downloadКоманда загрузит пакет вGOPATH/pkg/modПо пути можно использовать указанную версию при скачивании@latest. Можно использовать на любом путиgo mod download

➜  jinzhu pwd
/Users/bytedance/go/pkg/mod/github.com/jinzhu
➜  jinzhu ls
gorm@v1.9.11-0.20190912141731-0c98e7d712e2    inflection@v1.0.0
gorm@v1.9.12                                  now@v1.0.1
inflection@v0.0.0-20180308033659-04140366298a now@v1.1.1
➜  jinzhu go mod download -x github.com/jinzhu/gorm@v1.9.8  # 要指定版本
➜  jinzhu ls
gorm@v1.9.11-0.20190912141731-0c98e7d712e2    inflection@v1.0.0
gorm@v1.9.12                                  now@v1.0.1
gorm@v1.9.8                                   now@v1.1.1
inflection@v0.0.0-20180308033659-04140366298a
➜  jinzhu cd gorm@v1.9.8

import

импорт импортирует файловое хранилище相对路径(абсолютные пути использовать нельзя) илиModules Name, не является именем пакета, но используется при вызове функцииpackage的name.

импорт сначала начнется с$GOROOTнайти в, а затем из$GOPATH/srcпоиск, если да./или../Импорт в начале идет непосредственно к соответствующему относительному пути для поиска.

Когда импорт不区分大小写, поэтому имя папки в проекте go должно быть максимально строчным, и может быть косая черта _, но в имени пакета не должно быть_, иначе golint подскажет.

Возьмите файловую структуру 🌰, как показано на рисунке.

gotest
├── format_print
│   └── colorprintpath.go  # 文件名并不影响 import
└── sdemo
    ├── demo.go

colorprintpath.go

package colorprintfile // 调用方法时候通过package name 调用
import "fmt"
// NewPirnt is the new format print  公开方法要有注释
func NewPrint(content string) {
 fmt.Printf("This is the content: %v \n", content)
}

demo.goвызвать вышеуказанный метод

package main
import  "../format_print"  // import 使用的是相对路径
func main(){
 colorprintfile.NewPrint("hello")  // 调用package中的公开方法
}

если используетсяgo mod, с go.mod под файлом проекта файл будет иметь

module github.com/airren/gotest

На данный момент вы не можете использовать относительный путь для ссылки на пакет, чтобы передатьmodules的方式Цитировать

package main
import  "github.com/airren/gotest/format_print"
func main(){
 colorprintfile.NewPrint("hello")  // 调用package中的公开方法
}

go get

Может быть выполнен в любом путиgo get

  • Используется для загрузки и установки пакетов кода из удаленных репозиториев кода (github, gitlab, gogs).

  • Поддерживаемые системы контроля версий кода: Git, Mercurial(hg), SVN, Bazaar.

  • Указанный пакет кода будет загружен в$GOPATHВключите каталог src первой рабочей области перед установкой

    Общие параметры

    -d         # 只执行下载动作,而不执行安装动作
    -fix       # 在下载代码包后先执行修正动作,而后再进行编译和安装
    -u         # 利用网络来更新已有的代码包及其依赖包
    -x         # 显示过程

Например, используйтеgo getПолучить гормов. пройти через-xПараметры могут показать подробный процесс.

➜  ~ go get -u -x github.com/jinzhu/gorm
cd .
git clone -- https://github.com/jinzhu/gorm /Users/bytedance/go/src/github.com/jinzhu/gorm
cd /Users/bytedance/go/src/github.com/jinzhu/gorm
git submodule update --init --recursive
cd /Users/bytedance/go/src/github.com/jinzhu/gorm
git show-ref
cd /Users/bytedance/go/src/github.com/jinzhu/gorm
git submodule update --init --recursive
cd /Users/bytedance/go/src/github.com/jinzhu/inflection
git config remote.origin.url
cd /Users/bytedance/go/src/github.com/jinzhu/inflection
git pull --ff-only
cd /Users/bytedance/go/src/github.com/jinzhu/inflection
git submodule update --init --recursive
cd /Users/bytedance/go/src/github.com/jinzhu/inflection
git show-ref
cd /Users/bytedance/go/src/github.com/jinzhu/inflection
git submodule update --init --recursive
WORK=/var/folders/pz/w7jm4wm933lcspm82kff26600000gn/T/go-build644292157

Если у вас естьgo.modИспользование go get в папке проекта запишет соответствующие зависимости и версииgo.mod,go.sum генерируется автоматически. Подробную информацию можно найти на странице https://studygolang.com/articles/25658.

➜  gotest cat go.mod 
module github.com/airren/gotest

go 1.14
➜  gotest cat go.sum 
cat: go.sum: No such file or directory
➜  gotest go get -u github.com/jinzhu/gorm/  # 拉取gorm  
go: github.com/jinzhu/gorm upgrade => v1.9.12
➜  gotest cat go.mod 
module github.com/airren/gotest

go 1.14

require github.com/jinzhu/gorm v1.9.12 // indirect  # 新增依赖, 未被使用或者间接使用会有 indirect
➜  gotest cat go.sum 
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=

Не скупитесь на критику и идеи, пожалуйста, оставьте сообщение, и мы добьемся прогресса вместе.

использованная литература:

https://github.com/golang/go/wiki/Modules

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

https://juejin.cn/post/6844903433846145038

https://learnku.com/go/t/39086

https://studygolang.com/articles/25658