golang + Alpine は最高の方程式やん(開発環境から作ってみた)

ツール

前々から気になっていて、ちゃんと手を出せていなかった Go言語。
この週末でなにか書いてみようと思って、少し触ってみました。

開発自体は Windows でやっているのですが、Linux向けバイナリをクロスコンパイルして、Alpineベースの Docker イメージにすると、すごく良い感じでした。(20MBくらいに収まる…!)

まずは 開発環境

JetBrains に愛を捧げつつ、Vim や Sublime Text も使う浮気性なので、色々試してみました。VS Code? …流行りに逆らいたいお年頃なので、使いません。

Sublime Text 3

Sublime Text 3 でGo言語を扱おうとすると、色々と選択肢があるようですが…、開発が停止していたり、諸々でどれを使えばいいか分からない状態でした…。

今どきLSPだろうと思ったのですが、こちらを読むと GoSublimeの方が良い模様…。

というわけで、

GitHub - DisposaBoy/GoSublime: A Golang plugin collection for SublimeText 3, providing code completion and other IDE-like features.
A Golang plugin collection for SublimeText 3, providing code completion and other IDE-like features. - GitHub - DisposaBoy/GoSublime: A Golang plugin collection...

を使ってみました。Package Control にできていないようです。自分でパッケージディレクトリに git clone してkルウ必用があります。さらに、最初の一回は Sublime Text 実行後に “Ctrl + .” + “Ctrl + x” など、呪文を唱える必要があり(詳しくは公式ドキュメント参照)、インストール手順が面倒でした。

ですが、いざ環境を作ると、思ったより快適。後述の Goland には負けますが、補完等が効いた状態でサクサクと書くことが出来ました。

Goland

愛すべき、JetBrains社製IDE、Goland。みな使うべき。

特に設定に悩むことなく、 Go を書き始められました。
補完なども言うまでもなく完璧。全てが完璧。そう、Goland ならね。

vim + LanguageClient-neovim + go-langserver + vim-go

vim 環境が一番厄介かもしれません。色んなソリューションがありすぎます!

LanguageClient-neovim を使っているので、go-langserver と連携させて使います。
vim-go も補完機能を持っていますが、これは切っておくようにします。

GitHub - sourcegraph/go-langserver: Go language server to add Go support to editors and other tools that use the Language Server Protocol (LSP)
Go language server to add Go support to editors and other tools that use the Language Server Protocol (LSP) - GitHub - sourcegraph/go-langserver: Go language se...

go-langserver は `go get -u github.com/sourcegraph/go-langserver` でインストールしておきます。

あとは、vim の設定を追記していきます。(LanguageClient-neovimは導入済み…)

...(省略)

" Deinを使っているので、vim-go を追加
call dein#add('fatih/vim-go', {'do', ':GoInstallBinaries'})

...(省略)
" vim-go の補完機能を無効化する
let g:go_code_completion_enabled = 0

" go-langserver を使うように設定(python と ruby もLSPを使うようにしています)
" -gocodecompletion を付けてあげないと補完されなくなります。(ヘルプによると、メモリを凄く食うらしいです)
let g:LanguageClient_serverCommands = {
 \ 'python': ['pyls'],
 \ 'go': [$GOPATH.'/bin/go-langserver', '-gocodecompletion'],
 \ 'ruby': ['solargraph', 'stdio'],
 \ }
...(省略)

vim-go は gocode(かつてのGo補完の本命) だけじゃなくて、golsp (公式のLSPサーバー)にも対応しているようなので、そちらを使っても良いのですが…。なんとなく、設定を一箇所にまとめたいので、LanguageClient-neovim経由で設定してみました。

書いてみた

Redmine と Trello から、現在進行系のチケットを取ってきて、Microsoft Teams に発言させるというコードを書いてみました。

Trello にはこのライブラリ。

GitHub - adlio/trello: Trello API wrapper for Go
Trello API wrapper for Go. Contribute to adlio/trello development by creating an account on GitHub.

Redmine にはあまりいいライブラリが見当たりませんでした…ので、

Go言語でJSONに泣かないためのコーディングパターン - Qiita
いまになって見直してみると微妙な部分が多かったので、 この記事の Qiita での公開を終了することにしました。 いいね!&ストックして頂いた皆様、ありがとうございました。

この辺見ながら、ゴリゴリ書いてみました。 JSON で受け取って、あとはゴリゴリ…。
ゴリゴリ自分で書いた後に、こんなサービス見つけました。

JSON-to-Go: Convert JSON to Go instantly

もっと早く気づくべきだった(´°̥̥̥̥̥̥̥̥ω°̥̥̥̥̥̥̥̥`)

具体的なコードは割愛。( API Key などがワイヤードロジック状態でみせれない…笑)

あとは、Teams 向けには、Webhookを発行しておいて、発行した URLに Post でデータを送るだけなので、割愛。

Docker で イメージにしてみた

Go 言語なんで、環境毎にビルドしておいてもいいのですが、個人的には Docker でイメージ化したほうが楽なので、イメージ化してみました。

シンプルですが、こんな感じで Docker イメージを作ってます。

FROM alpine

RUN apk add --no-cache ca-certificates
COPY bin/whats_working /usr/local/bin/whats_working
RUN chmod +x /usr/local/bin/whats_working

CMD ["/usr/local/bin/whats_working"]

Goで作成したバイナリは素の Alpine Linux でも動くのですが、https 通信を行う場合は ca-certificates パッケージを入れておく必要があります。なにげに罠ですね。

あとは、開発をしている環境は Windows なので、クロスコンパイルの Makefile を書いて仕上げ。

BIN_WIN := bin/whats_working.exe
BIN_LINUX := bin/whats_working
DOCKER_IMAGE := whats_working

.PHONY: all
all: windows linux docker

.PHONY: windows
windows: $(BIN_WIN)

.PHONY: linux
linux: $(BIN_LINUX)

.PHONY: prepare
prepare:
	go get "golang.org/x/sync/errgroup"
	go get "github.com/adlio/trello"

$(BIN_WIN): **/*.go prepare
	CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o $(BIN_WIN) -v

$(BIN_LINUX): **/*.go prepare
	go install
	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $(BIN_LINUX) -v

.PHONY: clean
clean:
	go clean
	rm -f $(BIN_WIN)
	rm -f $(BIN_LINUX)

.PHONY: run
run:
	go run main.go

.PHONY: docker
docker: $(BIN_LINUX)
	docker build -t $(DOCKER_IMAGE) .

本当は go dep を使うべきですが、まだ間に合っていないです・・・。
とりあえず、自分で go get をしています。そのうち、置き換えなくちゃですね。

結構、快適な環境ができあがりました。満足。

コメント

タイトルとURLをコピーしました