Golandをつかいましょう 2019冬

# はじめに
この記事は、アドベントカレンダー [Go4](https://qiita.com/advent-calendar/2019/go4) の21日目の記事です。

みなさん、Goのエディタ何を使っていますか？
Vim? Vscode?

そうですね**Goland**を使いましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/8fa99a2b-5e86-bac7-85e5-2d50e73fcd4b.png)

# Golandの利点
- インストールしたらデフォルトでいい感じの環境
- JetBrainsのエディタはUI同じなので複数言語使う人におすすめ

# Golandはじめ方
それでは、Golandを始めていきましょう

*筆者がMacしか持ってないのでここではMacでやる手順を記載してしまいました。*
*ただし心配することはありません。JetBrains製品はWindows,Linuxもサポートしています。導入手順も大体同じです。多分。*

## Golandを買いましょう
Golandは有償です。初年度は1万円ですが、2年目以降はディスカウントされます。さらに使用していくうちにだんだんと多幸感に包まれるため、相殺され実質無料になります。

国内代理店のサムライズムさん経由なら若干安く購入することが出来ます。
また、日本語でのサポートも行っていただけるのでそちら経由で購入することをおすすめします。
https://samuraism.com/jetbrains/goland

実質無料なのですが、どうしても使ってから購入したい人は30日間のトライアルがあるのでそちらを利用してもいいかもしれません。

ここまできてまだお悩みなら一旦 [All Products Pack
](https://samuraism.com/jetbrains/all-products-pack)を購入された方がいいと思います。

こちらも初年度は3万円弱のお値段なのですが、継続3年目で2万円を切る値段にディスカウントされます。

もしあなたが、複数の言語を操るプログラマーなら迷わず購入するべきです。

*以降はサムライズムさんのサイトで購入した体で話を進めていきます。*

## インストールしましょう
購入してアクティベーションされるまで若干のタイムラグがあります。その間にGolandをインストールしておきましょう

**ちょっと待ってください。**Chromeで`Goland`と検索してダウンロードページに進もうとしませんでしたか？
JetBrains製品をインストールするために直接アプリをインストールするのは愚かです。
ToolBox Appをインストールしましょう
https://www.jetbrains.com/ja-jp/toolbox-app/

ToolBox Appを使うことで、ライセンスの自動適用、バージョン自動管理などを簡単に行うことが出来ます。

ToolBox Appを起動すると、なんか右上にメ●カ●のようなアイコンが表示されていませんか？
クリックしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/101eb94c-baff-f3d0-73aa-1ef958ad7413.png)

そこにGolandがありますね。
`Install`ボタンをポチりましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/8925c465-7592-7e6d-e55d-f1cbc9a15c15.png" width=50%>

そしてインストールされるのを待ちましょう。

....

## アクティベーションしましょう
ちょうど、アクティベーションメールが届く頃だと思います。
`Gmail`で確認しましょう。
こんな感じのメールにPDFが添付されているかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/d04d5ac3-6a92-0073-9b31-31544f5be231.png)

アクティベーション用URLをクリックして、流れでJetBrainsアカウントを作りましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/a3497a72-c7ee-4091-9243-c927f2d49030.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/786a3a4c-a4c3-9eb9-9a72-2896c2b25cf9.png)

そしてそのアカウントでToolBox Appにログインしましょう。
これでエディタ個別のアクティベーションが不要になり、以降は期限が切れるまでつかいたい放題です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/fa3d7483-f95e-46d7-967b-1cc6d1c6cd86.png" width=50% />

## Goをインストールしましょう
「は？ここでGo？Golandで全部揃うって言ったじゃん？嘘なの？」

と思われるかもしれませんが、Golandと同じくらい便利なツールがあります。

`anyenv`です。

「は？goenv入れておけばいいやん。なんで？」
と思われるかもしれませんが、anyenvを入れておけば、他言語も使えるからとりあえず入れとこ?な？

brewで入れて環境変数をゴニョゴニョするだけです。入れておきましょう。
https://github.com/anyenv/anyenv#homebrew-for-macos-user

