Skip to content

Instantly share code, notes, and snippets.

@utamori
Last active June 16, 2020 05:20
Show Gist options
  • Save utamori/42f17fb7a6e22cea6e346530d14d2684 to your computer and use it in GitHub Desktop.
Save utamori/42f17fb7a6e22cea6e346530d14d2684 to your computer and use it in GitHub Desktop.
gomodulesのwiki和訳していく

Modules · golang/go Wikiの翻訳

注意:完全な翻訳ではありません。Git以外のVCSへの言及などは意図的に省いています。リンクも所々ありません。 FAQは気になったところから徐々に訳していきます

Go Modules

Goは1.11以降、ここで提案されているようなバージョン付きmodulesのサポートが含まれています。 2018年2月には初期のプロトタイプvgoが発表されました。2018年7月には、バージョン管理された modules がメインのGoリポジトリに統合されました。

Go 1.14では、modulesのサポートは本番使用の準備ができていると考えられ、すべてのユーザーは他の依存関係管理システムからmodulesに移行することが推奨されています。 Goツールチェーンの問題で移行できない場合は、そのissueがopenになっているか確認してください。Issues · golang/go (その問題がGo1.15マイルストーンにない場合は、その問題が移行を妨げている理由をコメントし、適切に優先順位を付けられるようにしてください)。 また、より詳細なフィードバックを得るために、レポートを提供することもできます。

最近の変更点

Go 1.14

  • メインモジュールにトップレベルのvendorディレクトリがあり、そのgo.modファイルがgo 1.14以上を指定している場合、そのフラグを受け入れる操作のために、goコマンドのデフォルトが-mod=vendorになりました。
  • -mod=readonly は、go.mod ファイルが read-only でトップレベルのvendorディレクトリが存在しない場合にデフォルトで設定されるようになりました。
  • -modcacherw は、モジュールキャッシュに新しく作成されたディレクトリを読み込み専用にするのではなく、デフォルトのパーミッションのままにしておくように go コマンドに指示する新しいフラグです。
  • -modfile=file は、モジュールのルートディレクトリにあるファイルではなく、別の go.mod ファイルを読む (そして、場合によっては書き込む) ことを go コマンドに指示する新しいフラグです。
  • モジュール対応モードが明示的に有効になっている場合(GO111MODULE=onが設定されている場合)、go.modファイルが存在しない場合、ほとんどのモジュールコマンドの機能はより限定されます。
  • goコマンドは、moduleモードでSubversionリポジトリをサポートするようになりました。

Go 1.13

  • Goツールは、https://proxy.golang.org にある公開の Go モジュールミラーからモジュールをダウンロードすることをデフォルトとし、https://sum.golang.org にある公開の Go checksum データベースに対して、ダウンロードしたモジュールを (ソースにかかわらず) 検証することをデフォルトとするようになりました。
    • プライベートコードを使用している場合は、GOPRIVATE 設定 (go env -w GOPRIVATE=*.corp.com,github.com/secret/repo のように) を設定するか、使用頻度の低いユースケースをサポートするより細かい GONOPROXYGONOSUMDBを設定する必要があります。詳細はドキュメントを参照してください。
  • GO111MODULE=autoは、GOPATH内であってもgo.modがあればモジュールモードを有効にします。(Go 1.13以前では、GO111MODULE=autoではGOPATH内でモジュールモードを有効にすることはありませんでした)。
  • go get の引数が変更されました。
    • go get -u (引数なし) は、現在のパッケージの直接および間接的な依存関係のみをアップグレードし、 モジュール全体を検査しなくなりました。
    • go get -u ./…をモジュールのルートから 実行すると、モジュールの直接および間接的な依存関係をすべてアップグレードします。テストの依存関係は除外します。
    • go get -u -t ./…も似ていますが、テストの依存関係もアップグレードします。
    • go get-m をサポートしなくなりました (他の変更により go get -d と大きく重なっていたからです。通常は go get -m foo go get -d foo に置き換えることができます)。

クイックスタート

簡単な例

詳細はこのページの残りの部分で説明しますが、ここではゼロからモジュールを作成する簡単な例を紹介します。

GOPATHの外側にディレクトリを作成し、オプションでGitを初期化します。

