この記事は Go7 Advent Calendar 2019 2日目の記事です。 https://qiita.com/advent-calendar/2019/go7
想定読者は初級者です。
複数のプロジェクトに携わっている場合、プロジェクトごとにGoのバージョンを切り替えたいことがあると思います。 また、Goのバージョンアップ前後の動作確認をしたいこともきっとあるはずです。
そこでGo のバージョンを切り替えるツール goenv
のインストールと使い方について書きます。
Goの記事ですがGoのコードはほぼ出現しません。
対象OSはUbuntu18.04です。もうすぐ20.04ですね..(遠い目)
今回利用する環境は以下のファイルで作ります。任意のディレクトリの同じ階層に配置してください。
FROM ubuntu:18.04 AS ubuntu-for-goenv
WORKDIR /root/
RUN set -x; \
apt update &&\
apt install -y git wget python3 python3-pip &&\
python3 -m pip install ansible
version: '3.7'
services:
goenv:
build: .
container_name: ubuntu18.04-for-goenv
tty: true
volumes:
- .:/root/
working_dir: /root/
Installation
手順 に従ってインストールしていきます。
root@1800db436399:~# git clone https://github.com/syndbg/goenv.git ~/.goenv
Cloning into '/root/.goenv'...
remote: Enumerating objects: 161, done.
remote: Counting objects: 100% (161/161), done.
remote: Compressing objects: 100% (93/93), done.
remote: Total 13996 (delta 78), reused 119 (delta 55), pack-reused 13835
Receiving objects: 100% (13996/13996), 2.53 MiB | 11.56 MiB/s, done.
Resolving deltas: 100% (9556/9556), done.
root@1800db436399:~# echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.bashrc
root@1800db436399:~# echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.bashrc
root@1800db436399:~# echo 'eval "$(goenv init -)"' >> ~/.bashrc
# goenv に GOPATH と GOROOT を管理させたい場合は `goenv init` の後ろに来るように以下を書き込む
root@1800db436399:~# echo 'export PATH="$GOROOT/bin:$PATH"' >> ~/.bashrc
root@1800db436399:~# echo 'export PATH="$PATH:$GOPATH/bin"' >> ~/.bashrc
# シェルを再読込すると
root@1800db436399:~# exec $SHELL
# 最新版が入りました
root@1800db436399:~# goenv --version
goenv 2.0.0beta11
これだけでは面白くないので Ansible でインストールできるように Playbook を作ります。
できあがったものがこちらです。ローカルで使うことを前提に作ってあります
- hosts: localhost
connection: local
gather_facts: false
tasks:
- name: clone goenv
git:
repo: https://github.com/syndbg/goenv.git
dest: ~/.goenv
force: yes
version: "{{ version | default('master') }}"
- name: set export GOENV_ROOT
lineinfile:
path: ~/.bashrc
regexp: '^export GOENV_ROOT="\$HOME/\.goenv"'
line: export GOENV_ROOT="$HOME/.goenv"
insertafter: EOF
- name: set export PATH
lineinfile:
path: ~/.bashrc
regexp: '^export PATH="\$GOENV_ROOT/bin:\$PATH"'
line: export PATH="$GOENV_ROOT/bin:$PATH"
insertafter: EOF
- name: set goenv init
lineinfile:
path: ~/.bashrc
regexp: '^eval "\$\(goenv init -\)"'
line: eval "$(goenv init -)"
insertafter: EOF
- name: set export PATH
lineinfile:
path: ~/.bashrc
regexp: '^export PATH="\$GOROOT/bin:\$PATH"'
line: export PATH="$GOROOT/bin:$PATH"
insertafter: EOF
- name: set eport PATH
lineinfile:
path: ~/.bashrc
regexp: '^export PATH="\$PATH:\$GOPATH/bin"'
line: export PATH="$PATH:$GOPATH/bin"
insertafter: EOF
実行してみます。
せっかくなのでStableなバージョン(執筆時は1.23.3) を入れてみます。
ただしStable版だと 1.12beta1
までしかインストールできないので、実際に導入する場合はバージョンを指定しないほうがよいでしょう。
- info
.bashrc
がないとエラーになった場合は空でもいいのでtouch .bashrc
のように作成してください。
# 一旦まっさらにして
root@8fff234db161:~# goenv
bash: goenv: command not found
# extra-vars でバージョン(タグ)を渡す
root@8fff234db161:~# ansible-playbook provision.yaml --extra-vars "version=1.23.3"
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
PLAY [localhost] ***************************************************************
TASK [clone goenv] *************************************************************
changed: [localhost]
TASK [set export GOENV_ROOT] ***************************************************
changed: [localhost]
TASK [set export PATH] *********************************************************
changed: [localhost]
TASK [set goenv init] **********************************************************
changed: [localhost]
TASK [set export PATH] *********************************************************
changed: [localhost]
TASK [set eport PATH] **********************************************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=6 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# シェルを再読込すると
root@8fff234db161:~# exec $SHELL
# インストールされてますね
root@8fff234db161:~# goenv --version
goenv 1.23.3
多分Ubuntuなら動くと思います。 git
とか入ってないとだめですが。
Use
話が横にそれましたが、さっきの続きです。
もう少しコマンドを触ってみましょう。
# コマンドの一覧
root@1800db436399:~# goenv commands
--version
commands
completions
exec
global
help
hooks
init
install
local
prefix
rehash
root
shell
shims
uninstall
version
version-file
version-file-read
version-file-write
version-name
version-origin
versions
whence
which
# 1.12.0 をインストール
root@1800db436399:~# goenv install 1.12.0
Downloading go1.12.linux-amd64.tar.gz...
-> https://dl.google.com/go/go1.12.linux-amd64.tar.gz
Installing Go Linux 64bit 1.12.0...
Installed Go Linux 64bit 1.12.0 to /root/.goenv/versions/1.12.0
# 1.13.4 をインストール
root@1800db436399:~# goenv install 1.13.4
Downloading go1.13.4.linux-amd64.tar.gz...
-> https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz
Installing Go Linux 64bit 1.13.4...
Installed Go Linux 64bit 1.13.4 to /root/.goenv/versions/1.13.
# バージョン一覧
root@1800db436399:~# goenv versions
1.12.0
1.13.4
root@1800db436399:~# ls ~/.goenv/versions/
1.12.0 1.13.4
# グローバルバージョンを 1.12.0 にセットする
root@1800db436399:~# goenv global 1.12.0
root@1800db436399:~# goenv versions
* 1.12.0 (set by /root/.goenv/version)
1.13.4
# subディレクトリを作り,ローカルバージョンを 1.13.4 にセットする
root@1800db436399:~# mkdir sub
root@1800db436399:~# cd sub/
root@1800db436399:~/sub# goenv local 1.13.4
root@1800db436399:~/sub# goenv versions
1.12.0
* 1.13.4 (set by /root/sub/.go-version)
# subディレクトリから出ると1.12.0 に戻る
root@1800db436399:~/sub# cd ..
root@1800db436399:~# goenv exec go version # goenv version でも可
go version go1.12 linux/amd64
root@1800db436399:~# goenv versions
* 1.12.0 (set by /root/.goenv/version)
1.13.4
# subディレクトリに入ると 1.13.4 が自動的にセットされる
root@1800db436399:~# cd sub/
root@1800db436399:~/sub# goenv exec go version # goenv version でも可
go version go1.13.4 linux/amd64
root@1800db436399:~/sub# goenv versions
1.12.0
* 1.13.4 (set by /root/sub/.go-version)
goenv のコマンド体系はシンプルでわかりやすいのであまりハマることはないと思いますが、 基本的なコマンドくらいはいつでも使えるようにしておきたいところですね
個人的に使いそうなサブコマンドを一覧にしてみました。
- exec
- 現在のセットされているバージョンの
go
コマンドを使って色々する -
$ goenv exec go run main.go
- 現在のセットされているバージョンの
- install
- 対象のGoバージョンをインストール
-
$ goenv install 1.13.4
- uninstall
- 対象のGoバージョンをアンインストール
-
$ goenv uninstall 1.12.0
- global
- デフォルト(グローバル)のGoバージョンを設定する
-
$ goenv global 1.12.0
- local
- そのディレクトリだけで有効な(ローカルの)Goバージョンを設定する
-
$ goenv local 1.13.4
- versions
- 利用可能なGoバージョンの一覧および現在のGoバージョンを表示する
-
$ goenv versions
- which
- 実行ファイルが置かれているファイルパスを表示する
-
$ goenv which gofmt
以上です。明日も書きます。