### GOENV_DISABLE_GOPATH=1
悪いこと言わないので`~/.bash_profile`とかに
`export GOENV_DISABLE_GOPATH=1`を追加しておいてください。
何も考えずにとりあえず追加しておいてください。
理由を知りたい人はこちらにありがたい記事があるので見ておいてください。
https://qiita.com/gimKondo/items/add08298e24ae400505e
(自分もハマってた)

### goの最新版をインストールしてください。

```
goenv install -l # インストール可能なバージョン確認
goenv install 1.13.4 # 最新バージョンインストールしてね
goenv global 1.13.4
```

## goimportsをインストールしておきましょう

```
go get golang.org/x/tools/cmd/goimports
```

## Xcodeをインストールしましょう
何も考えずにとりあえず入れておきましょう。
インストール超長いんですが、業務時間に入れて構いません。

入れたら、下記のコマンドをやってください。

```
xcode-select
```

そんで環境変数を追加してください。
これも`~/.bash_profile`とかに突っ込んでおけばいいです。

```
export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)"
```

理由はOSXのアップデートのたびに、SDKROOTのパスがコロコロ変わるからなんですが、
ありがたい記事で解説されているので、参照されるといいと思います。
https://qiita.com/imbsky/items/da709a514dded95b8575

## Golandを立ち上げましょう
あなたは今使っているエディタに不満を持っていて、Golandに乗り換えようとしていると仮定しましょう。
ただし、手元には他エディタで作業しているプロジェクトフォルダがあります。

ToolBox AppからGolandを立ち上げてください

そして、あなたのいつも作業しているプロジェクトフォルダを開いてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/707c3c91-5168-2f0a-37ea-91519426c9a6.png)

開きましたね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/400a6359-62fc-6017-e434-cc0d2293c0ea.png)

後少しで開発出来ます。

## 設定をしましょう
### GOROOT
`Command + ,` でPreferences(設定画面)が開きます。
`Go > GOROOT`で設定しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/238fd517-8ae3-49a4-796b-649d160ff326.png)

### Go Module
GolandはGo Moduleに対応しています。
`Go > Go Modules(vgo)`で`Enable Go Modules(vgo) integration`にチェックしましょう
`Proxy`は`direct`にしておいてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/8c024564-4d12-681d-9ee5-056ebbaf81df.png)

*Dep,Go Mdudle Vendoring modeにも対応していますが、絶対にやめておきましょう。*
*Go Moduleを使っている限り、プロジェクトフォルダに`vendor/`が存在することに何の意味もありません。(個人の感想です)*

## コーディングしましょう
おめでとうございます！ここまできたら、Golandでの開発環境は整いました！
あとはザクザクコーディングしていくだけです！Golandの世界へようこそ！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/ae8cfb76-f0dd-c715-23ed-8cdfec8fb1ac.png" width=50% />

### プラグインを入れておきましょう
どんなにデフォでいい感じと言いつつも、やれvimバインドしたいだの、github連携させたいだの
個人の趣味に合わせた使い方をしたい場合はプラグインをインストールすることが出来ます。

僕は本当はデフォでも大丈夫なんですが、下記のプラグインとか入れています。

- ideaVim
- .ignore
- BashSupport
- Github
- Docker

### コーディングサンプル
先ほど、あなたのプロジェクトフォルダを開いてもらったのですが、いったん閉じていただいて、
ここではサンプルを使って、Golandでのコーディング作業を見ていきましょう。

こちらのコードを下記のディレクトリ構成にして貼り付けてください

```
project/
  `- sample/
      |- mocks/
      `- sample.go
       |- sample.go
       `- sample.test.go
```

```sample/sample.go
package sample

import (
	"fmt"
)

type HogeClient interface {
	Do() error
}

type Sample struct {
	HogeClient HogeClient
}

func (s *Sample) Do() error {
	err := s.HogeClient.Do()
	if err != nil {
	  return fmt.Errorf("えらーだよ : %w", err)
	}
	return nil
}
```

```sample/sample_test.go
package sample

