42
52

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Golang - Go Modulesで開発環境の用意する

Last updated at Posted at 2019-10-01

はじめに

今まで以下の流れで開発環境を用意しました。

GoModulesの存在を知り、以下の理由からもう一度開発環境を見直すことにしました。

  • バージョン管理のデファクトスタンダードになる(なってる?)GoModulesを理解したかった
  • GoModulesを使用することで、設定に苦しんだGOPATH関連の制限から解放されそうだった

Go Modules

GoModulesは、Go1.11から導入され始めたGoの新しいバージョン管理システムになります。
詳細については、以下を参照いただくのが良いと思います。
GoModulesの概要から、今までのバージョン管理との違いまで把握できます。

GOPATH mode から module-aware mode

今まで(GOPATH mode)は標準pkg以外を全部 $GOPATH 以下のディレクトリで管理する仕様となっており
プロジェクトも $GOPATH/src 配下に作成する必要がありました。この制約で上記の開発環境を用意する際にかなり苦しみました。

しかし、module-aware mode では標準pkg以外の全てのパッケージをモジュールとして扱い、モジュールの管理やビルドが任意のディレクトリで可能になりました。($GOPATH/src にプロジェクトを配置しちゃダメというわけではなそう)

環境構築

go(1.10以降)とVSCodeはインストール済みの状態から始めたいと思います
私はgo(1.13.1)、VSCode(1.38.1)でやっています

環境変数

.zshrc(Shellによる)
export PATH=$GOPATH/bin:$PATH
export GOPATH=$HOME/go
export GO111MODULE=on

※GOPATHはプロジェクトと違うディレクトリで試したかったので $HOME/go にしています

GO111MODULE はGOPATH modeとmodule-aware modeを切り替えるための環境変数です。
Go 1.13からデフォルトが on になる予定だったようですが、どうやら auto がデフォルトになっているそうです。
そのため環境変数に上記を設定します。

  • on :Go modules を使う (module-aware mode)
  • off :$GOPATH を使う (GOPATH mode)
  • auto :$GOPATH/src の外に対象のリポジトリがあり、 go.mod が存在する場合は module-aware mode、そうでない場合は GOPATH mode

ディレクトリの作成

以下の構成でディレクトリを作成します

参考:Modules#quick-start

$  tree -F GolangProjects
GolangProjects
└── github.com/
    └── so-heee/
        └── modules_example/

モジュールの初期化

以下のコマンドでモジュールを初期化します
初期化すると go.mod ファイル(モジュールを管理するファイル)が出来ます

$ go mod init github.com/so-hee/modules_example
go: creating new go.mod: module github.com/so-hee/modules_example
└── modules_example
    └── go.mod

サンプルプログラムの作成

hello.go
package main

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

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

ビルドと実行

作成したファイルをビルドすると、依存パッケージである rsc.io/quote がダウンロードされます

$ go build -o hello
go: finding rsc.io/quote v1.5.2
go: downloading rsc.io/quote v1.5.2
go: extracting rsc.io/quote v1.5.2
go: downloading rsc.io/sampler v1.3.0
go: extracting rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: extracting golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: finding rsc.io/sampler v1.3.0
go: finding golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c

GOPATHに設定したディレクトリにパッケージがダウンロードされています

$ tree -F go -L 3 -d
go
└── pkg
    └── mod
        ├── cache
        ├── golang.org
        └── rsc.io

また go.sum ファイル(依存モジュールのチェックサムの管理をしてるファイル)が作成されています
ビルドしたファイルを実行してみます

$ ./hello
Hello, world.

VSCodeでの環境設定

上記のフォルダをVSCodeで開きます

拡張機能インストール

Cmd + Shif + x でExtensionMarketplaceを開いてGoをインストール

スクリーンショット 2019-09-22 20.03.18.png

先ほど作成したhello.goのファイルを開くとツールのパッケージをインストールするか聞かれるのでインストールしましょう

スクリーンショット 2019-10-01 16.15.05.png