$ mkdir -p /tmp/scratchpad/repo
$ cd /tmp/scratchpad/repo
$ git init -q
$ git remote add origin https://github.com/my/repo

Modulesを初期化します

$ go mod init github.com/my/repo

go: creating new go.mod: module github.com/my/repo

コードを書きます

$ cat <<EOF > hello.go
package main

import (
    "fmt"
    "rsc.io/quote"
)

func main() {
    fmt.Println(quote.Hello())
}
EOF

ビルドして、実行します

$ go build -o hello
$ ./hello

Hello, world.

go.mod ファイルが更新され、依存関係の明示的なバージョンが含まれるようになりました。 ここでv1.5.2はセマンティックバージョニングを指します。

$ cat go.mod

module github.com/my/repo

require rsc.io/quote v1.5.2

日々の流れ

上の例では go get は必要ありませんでした。

一般的な日常のワークフローは以下のようになります。

  • 必要に応じて .go コードにインポート文を追加します。
  • go buildgo testのような標準的なコマンドは、インポートを満たすために必要に応じて自動的に新しい依存関係を追加します(go.modを更新し、新しい依存関係をダウンロードします)。
  • 必要に応じて、go get foo@v1.2.3, go get foo@mastergo get foo@e3702bed2 などのコマンドを使って、より特定のバージョンの依存関係を選択したり、 go.mod を直接編集したりできます。

他の一般的な機能を簡単に紹介します。

  • go list -m all — すべての直接的、間接的な依存関係の、ビルドで使用される最終バージョンを表示する
  • go list -u -m all — すべての直接・間接な依存関係の、マイナーアップグレードとパッチアップグレードを表示する
  • go get -u ./... or go get -u=patch ./... (モジュールのルートディレクトリから)直接的、間接的な依存関係をすべて最新のマイナーアップグレードやパッチアップグレードに更新する(プレリリースは無視する)
  • go build ./... or go test ./... (モジュールのルートディレクトリから)モジュール内のすべてのパッケージをビルドしたりテストする
  • go mod tidygo mod tidy - go.mod から不要になった依存関係を削除し、OS、アーキテクチャ、ビルドタグの他の組み合わせに必要な依存関係を追加する
  • replace ディレクティブまたは gohack - 依存関係のフォーク、ローカルコピー、正確なバージョンを使う
  • go mod vendorvendor ディレクトリを作成するためのオプションのステップ

次の「Modulesに関連する新しい概念」の4つのセクションを読んだ後、ほとんどのプロジェクトでModulesを使い始めるのに十分な情報を得ることができるでしょう。 また、より詳細なトピックのリストへ慣れるために、上記の目次(とFAQ)を見直すことも有用です。

Modulesに関連する新しい概念

これらのセクションでは、主な新しいコンセプトのハイレベルな紹介をしています。詳細と根拠については、デザインの背後にある哲学を説明するRuss Cox による 40 分間の紹介ビデオ公式の提案書、またはより詳細な初期vgoブログの連載をご覧ください。

Modules

module とは、関連するGoパッケージの集合体であり、1つのユニットとしてバージョン管理されています。

Modulesは、正確な依存関係の要件を記録し、再現性のあるビルドを作成します。

ほとんどの場合、バージョン管理リポジトリには、リポジトリのルートで定義されたモジュールが1つだけ含まれています。 ( Modulesには1つのリポジトリで複数のモジュールのサポートもあります。 しかし、一般的には、リポジトリごとに単一のモジュールを作成するよりも、継続的に作業を行う必要が出てしまいます。)。

リポジトリ、モジュール、パッケージの関係をまとめています。

  • リポジトリには、1つまたは複数のGoモジュールが含まれています。
  • 各モジュールには、1つまたは複数のGoパッケージが含まれています。
  • 各パッケージは、1つのディレクトリにある1つ以上のGoソースファイルで構成されています。

moduleは一つにしてパッケージを分ける方法がいいかな(メモ)