import (
	"fmt"
	"testing"

	"github.com/golang/mock/gomock"
	"github.com/junpayment/sample/sample/mocks"
	"github.com/stretchr/testify/assert"
)

func TestSample_Do(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		ctrl := gomock.NewController(t)
		mock := mocks.NewMockHogeClient(ctrl)
		mock.EXPECT().Do().Return(nil)
		s := &Sample{HogeClient: mock}
		err := s.Do()
		assert.Nil(t, err)
	})
	t.Run("failed", func(t *testing.T) {
		ctrl := gomock.NewController(t)
		mock := mocks.NewMockHogeClient(ctrl)
		mock.EXPECT().Do().Return(fmt.Errorf("test"))
		s := &Sample{HogeClient: mock}
		err := s.Do()
		assert.Nil(t, err)
	})
}
```

```sample/mocks/sample.go
// Code generated by MockGen. DO NOT EDIT.
// Source: sample/sample.go

// Package mocks is a generated GoMock package.
package mocks

import (
	gomock "github.com/golang/mock/gomock"
	reflect "reflect"
)

// MockHogeClient is a mock of HogeClient interface
type MockHogeClient struct {
	ctrl     *gomock.Controller
	recorder *MockHogeClientMockRecorder
}

// MockHogeClientMockRecorder is the mock recorder for MockHogeClient
type MockHogeClientMockRecorder struct {
	mock *MockHogeClient
}

// NewMockHogeClient creates a new mock instance
func NewMockHogeClient(ctrl *gomock.Controller) *MockHogeClient {
	mock := &MockHogeClient{ctrl: ctrl}
	mock.recorder = &MockHogeClientMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockHogeClient) EXPECT() *MockHogeClientMockRecorder {
	return m.recorder
}

// Do mocks base method
func (m *MockHogeClient) Do() error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Do")
	ret0, _ := ret[0].(error)
	return ret0
}

// Do indicates an expected call of Do
func (mr *MockHogeClientMockRecorder) Do() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Do", reflect.TypeOf((*MockHogeClient)(nil).Do))
}
```

さらにいろいろ`go get`してください

```
go get github.com/golang/mock
go get github.com/stretchr/testify
```

この状態で、ここの緑の三角をクリックしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/fc4f8315-4aa2-df70-24e6-cb9821529efd.png)

そして`Run`するとテスト実行されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/01d1b54f-8293-2943-c0f2-967c7caa9ee9.png)

こんな感じでまじでほとんど何もしなくてもデフォでデバッグ出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/62f8e9de-6c47-21b7-cc93-084e6e7da026.png)

おっとテスト失敗しましたね。
テストを書き直して失敗したテストだけやり直しましょう。

```sample/sample_test.go
	t.Run("failed", func(t *testing.T) {
		ctrl := gomock.NewController(t)
		mock := mocks.NewMockHogeClient(ctrl)
		mock.EXPECT().Do().Return(fmt.Errorf("test"))
		s := &Sample{HogeClient: mock}
		err := s.Do()
		assert.NotNil(t, err) // ここ
	})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/72168081-be7e-0a2c-4b0c-0e9a1a98bc1b.png)

楽ぅ〜

デバッグモードでも実行出来ます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/285b4de3-2dfb-62f1-c382-57465c58492d.png)

ブレークポイントも貼りましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/56142433-988b-a09a-df2a-fefe1c47d955.png)

条件付きのブレークポイントも貼りましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/6282fa3a-fa6f-9ba3-3e35-dfd1af9b3538.png)

便利ぃ〜

## 最後に
ここまで来たら、もはや今までのエディタをアンインストールし、全てのJetBrains製品をインストールするのみです。

Goland,JetBrains人口は他のエディタに比べて少ないのですが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12060/c6c5293a-ec81-a172-8a2a-0f77d6f31308.png)
[引用]https://job-draft.jp/articles/323

`デフォルト状態でいい感じに開発スタートできる(当社比)`, `すぐコーディング作業に没頭することのできる(当社比)`という利点は
各プログラミング言語ごとに最適化された製品があるJetBrainsならでは無いでしょうか？だよね？

みなさんGolandつかいましょう。