481 lines
12 KiB
Text
481 lines
12 KiB
Text
Modules
|
||
Лекция 5
|
||
|
||
Арсений Балобанов
|
||
|
||
* Modules
|
||
|
||
# go mod init github.com/verytable/hello
|
||
go: creating new go.mod: module github.com/verytable/hello
|
||
# cat go.mod
|
||
module github.com/verytable/hello
|
||
|
||
go 1.22.0
|
||
|
||
- *package* — набор исходных файлов из одной директории, которые компилируются вместе
|
||
- *module* — набор пакетов, которые релизятся вместе
|
||
- github.com/verytable/hello — *module*path*, префикс всех пакетов модуля
|
||
|
||
* Modules
|
||
|
||
- *import*path* — строчка для импорта пакета
|
||
|
||
Например, в модуле `github.com/google/go-cmp` есть директория `cmp/`.
|
||
|
||
import path пакета `cmp` будет `github.com/google/go-cmp/cmp`.
|
||
|
||
* Modules
|
||
|
||
# cat hello.go
|
||
package main
|
||
|
||
import "fmt"
|
||
|
||
func main() {
|
||
fmt.Println("Hello, world!")
|
||
}
|
||
|
||
Install binary.
|
||
|
||
# go env -w GOBIN=/tmp/bin
|
||
# go install .
|
||
# /tmp/bin/hello
|
||
Hello, world!
|
||
# go env -u GOBIN
|
||
|
||
* Modules
|
||
|
||
# mkdir -p morestrings
|
||
# cat morestrings/reverse.go
|
||
package morestrings
|
||
|
||
func ReverseRunes(s string) string {
|
||
r := []rune(s)
|
||
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
|
||
r[i], r[j] = r[j], r[i]
|
||
}
|
||
return string(r)
|
||
}
|
||
|
||
* Modules
|
||
|
||
# go build ./morestrings // в репозитории ничего не изменится
|
||
|
||
- *go*env*GOCACHE* — внутренний кэш `go`build`
|
||
|
||
Команда go кэширует выходные данные сборки для повторного использования в будущих сборках.
|
||
|
||
`go`help`cache` для деталей.
|
||
|
||
* Modules
|
||
|
||
Используем subpackage
|
||
|
||
# cat hello.go
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
|
||
"github.com/verytable/hello/morestrings"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
|
||
}
|
||
|
||
# go install github.com/verytable/hello
|
||
# hello
|
||
Hello, Go!
|
||
|
||
* Modules
|
||
|
||
Добавляем внешнюю зависимость
|
||
|
||
# cat hello.go
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
|
||
"github.com/google/go-cmp/cmp"
|
||
"github.com/verytable/hello/morestrings"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
|
||
fmt.Println(cmp.Diff("Hello World", "Hello Go"))
|
||
}
|
||
|
||
* Modules
|
||
|
||
# go mod tidy
|
||
go: finding module for package github.com/google/go-cmp/cmp
|
||
go: found github.com/google/go-cmp/cmp in github.com/google/go-cmp v0.6.0
|
||
# go install
|
||
# hello
|
||
Hello, Go!
|
||
string(
|
||
- "Hello World",
|
||
+ "Hello Go",
|
||
)
|
||
|
||
Внешние зависимости хранятся in go.mod.
|
||
|
||
# cat go.mod
|
||
module github.com/verytable/hello
|
||
|
||
go 1.22.0
|
||
|
||
require github.com/google/go-cmp v0.6.0
|
||
|
||
* Modules
|
||
|
||
- *go*mod*tidy* makes sure go.mod matches the source code in the module
|
||
|
||
`go`mod`help`tidy` для подробностей.
|
||
|
||
* Modules
|
||
|
||
Исходный код модулей хранится в *$GOPATH/pkg/mod*.
|
||
|
||
# tree -L 2 $GOPATH/pkg/mod/github.com/google
|
||
...
|
||
├── go-cmp@v0.5.9
|
||
│ ├── cmp
|
||
│ ├── CONTRIBUTING.md
|
||
│ ├── go.mod
|
||
│ ├── LICENSE
|
||
│ └── README.md
|
||
├── go-cmp@v0.6.0
|
||
│ ├── cmp
|
||
│ ├── CONTRIBUTING.md
|
||
│ ├── go.mod
|
||
│ ├── LICENSE
|
||
│ └── README.md
|
||
...
|
||
|
||
* Modules
|
||
|
||
- *go*clean* — чистит системные директории
|
||
|
||
`go`clean`-modcache` удаляет *все* модули из *$GOPATH/pkg/mod*.
|
||
|
||
`go`clean`-cache` удаляет объекты из *GOCACHE*.
|
||
|
||
* Modules
|
||
|
||
Установить другую версию пакета.
|
||
|
||
# go get github.com/google/go-cmp/cmp@v0.5.5
|
||
go: downloading github.com/google/go-cmp v0.5.5
|
||
go: downgraded github.com/google/go-cmp v0.6.0 => v0.5.5
|
||
|
||
Обновить модули.
|
||
|
||
# go mod tidy
|
||
go: downloading golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
|
||
|
||
# cat go.mod
|
||
module github.com/verytable/hello
|
||
|
||
go 1.22.0
|
||
|
||
require github.com/google/go-cmp v0.5.5
|
||
|
||
* Modules
|
||
|
||
# go list -m -f {{.Path}}{{.Version}} all
|
||
github.com/verytable/hello
|
||
github.com/google/go-cmpv0.5.5
|
||
golang.org/x/xerrorsv0.0.0-20191204190536-9bdfabe68543
|
||
|
||
Format options.
|
||
|
||
type Module struct {
|
||
Path string // module path
|
||
Version string // module version
|
||
Versions []string // available module versions (with -versions)
|
||
Replace *Module // replaced by this module
|
||
Time *time.Time // time version was created
|
||
Update *Module // available update, if any (with -u)
|
||
Main bool // is this the main module?
|
||
Indirect bool // is this module only an indirect dependency of main module?
|
||
Dir string // directory holding files for this module, if any
|
||
GoMod string // path to go.mod file used when loading this module, if any
|
||
GoVersion string // go version used in module
|
||
Retracted string // retraction information, if any (with -retracted or -u)
|
||
Error *ModuleError // error loading module
|
||
}
|
||
|
||
* Modules
|
||
|
||
- *go.sum* — хранит хэши модулей
|
||
|
||
# cat go.sum
|
||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||
|
||
* Modules
|
||
|
||
- *go*mod*graph* — печатает граф зависимостей модулей
|
||
|
||
# go mod graph
|
||
github.com/verytable/hello github.com/google/go-cmp@v0.5.5
|
||
github.com/verytable/hello go@1.22.0
|
||
github.com/google/go-cmp@v0.5.5 golang.org/x/xerrors@v0.0.0-20191204190536-9bdfabe68543
|
||
go@1.22.0 toolchain@go1.22.0
|
||
|
||
* Modules
|
||
|
||
- *go*mod*why* — показывает кратчайший по импортам путь до пакета
|
||
|
||
# go mod why golang.org/x/xerrors
|
||
# golang.org/x/xerrors
|
||
github.com/verytable/hello
|
||
github.com/google/go-cmp/cmp
|
||
github.com/google/go-cmp/cmp.test
|
||
github.com/google/go-cmp/cmp/cmpopts
|
||
golang.org/x/xerrors
|
||
|
||
* Modules
|
||
|
||
- *go*mod*vendor* — копирует зависимости модуля в директорию `./vendor`
|
||
|
||
Vendor dependencies.
|
||
|
||
# go mod vendor
|
||
# tree -L 3 ./vendor
|
||
./vendor
|
||
├── github.com
|
||
│ └── google
|
||
│ └── go-cmp
|
||
└── modules.txt
|
||
|
||
* Modules
|
||
|
||
# cat vendor/modules.txt
|
||
# github.com/google/go-cmp v0.5.5
|
||
## explicit
|
||
github.com/google/go-cmp/cmp
|
||
github.com/google/go-cmp/cmp/internal/diff
|
||
github.com/google/go-cmp/cmp/internal/flags
|
||
github.com/google/go-cmp/cmp/internal/function
|
||
github.com/google/go-cmp/cmp/internal/value
|
||
|
||
* Modules
|
||
|
||
Indirect зависимости
|
||
|
||
# go mod init github.com/verytable/world
|
||
go: creating new go.mod: module github.com/verytable/world
|
||
|
||
# cat sum.go
|
||
package world
|
||
|
||
import _ "github.com/jackc/pgx/v5"
|
||
|
||
func Sum(a, b int) int {
|
||
return a + b
|
||
}
|
||
|
||
* Modules
|
||
|
||
Indirect зависимости
|
||
|
||
# go mod tidy
|
||
...
|
||
|
||
# cat go.mod
|
||
module github.com/verytable/world
|
||
|
||
go 1.22.0
|
||
|
||
require github.com/jackc/pgx/v5 v5.5.5
|
||
|
||
require (
|
||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||
golang.org/x/crypto v0.17.0 // indirect
|
||
golang.org/x/text v0.14.0 // indirect
|
||
)
|
||
|
||
* Modules
|
||
|
||
Как импортировать пакет из локального модуля
|
||
|
||
# cat hello.go
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
|
||
"github.com/google/go-cmp/cmp"
|
||
"github.com/verytable/hello/morestrings"
|
||
"github.com/verytable/world"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
|
||
fmt.Println(cmp.Diff("Hello World", "Hello Go"))
|
||
|
||
fmt.Println(world.Sum(1, 2))
|
||
}
|
||
|
||
* Modules
|
||
|
||
Как импортировать пакет из локального модуля
|
||
|
||
# go install .
|
||
main.go:8:2: no required module provides package github.com/verytable/world; to add it:
|
||
go get github.com/verytable/world
|
||
|
||
# go get github.com/verytable/world
|
||
go: module github.com/verytable/world: git ls-remote -q origin in /home/verytable/go/pkg/mod/cache/vcs/8d15fd58d5b540d58dc97582a5a11fe29782f4416e9628e0183c4ea4f8c7cdcd: exit status 128:
|
||
fatal: could not read Username for 'https://github.com': terminal prompts disabled
|
||
Confirm the import path was entered correctly.
|
||
|
||
* Modules
|
||
|
||
- *go*mod*edit* — вносит правки в go.mod
|
||
|
||
# go mod edit -replace github.com/verytable/world=/tmp/world
|
||
# cat go.mod
|
||
module github.com/verytable/hello
|
||
|
||
go 1.22.0
|
||
|
||
require github.com/google/go-cmp v0.5.5
|
||
|
||
replace github.com/verytable/world => /tmp/world
|
||
|
||
* Modules
|
||
|
||
# go get ./...
|
||
go: added github.com/jackc/pgpassfile v1.0.0
|
||
go: added github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a
|
||
go: added github.com/jackc/pgx/v5 v5.5.5
|
||
go: added github.com/verytable/world v0.0.0-00010101000000-000000000000
|
||
go: added golang.org/x/crypto v0.17.0
|
||
go: added golang.org/x/text v0.14.0
|
||
|
||
# go run .
|
||
Hello, Go!
|
||
string(
|
||
- "Hello World",
|
||
+ "Hello Go",
|
||
)
|
||
|
||
3
|
||
|
||
* Modules
|
||
|
||
Выложить свой пакет в открытый доступ.
|
||
|
||
# git init
|
||
# git add .
|
||
# git commit
|
||
# git push
|
||
# go get github.com/verytable/hello@v0.0.0-20240303255101-161cd47e91fd
|
||
|
||
# git tag v0.0.1
|
||
# git push v0.0.1
|
||
# go get github.com/verytable/hello@v0.0.1
|
||
|
||
* Modules
|
||
|
||
Semantic versioning
|
||
|
||
.image versions.png _ 700
|
||
|
||
* Modules
|
||
|
||
v2 and beyond
|
||
|
||
.link https://github.com/googleapis/gax-go Отдельная директория
|
||
|
||
├── go.mod
|
||
├── package.go
|
||
└── v2
|
||
├── go.mod
|
||
└── package.go
|
||
|
||
.link https://github.com/go-yaml/yaml Git ветки
|
||
|
||
main == v0/v1
|
||
├── go.mod
|
||
└── package.go
|
||
|
||
v2 == v2
|
||
├── go.mod
|
||
└── package.go
|
||
|
||
* Modules
|
||
|
||
Module proxy
|
||
|
||
# curl https://proxy.golang.org/github.com/google/go-cmp/@v/list
|
||
v0.5.8
|
||
v0.5.5
|
||
v0.6.0
|
||
|
||
# curl https://proxy.golang.org/github.com/google/go-cmp/@v/v0.5.5.info
|
||
{"Version":"v0.5.5","Time":"2021-03-03T20:48:37Z"}
|
||
|
||
# curl https://proxy.golang.org/github.com/google/go-cmp/@latest
|
||
{"Version":"v0.6.0",
|
||
"Time":"2023-08-31T17:32:40Z",
|
||
"Origin":{"VCS":"git","URL":"https://github.com/google/go-cmp","Ref":"refs/tags/v0.6.0", ...}}
|
||
|
||
# curl https://proxy.golang.org/github.com/google/go-cmp/@v/v0.6.0.mod
|
||
module github.com/google/go-cmp
|
||
|
||
go 1.13
|
||
|
||
# curl -O https://proxy.golang.org/github.com/google/go-cmp/@v/v0.6.0.zip
|
||
|
||
* Modules
|
||
|
||
Module proxy
|
||
|
||
# go get -x github.com/google/go-cmp/cmp
|
||
get https://proxy.golang.org/github.com/@v/list
|
||
get https://proxy.golang.org/github.com/google/go-cmp/@v/list
|
||
get https://proxy.golang.org/github.com/google/go-cmp/cmp/@v/list
|
||
get https://proxy.golang.org/github.com/google/@v/list
|
||
get https://proxy.golang.org/github.com/google/go-cmp/cmp/@v/list: 404 Not Found (0.622s)
|
||
get https://proxy.golang.org/github.com/google/@v/list: 404 Not Found (0.622s)
|
||
get https://proxy.golang.org/github.com/@v/list: 404 Not Found (0.622s)
|
||
get https://proxy.golang.org/github.com/google/go-cmp/@v/list: 200 OK (0.638s)
|
||
go: added github.com/google/go-cmp v0.6.0
|
||
|
||
* Modules
|
||
|
||
Vanity import
|
||
|
||
Исходный код лежит на [[https://github.com/uber-go/atomic][https://github.com/uber-go/atomic]], однако импорт другой
|
||
|
||
import "go.uber.org/atomic"
|
||
|
||
Команда *go*get* внутри делает http запрос к [[https://go.uber.org]]
|
||
|
||
# curl https://go.uber.org/atomic\?go-get\=1
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta name="go-import" content="go.uber.org/atomic git https://github.com/uber-go/atomic">
|
||
<meta name="go-source" content="go.uber.org/atomic https://github.com/uber-go/atomic https://github.com/uber-go/atomic/tree/master{/dir} https://github.com/uber-go/atomic/tree/master{/dir}/{file}#L{line}">
|
||
<meta http-equiv="refresh" content="0; url=https://pkg.go.dev/go.uber.org/atomic">
|
||
</head>
|
||
<body>
|
||
Nothing to see here. Please <a href="https://pkg.go.dev/go.uber.org/atomic">move along</a>.
|
||
</body>
|
||
</html>
|
||
|
||
* Ссылки:
|
||
|
||
.link https://golang.org/cmd/go/ — go cmd
|
||
.link https://www.youtube.com/watch?v=F8nrpe0XWRg — ▶️ Go with Versions, Russ Cox
|
||
.link https://play-with-go.dev/ — play-with-go
|