聞かれない場合がもしあった場合は、Cmd + Shift + P でコマンドパレットを表示
GO: Install/Update Tools で全て選択してインストールしましょう

独自パッケージの作成

新規でパッケージを作成し、mainでimportしてみます

modules_example/calc/calc.go
package calc

// Sum は引数a, bを合算して返却します
func Sum(a, b int) int {
	return a + b
}
hello.go
package main

import (
	"fmt"

	"github.com/so-heee/modules_example/calc"
	"rsc.io/quote"
)

func main() {
	fmt.Println(quote.Hello())
	fmt.Println(calc.Sum(1, 2))
}

問題なくimportできたので、実行してみます。F5でデバッグしてみます

Hello, world.
3

Dockerを使った開発環境の設定

dockerのインストール

Homebrewでdockerをインストールします(Homebrewの使い方は省略します)

$ brew cask install docker
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> Updated Formulae
dbmate                kops                  mosquitto            rabbitmq

==> Satisfying dependencies
==> Downloading https://download.docker.com/mac/stable/38240/Docker.dmg
######################################################################## 100.0%
==> Verifying SHA-256 checksum for Cask 'docker'.
==> Installing Cask docker
==> Moving App 'Docker.app' to '/Applications/Docker.app'.
🍺  docker was successfully installed!

$ docker --version
Docker version 19.03.2, build 6a30dfc

VSCodeにRemote-Containersのインストール

Cmd + Shif + x でExtensionMarketplaceを開いて Remote-Containers を検索してインストールします

スクリーンショット 2019-09-26 12.36.38.png

設定ファイルの作成

左下の矢印アイコンを選択します

スクリーンショット 2019-09-26 12.33.32.png

今度は Remote-Containers: Add Development Container Configuration Files を選択します
何の開発環境を作るか聞かれるためGoを選択します

スクリーンショット 2019-09-26 17.33.21.png

選択すると先ほどのサンプルであった.devcontainerディレクトリが作成され
その下にdevcontainer.jsonDockerfileが入っています

スクリーンショット 2019-10-01 17.03.23.png

Dockerコンテナの作成

左下の矢印アイコンを選択します

Remote-Containers: Open Folder in Container を選択し、フォルダを選択します
スクリーンショット 2019-09-26 12.33.09.png

ビルドが開始されます

スクリーンショット 2019-09-26 13.56.13.png

スクリーンショット 2019-09-26 17.41.31.png

ビルド中にdetailsを押すと、ターミナルにビルドの状況が表示されます

完了するとエクスプローラーに表示されます

スクリーンショット 2019-10-01 17.13.00.png

コンテナ上でGOのプログラムを実行

ターミナルタブを開いて、右側のプルダウンを 1:bash にします
hello.goを実行してみます

するとコンテナ上のGOPATH(devcontainer.jsonのgo:gopath)に依存パッケージがダウンロードされます
ローカルの時と同じですね。

root@4f93101644d1:/workspaces/GolangProjects/github.com/so-heee/modules_example# go run ./hello.go 
go: downloading rsc.io/quote v1.5.2
go: extracting rsc.io/quote v1.5.2
go: downloading rsc.io/sampler v1.3.0
go: extracting rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: extracting golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: finding rsc.io/quote v1.5.2
go: finding rsc.io/sampler v1.3.0
go: finding golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
こんにちは世界。
3

※こんにちは世界になるのは別の問題だと思うので今回は無視します(F5実行は問題ありません)

課題(依存先モジュールの編集する時)

githubで公開すると、基本的にそちらを参照してしまうため、ローカルで修正しても動作が変わりませんでした。。。
対応策としてgo.modを一時的に書き換えてreplaceディレクティブを使う方法や、go mod vendor でvendorを書き出してしまってそれを編集するなどがあるようですが、そもそも開発スタイルが正しいのか不安が残ります。
こちら解決策ご存知の方、もしくは別の方法をとってる方などいましたら是非ご教示ください!!

参考:最近のGo Modulesプラクティス ~ ghqユーザーの場合も添えて

参考

42
52
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
52

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?