モジュールは semver に従ってセマンティックにバージョン管理されていなければならず、通常は v0.1.0, v1.2.3, v1.5.0-rc.1 のように v(メジャー).(マイナー).(パッチ) の形式をとっています。先頭の v は必須です。Gitを使用している場合は、リリースされたコミットにそのバージョンをタグ付けします。公開・非公開のモジュールリポジトリやプロキシも利用できます(FAQを参照

go.mod

モジュールは、ツリーのルートディレクトリにある go.modファイルを含むGoソースファイルのツリーによって定義されます。モジュールのソースコードは、GOPATHの外に置くことができます。モジュールには、modulerequirereplaceexcludeの4つのディレクティブがあります。

以下は、モジュールを定義するgo.modファイルの例です。 github.com/my/thing

module github.com/my/thing

require (
    github.com/some/dependency v1.2.3
    github.com/another/dependency/v4 v4.0.0
)

モジュールは、モジュールパスを提供するmoduleディレクティブを介して、そのgo.modの中で同一性を宣言します。モジュール内のすべてのパッケージのインポートパスは、 共通のプレフィックスとしてモジュールパスを共有します。モジュールのパスと go.mod からパッケージのディレクトリへの相対パスは、 パッケージのインポートパスを決定します。

たとえば、リポジトリにgithub.com/user/mymodモジュールを作成していて、インポートパスがgithub.com/user/mymod/foogithub.com/user/mymod/barである2つのパッケージを含む場合、go.modファイルの最初の行は通常、モジュールパスをmodule github.com/user/mymodと宣言します。対応するディレクトリの構造は次のようになります。

mymod
|-- bar
|   `-- bar.go
|-- foo
|   `-- foo.go
`-- go.mod

Goソースコードでは、パッケージはモジュールパスを含むフルパスを使用してインポートされます。たとえば、上の例で go.mod のモジュール名を module github.com/user/mymod と宣言した場合、パッケージbarを利用したい時は以下のようにインポートします。

import "github.com/user/mymod/bar"

これは、モジュール github.com/user/mymod からパッケージbarをインポートします。

excludereplace ディレクティブは、mainモジュールでのみ動作します。 mainモジュール以外のモジュールの excludereplace ディレクティブは、mainモジュールをビルドする際に無視されます。したがって、replace文とexclude文は、依存関係による完全な制御を受けることなく、 mainモジュールがそれ自身のビルドを完全に制御できるようにします。(いつreplaceexcludeを使うかについては、以下のFAQ を参照してください)

Version Selection

todo

Semantic Import Versioning

todo

Modulesの使い方

Moduleをインストールしてアクティブにする

Go1.14ではデフォルトでインストールされているので飛ばす

Moduleを定義する

既存のプロジェクトのgo.modを作成するには、次のようにします。

1 GOPATHの外側にあるモジュールのソースツリーのルートに移動します。

$ cd <project path outside $GOPATH/src> # e.g., cd ~/projects/hello

2.初期モジュール定義を作成し、それをgo.modファイルに書き込みます。

$ go mod init

このステップでは、既存のdep Gopkg.lockファイルや他の9つのサポートされている依存関係フォーマットのいずれかから変換し、既存の設定にマッチするようにrequire文を追加します。

go mod initは、適切なモジュールパスを自動的に決定するために補助データ(VCSメタデータなど)を使用できますが、go mod initがモジュールパスを自動的に決定できないと述べている場合や、そのパスを上書きする必要がある場合には、たとえば、go mod initにオプションの引数としてモジュールパスを与えることができます。

$ go mod init github.com/my/repo

3.モジュールをビルドする

モジュールのルートディレクトリから実行されると、./... パターンは現在のモジュール内のすべてのパッケージにマッチします。go build` は、この特定のビルド呼び出しのためのインポートを満たすために必要に応じて、不足している依存関係や変換されていない依存関係を自動的に追加します。

$ go build ./...

4.選択したバージョンで動作することを確認するために、モジュールをテストする

$ go test ./...

5.(オプション)モジュールのテストと、すべての直接および間接的な依存関係のテストを実行して、非互換性をチェックする

$ go test all

リリースにタグを付ける前に、下記の「リリースの準備方法」を参照してください。

これらのトピックの詳細については、公式モジュールのドキュメントへの主要な入り口はgolang.orgにあります。

依存関係のアップグレードとダウングレード

リリースへの準備方法

モジュールをリリースする(すべてのバージョン共通)

モジュールをリリースする(v2以上)

リリースの公開

todo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment