Help us understand the problem. What is going on with this article?

Goで開発を始める前に絶対に読んでほしいGolandの設定3選

More than 1 year has passed since last update.

この記事は全部俺 Advent Calendar 2018の6日目の記事です。

完成形

  • 開発環境をDocker化してローカル環境から切り離す
  • go fmtgoimportsなどの各種静的解析/整形ツールをファイル保存時に自動実行するようにする
  • pre-commitファイルを設定して、golintがエラーを出力する場合にはcommit自体できないようにする

開発環境のDocker化

Docker containerの作成

  1. Dockerが入っていない場合はマシンにDockerをインストールします。
  2. Golandを立ち上げて、PluginsからDocker integrationをインストールし、Golandを再起動します。
  3. 新規Projectを作成し、下の画像1.のように、DockerタブからDocker→imagesを選んで右クリックし、Pull Image...を選択します。
  4. Repositoryにgolangを入力し、OKを押すと、golang:latestのDocker Imageがプルされるはずです。
  5. imagesにgolang:latestが作成されるので、右クリックしてCreate containerを選択し、Create...を選びます。
  6. 画像2.のように、Name/Image ID/Container Nameを設定・確認し、Runを押します。

画像1. Docker Hubからgolangイメージをpullする
image.png

画像2. Docker containerを作成する
image.png

実行の構成を編集

Hello, World!を表示するファイルを作成し、これをDocker環境で実行できるように実行の構成を編集します。
まず、以下の実行ファイルを作成します。

~/hello.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

次に、以下の画像のように、Run Configurationsを編集します。
- Commandをgo run /go/src/golang-sample/hello.goに変更
- Run optionsを-v [プロジェクトルートパス]:/go/src/golang-sampleに変更

image.png

この状態でRunを実行すると、以下のようにDocker container内でHello, World!が出力されます。
image.png

これで実行環境のDocker化は完了です。

ファイル保存時に自動でgo fmtなどの各種整形ツールを実行させる

pluginのインストール

Pluginsから、File Watchersをインストールし、Golandを再起動します。
後は、以下の整形ツールのうち、使うものについて設定してください。
【2019/09/03追記】
全部入りのファイルを以下のgistに配置しているので、こちらをローカルにファイル保存したものをimportすることでも設定完了できます。
- File Watchers設定ファイル

image.png

私は上の画像のように、ファイルをimportした後、File Watchersの適用LevelをGlobalにして使用しています。こうすることで、Projectごとに以下の作業を繰り返すことなく、いつも同じLinterツールを同じように使用することができます!

go fmt/goimports

アクション検索から、File Watchersを検索して、ToolsのFile Watchersに移動し、+ボタンを押してgo fmtまたはgoimoprtsを押します。
これらのツールについては以上で完了です。
image.png

golint

go get -u golang.org/x/lint/golintでgolintをインストールし、File Watchersの設定画面で<custom>を選択し、下記のように設定します。

image.png

goreturns

go get -u sourcegraph.com/sqs/goreturnsでgoreturnsをインストールし、File Watchersの設定画面で<custom>を選択し、下記のように設定します。

image.png

go vet

File Watchersの設定画面で<custom>を選択し、下記のように設定します。

image.png

実行確認してみる

以下のようなJSONファイルを読み込んで表示するGoファイルを作成してみます。
lintで自動整形されることを確認するために、わざと不要な改行を入れたり、import順番をめちゃくちゃにしたりしています。

~/json_reader.go
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "io/ioutil"
)

type Product struct {
    Id    int
    Name  string
    Price int
}

func main() {
    bytes, err := ioutil.ReadFile("vro.json")
    if err != nil {
        log.Fatal(err)
    }



    var products []Product
    if err := json.Unmarshal(bytes, &products); err != nil {
        log.Fatal(err)
    }

    for _, p := range products {
        fmt.Printf("%d : %s: %d\n", p.Id, p.Name, p.Price)
    }
}

このファイルについて、⌘ + Sや Ctrl + Sでファイル保存をしてみると、import順序を修正したり、不要な改行が削除され、次のようにファイルが自動整形されるはずです。

~/json_reader.go
package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
)

type Product struct {
    Id    int
    Name  string
    Price int
}

func main() {
    bytes, err := ioutil.ReadFile("vro.json")
    if err != nil {
        log.Fatal(err)
    }

    var products []Product
    if err := json.Unmarshal(bytes, &products); err != nil {
        log.Fatal(err)
    }

    for _, p := range products {
        fmt.Printf("%d : %s: %d\n", p.Id, p.Name, p.Price)
    }
}

地味にファイル末尾の改行も追加されたりしています。
更に、golintを適用している場合はlint結果として、以下の内容が画面下部のRunウィンドウに出力されているはずです。

/go/bin/golint /go/src/golang-sample/json_reader.go
/go/src/golang-sample/json_reader.go:10:6: exported type Product should have comment or be unexported
/go/src/golang-sample/json_reader.go:11:2: struct field Id should be ID

結果を読むと、Errorというほどでは無いが、先程のGoファイルにおいて、以下の改善点が見つかったようです。
- Productにcommentを書くべき
- Idという名前をIDという名前に変更したほうが良い

指摘されたとおりに修正を行って再度ファイル保存をすると、上記の指摘が消えることが確認できます。

pre-commitを用いてイケてないソースコードのコミットを阻止する

pre-commitとは?

.git/hooks/以下に配置されているファイル群の1つです。
.git/hooks/のファイル群は、何かのイベントにフックされて記載されている処理を行うものになります。
pre-commitはそのうちのcommit前に呼び出されるもので、これを編集することでcommit前にgolintを走らせ、結果がNGだった場合はコミット自体できないようにすることが可能です。

pre-commitファイル

下記のファイルを.git/hooks/pre-commitとして保存することで、git commitを失敗する環境を作ることができます。
前提として、golintがインストールされていることが必要なのでない場合はgo get -u golang.org/x/lint/golintしておいてください。

[project-root]/.git/hooks/pre-commit
#!/usr/bin/env bash

failed=false

for file in "$@"; do
    # redirect stderr so that violations and summaries are properly interleaved.
    if ! golint -set_exit_status "$file" 2>&1
    then
        failed=true
    fi
done

if [[ $failed == "true" ]]; then
    exit 1

上記のファイルを作成した上で、先程のjson_reader.goのIDをIdに戻してコミットしようとすると、以下のような結果が出てコミットが失敗するようになります。

~/g/s/golang-sample> git commit -m "test commit"
On branch master
Changes not staged for commit:
        modified:   json_reader.go

上記のようなツールを使いこなして、より良い開発環境を作成していきましょう!
他に便利なツールがある場合、コメントなどでご教授いただけると幸いです!

tez
libora
e-Learning一括検索サービス『LIBORA』の開発・運営を行っています。
https://libora.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away