とあるプロジェクトでセルフホストしている GitLab で Go Modules を利用しようしてハマったのでメモ。
foo モジュールを private.host/account1/foo に公開したとします。
go.mod
module private.host/account1/foo go 1.12
利用側では、
import "private.host/account1/foo"
のように指定します。go get / run / build する際、go コマンドは https://private.host/account1/foo?go-get=1
のようにリクエストを投げるようです。GitLab などの VCS hosting サイトはこのリクエストに対して
<meta name="go-import" content="private.host/account1/foo git https://private.host/account1/foo.git">
のように、VCS の種類とリポジトリの URL を含むメタタグを HTML として返すことを期待されます。
go コマンドはこの HTML をパースして VCS の種類、リポジトリのロケーションを特定し、VCS の CLI コマンドにモジュールの取得を委譲します。
gitlab.com では go-get=1 のクエリパラメータ付きリクエストに以下のような HTML を返却しています。
<html> <head> <meta name="go-import" content="gitlab.com/kondoumh/go-samplemodlue git https://gitlab.com/kondoumh/go-samplemodule.git" /> : </head> <body> go get https://gitlab.com/kondoumh/go-samplemodule </body> </html>
GitHub の場合はこんな感じ
<html lang="en"> <head> <meta charset="utf-8"> : <meta name="go-import" content="github.com/kondoumh/gogreeting git https://github.com/kondoumh/gogreeting.git"> : </head> <body> :
Go Modules はソースコードであり、Git 以外の VCS (Mercurial, Bazzar etc.) でもホストされる可能性があります。Java や Node.js などのようにビルド・パッケージングしてホストするわけではないので、このように VCS によらない方法を取っているのでしょう。
件の GitLab は HTTPS ポートが規定の 443 以外で公開されていました。しかし go コマンドは既定のポートにリクエストを投げるので Connection refused でエラーになっていました。443 ポートを受け付けるように設定したら無事に使えるようになりました。