プライベートリポジトリのモジュールをgo getするための設定(https)
社内のプライベートリポジトリをgo getする際にしばしば混乱するのでメモ。httpsでのアクセスが必要な環境なので、https前提の話となっている。
何も設定していない場合に発生するエラー
前提:
- go version go1.15.6 linux/amd64 (ちょっと古い…)
- GOPRIVATEを設定していない
- httpsの認証情報を設定してない
- キャッシュクリア
- go.modがあるディレクトリで実行
go get, go get ${モジュール名}
- go.modに記載のモジュールをインストールする。
- ①プライベートリポジトリの認証を突破できない
❯ go get ①go: github.com/Sho372/mysecret@v0.0.0-20221015173609-50bc2589408e: invalid version: git fetch -f origin refs/heads/*:refs/heads/* refs/tags/*:refs/tags/* in /home/sho/goworkspace/pkg/mod/cache/vcs/f7c95e78ccfc05412466703c9dfe4d96cfb78fa98dc272d0d7347bff3f468e2d: exit status 128: fatal: could not read Username for 'https://github.com': terminal prompts disabled
ちなみに、go.modがない環境で実行すると…
- ①に加えて②も起きる
❯ go get github.com/Sho372/go-const ①go get github.com/Sho372/go-const: module github.com/Sho372/go-const: git ls-remote -q origin in /home/sho/goworkspace/pkg/mod/cache/vcs/1213af4aff3f33e0fc4e0690d9630417ffc2fcdd363e78fe9cf3cf41f1e5a64c: exit status 128: fatal: could not read Username for 'https://github.com': terminal prompts disabled ②Confirm the import path was entered correctly. If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.
1. GOPRIVAETを設定
今回はモジュール名を直接指定する。モジュール名はモジュール側のgo.modに書いてある。
❯ export GOPRIVATE=github.com/Sho372/mysecret ❯ env | grep GOPRIVATE GOPRIVATE=github.com/Sho372/mysecret
指定するもジュルー名がわからない時はモジュール側のgo.modを確認する
❯ cat go.mod module github.com/Sho372/mysecret go 1.15
上記のexportで設定してもいいが、goの設定なので、go env -wで設定するようにしている。
go env -w GOPRIVATE=github.com/Sho372/mysecret
2. httpsの認証情報を設定に追加して、認証情報入力をスキップする
.netrc
Frequently Asked Questions (FAQ) - The Go Programming Language
git confg
プライベートリポジトリをgo getする方法 - 尋常でないもふもふ
bitbucket, gitlab
Today I Learned - Fix: go get private repository return error terminal prompts disabled
こちらも.netrcで設定してもいいが、.gitconfigで設定がまとまっている方がいいので、gitの設定で解決するようにしている。
git config --global url."https://${githubのaccess token}:x-oauth-basic@github.com/".insteadOf "https://github.com/"
❯ cat ~/.gitconfig [user] email = 32non23ca@gmail.com name = Sho372 [url "https://${githubのaccess token}:x-oauth-basic@github.com/"] insteadOf = https://github.com/
3. go get
設定が完了したら、欲しいプライベートモジュールをgo getする
❯ go get [github.com/Sho372/mysecret](http://github.com/Sho372/mysecret) go: downloading [github.com/Sho372/mysecret](http://github.com/Sho372/mysecret) v0.0.0-20221015173609-50bc2589408e go: [github.com/Sho372/mysecret](http://github.com/Sho372/mysecret) upgrade => v0.0.0-20221015173609-50bc2589408e ❯ cat go.mod module go-import-package go 1.15 require github.com/Sho372/mysecret v0.0.0-20221015173609-50bc2589408e // indirect
go getが成功すると、GOMODCACHE配下にread onlyで格納される
❯ go env | grep GOMODCACHE GOMODCACHE="/home/sho/goworkspace/pkg/mod" ❯ pwd /home/sho/goworkspace/pkg/mod/github.com/!sho372 ❯ ll total 16 drwxr-xr-x 4 sho sho 4096 Oct 16 02:41 . drwxr-xr-x 40 sho sho 4096 Oct 16 04:43 .. dr-x------ 2 sho sho 4096 Oct 16 02:41 mysecret@v0.0.0-20221015173609-50bc2589408e
❯ go env | grep GOCACHE GOCACHE="/home/sho/.cache/go-build"
4. ソース上で取得したモジュールをimportして使う
最後にソース上でimportする
import ( "fmt" "log" "github.com/Sho372/mysecret" ★ "github.com/shopspring/decimal" )
go mod vendor (vendoring)
go mod vendorを実行すると、vendorディレクトリが生成され、ソースコードが格納される。
- vendorディレクトリが生成され、この配下に依存モジュールのソースがダウンロードされる
- vendorがある場合は、そこにあるモジュールで依存が解決されるらしい
- GOMODCACHE配下とは異なり、修正可能なのでデバッグコードを差し込むことができる
❯ ll total 2368 drwxrwxrwx 1 sho sho 512 Oct 17 04:49 . drwxrwxrwx 1 sho sho 512 Oct 16 03:31 .. -rwxrwxrwx 1 sho sho 148 Oct 16 05:41 go.mod -rwxrwxrwx 1 sho sho 404 Oct 16 04:54 go.sum -rwxrwxrwx 1 sho sho 2421984 Oct 16 05:33 main -rwxrwxrwx 1 sho sho 261 Oct 16 04:57 main.go ❯ go mod vendor ❯ ll total 2368 drwxrwxrwx 1 sho sho 512 Oct 17 04:49 . drwxrwxrwx 1 sho sho 512 Oct 16 03:31 .. -rwxrwxrwx 1 sho sho 148 Oct 16 05:41 go.mod -rwxrwxrwx 1 sho sho 404 Oct 16 04:54 go.sum -rwxrwxrwx 1 sho sho 2421984 Oct 16 05:33 main -rwxrwxrwx 1 sho sho 261 Oct 16 04:57 main.go drwxrwxrwx 1 sho sho 512 Oct 17 04:49 vendor ★ ❯ ll vendor/github.com/Sho372 total 0 drwxrwxrwx 1 sho sho 512 Oct 17 04:49 . drwxrwxrwx 1 sho sho 512 Oct 17 04:49 .. drwxrwxrwx 1 sho sho 512 Oct 17 04:49 mysecret ★
キャッシュクリア実験
上記の手順でプライベートパッケージからパッケージを取得したあとに、以下を実施してキャッシュクリアの挙動を確かめた
1 go clean -modcache
- GOMODCACHE="/home/sho/goworkspace/pkg/mod" ディレクトリが削除される
- このあとにgo buildを実行してもまだ通る
2 go clean --cache
- GOCACHE="/home/sho/.cache/go-build"配下のキャッシュが削除される
- このあとにgo buildを実行してもまだ通る
3 rm -rf vendor
,go clean -modcache
,go clean --cache
- vendorディレクトリを削除
- go buildするとGOCACHEにキャッシュが残るので再度これもクリア
- 念のためGOMODCACHEもクリア
- これで完全にローカルからパッケージが消え去ったはず
4 go build
- パッケージのダウンロードが開始した。(ただし、Go 16ではgo build時の自動ダウンロードはなくなったらしいので、go get or go mod tidyを実行)
❯ go build go: downloading github.com/shopspring/decimal v1.3.1 go: downloading github.com/Sho372/mysecret v0.0.0-20221015173609-50bc2589408e
キャッシュクリアまとめ
つまり、ローカルのパッケージを完全に削除して、再ダウンロードしたい場合は以下ぽい
- もしvendorディレクトリがあるなら、
rm -rf vendor
go clean --cache
go clean -modcache
go get
orgo mod tidy
- もしvendorディレクトリが必要なら、
go mod vendor
プライベートモジュールの改修
- プライベートパッケージ側でブランチを切って改修
- そのブランチ版をインポートして使ってみる
1. プライベートモジュールで改修
feature
ブランチを作成して改修し、push- 新たに
pokemons
パッケージを作成
2. featureブランチ版をgo get
- @${ブランチ名}で指定できる
- go get -uだとさらにモジュールが依存するモジュールの最新も取得してくれるらしい。こっちが適切?
❯ go get github.com/Sho372/mysecret@feature go: github.com/Sho372/mysecret feature => v0.0.0-20221016202503-eb4c4bc6b253 go: downloading github.com/Sho372/mysecret v0.0.0-20221016202503-eb4c4bc6b253 ❯ cat go.mod module go-import-package go 1.15 require ( github.com/Sho372/mysecret v0.0.0-20221016202503-eb4c4bc6b253 github.com/shopspring/decimal v1.3.1 )
3. 使ってみる
- 今回は、「モジュール名」と「パッケージ名」が異なるから?、${モジュール名}/${パッケージ名}で指定するとimportできた
import ( "fmt" "log" "github.com/Sho372/mysecret" "github.com/Sho372/mysecret/pokemons" ★ "github.com/shopspring/decimal" ) func main() { mysecret.SecretProcess() fmt.Println(pokemons.PIKACHU) ★ amount, err := decimal.NewFromString("1.23") if err != nil { log.Fatal(err) } fmt.Println(amount.String()) }
4. 元のmainブランチ版に戻す
- go get ${モジュール名}@latestでも、元のmasterブランチの最新に戻った
- go get ${モジュール名}@latestはgo get ${モジュール名}と同じ意味らしい
❯ go get github.com/Sho372/mysecret@latest go: github.com/Sho372/mysecret latest => v0.0.0-20221015173609-50bc2589408e ❯ cat go.mod module go-import-package go 1.15 require ( github.com/Sho372/mysecret v0.0.0-20221015173609-50bc2589408e github.com/shopspring/decimal v1.3.1 ) ❯ go build go: finding module for package github.com/Sho372/mysecret/pokemons main.go:8:2: module github.com/Sho372/mysecret@latest found (v0.0.0-20221015173609-50bc2589408e), but does not contain package github.com/Sho372/mysecret/pokemons
masterブランチ指定でもいける
❯ go get github.com/Sho372/mysecret@master go: github.com/Sho372/mysecret master => v0.0.0-20221015173609-50bc2589408e
goコマンド
公式ドキュメント
Go Modules Reference - The Go Programming Language
go.modで定義された、プロジェクトの依存モジュールを取得したい時
- go get or go mod tidy
- 格納先:GOMODCACHE="/home/sho/goworkspace/pkg/mod"
cd ${go.modがあるディレクトリ} go get or go mod tidy
プロジェクトに新しいモジュールを追加したい時(go.modへの追記)
- go get ${モジュール名}
- 格納先:GOMODCACHE="/home/sho/goworkspace/pkg/mod"
cd ${go.modがあるディレクトリ} go get ${モジュール名} cat go.mod //取得したモジュール名が追記されている