Go1.11から導入されるvgoを試してみたメモ書きです。
基本的な流れは、和訳: A Tour of Versioned Go (vgo) (Go & Versioning, Part2)に沿っています。versioningが必要な理由や議論などは本記事では扱いません。
上記記事からvgoの開発が進みコマンドがいくつか変更になっていたので、同じくvgoを試す方の一助となればと思います。
今後も変更が入る可能性がありますが、x/vgo
からgo本体にマージされたので、いい区切りかと思い、記事としてまとめることにしました。
環境
❯ vgo version
go version go1.10.3 darwin/amd64 go:2018-02-20.1
vgoのインストール
❯ go get -u golang.org/x/vgo
vgoを動かしてみる
サンプルプログラム
// hello.go package main // import "github.com/you/hello" import ( "fmt" "rsc.io/quote" // この時点では、cannot find packageになるけどvgoが解決してくれる ) func main() { fmt.Println(quote.Hello()) }
あとは何も書いていないgo.mod
も作っておく。
❯ touch go.mod
vgo build
❯ vgo build vgo: resolving import "rsc.io/quote" vgo: finding rsc.io/quote v1.5.2 vgo: finding rsc.io/quote (latest) vgo: adding rsc.io/quote v1.5.2 vgo: finding rsc.io/sampler v1.3.0 vgo: finding golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c vgo: downloading rsc.io/quote v1.5.2 vgo: downloading rsc.io/sampler v1.3.0 vgo: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
これでbuildされるので、実行してみる。
❯ ./hello こんにちは世界。
空だったgo.mod
にも追記されている。
// go.mod module github.com/you/hello require rsc.io/quote v1.5.2
依存しているモジュールをvgo list -m
で表示できる。
コマンドが変更になったので、vgo list -m
だと1個しか出てこない。
→vgo list -m all
で全部出てくる。
❯ vgo list -m all github.com/you/hello golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c rsc.io/quote v1.5.2 rsc.io/sampler v1.3.0
Upgrade
-u
オプションでupdated packageを確認できる。コマンドが変わって[]
内にLATESTが表示されるようになった。
❯ vgo list -u -m all vgo: finding golang.org/x/text v0.3.0 vgo: finding rsc.io/sampler v1.99.99 github.com/you/hello golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c [v0.3.0] rsc.io/quote v1.5.2 rsc.io/sampler v1.3.0 [v1.99.99]
golang.org/x/text
をUpgradeしてみる。
❯ vgo get golang.org/x/text vgo: downloading golang.org/x/text v0.3.0
go.mod
が変わっている。
❯ git diff go.mod diff --git a/go.mod b/go.mod index 3200210..6246735 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,6 @@ module github.com/you/hello -require rsc.io/quote v1.5.2 +require ( + golang.org/x/text v0.3.0 + rsc.io/quote v1.5.2 +)
listで見ても以下のようにv0.0.0-20170915032832-14c0d48ead0c
からv0.3.0
になっていることがわかる。
❯ vgo list -m all
github.com/you/hello
golang.org/x/text v0.3.0
rsc.io/quote v1.5.2
rsc.io/sampler v1.3.0
テストしてみる。
❯ vgo test all ? github.com/you/hello 0.016s [no test files] ? golang.org/x/text/internal/gen 0.078s [no test files] ok golang.org/x/text/internal/tag 0.011s ? golang.org/x/text/internal/testtext 0.043s [no test files] ok golang.org/x/text/internal/ucd 0.015s ok golang.org/x/text/language 0.073s ok golang.org/x/text/unicode/cldr 0.132s ok rsc.io/quote 0.015s ok rsc.io/sampler 0.013s
rsc.io/quote
のv1.5.2
には以下のようにバグがあるが、上記のようにok
となる。
これは、all
の意味が"今の module 中の全てのパッケージと、それらが再帰的に import している全てのパッケージ"だから。
❯ vgo test rsc.io/quote/... ok rsc.io/quote (cached) --- FAIL: Test (0.00s) buggy_test.go:10: buggy! FAIL FAIL rsc.io/quote/buggy 0.008s
vgo get -u
ですべてのmoduleをupgradeできる。
❯ vgo get -u
vgo: finding rsc.io/quote latest
vgo: finding golang.org/x/text latest
vgo: finding rsc.io/sampler latest
vgo: finding golang.org/x/text latest
vgo: finding rsc.io/sampler latest
rsc.io/sampler
がv1.99.99
にupgradeされた。
❯ vgo list -m all
github.com/you/hello
golang.org/x/text v0.3.0
rsc.io/quote v1.5.2
rsc.io/sampler v1.99.99
でもテストには失敗する。
❯ vgo test all vgo: downloading rsc.io/sampler v1.99.99 ? github.com/you/hello 0.016s [no test files] ? golang.org/x/text/internal/gen 0.032s [no test files] ok golang.org/x/text/internal/tag (cached) ? golang.org/x/text/internal/testtext 0.020s [no test files] ok golang.org/x/text/internal/ucd (cached) ok golang.org/x/text/language (cached) ok golang.org/x/text/unicode/cldr (cached) --- FAIL: TestHello (0.00s) quote_test.go:19: Hello() = "99 bottles of beer on the wall, 99 bottles of beer, ...", want "Hello, world." FAIL FAIL rsc.io/quote 0.014s --- FAIL: TestHello (0.00s) hello_test.go:31: Hello([en-US fr]) = "99 bottles of beer on the wall, 99 bottles of beer, ...", want "Hello, world." hello_test.go:31: Hello([fr en-US]) = "99 bottles of beer on the wall, 99 bottles of beer, ...", want "Bonjour le monde." FAIL FAIL rsc.io/sampler 0.014s
Downgrade
v1.99.99
へUpgradeしたらテストに失敗してしまったので、Downgradeして戻すことにする。
戻せるバージョンに何があるのか確認。
❯ vgo list -m -versions all github.com/you/hello golang.org/x/text v0.1.0 v0.2.0 v0.3.0 rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1 rsc.io/sampler v1.0.0 v1.2.0 v1.2.1 v1.3.0 v1.3.1 v1.99.99
rsc.io/sampler
を一つ前のversionv1.3.1
へ戻す。
❯ vgo get rsc.io/sampler@v1.3.1 vgo: finding rsc.io/sampler v1.3.1 vgo: downloading rsc.io/sampler v1.3.1
rsc.io/sampler
がv1.99.99
からv1.3.1
にdowngradeされた。
❯ git diff go.mod diff --git a/go.mod b/go.mod index 6246735..a62aa4e 100644 --- a/go.mod +++ b/go.mod @@ -3,4 +3,5 @@ module github.com/you/hello require ( golang.org/x/text v0.3.0 rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.1 )
ちゃんとテストも通る。
❯ vgo test all ? github.com/you/hello 0.021s [no test files] ? golang.org/x/text/internal/gen 0.020s [no test files] ok golang.org/x/text/internal/tag (cached) ? golang.org/x/text/internal/testtext 0.031s [no test files] ok golang.org/x/text/internal/ucd (cached) ok golang.org/x/text/language (cached) ok golang.org/x/text/unicode/cldr (cached) ok rsc.io/quote 0.016s ok rsc.io/sampler 0.015s
もっと前のversionv.1.2.0
にすることもできる。
rsc.io/quote
も依存しているので一緒にdowngradeする必要がある。
❯ vgo get rsc.io/sampler@v1.2.0 vgo: finding rsc.io/sampler v1.2.0 vgo: finding rsc.io/quote v1.5.1 vgo: finding rsc.io/quote v1.5.0 vgo: finding rsc.io/quote v1.4.0 vgo: finding rsc.io/sampler v1.0.0 vgo: downloading rsc.io/sampler v1.2.0
ただし、テストに失敗する。
❯ vgo test all vgo: downloading rsc.io/quote v1.4.0 ? github.com/you/hello 0.019s [no test files] ? golang.org/x/text/internal/gen 0.023s [no test files] ok golang.org/x/text/internal/tag (cached) ? golang.org/x/text/internal/testtext 0.035s [no test files] ok golang.org/x/text/internal/ucd (cached) ok golang.org/x/text/language (cached) ok golang.org/x/text/unicode/cldr (cached) --- FAIL: TestHello (0.00s) quote_test.go:12: Hello() = "こんにちは世界。", want "Hello, world." FAIL FAIL rsc.io/quote 0.017s --- FAIL: TestHello (0.00s) hello_test.go:31: Hello([fr en-US]) = "Bonjour le monde.", want "Bonjour la monde." FAIL FAIL rsc.io/sampler 0.012s
none
で依存しているモジュールをすべて削除できる。
❯ vgo get rsc.io/sampler@none vgo: finding rsc.io/quote v1.3.0
こうするとテストが通る(全然モジュールが残っていないけど)。
❯ vgo test all vgo: downloading rsc.io/quote v1.3.0 ? github.com/you/hello 0.009s [no test files] ok rsc.io/quote 0.009s
Exclude
v1.99.99
がうまく動かないことを記録したい。
事前準備として、最新化しておく。
❯ vgo get -u
vgo: finding rsc.io/quote latest
vgo: finding golang.org/x/text latest
vgo: finding rsc.io/quote latest
vgo: finding rsc.io/sampler latest
vgo: finding golang.org/x/text latest
vgo: finding rsc.io/sampler latest
たしかにv1.99.99
になっている。
❯ vgo list -m all
github.com/you/hello
golang.org/x/text v0.3.0
rsc.io/quote v1.5.2
rsc.io/sampler v1.99.99
go.mod
にexclude "rsc.io/sampler" v1.99.99
を追加すればよい。
合わせてgo.mod
でrsc.io/sampler v1.3.1
にするのも忘れずに。
❯ vgo list -m all
github.com/you/hello
golang.org/x/text v0.3.0
rsc.io/quote v1.5.2
rsc.io/sampler v1.3.1
ちなみに、rsc.io/sampler v1.3.1
にするのも忘れると以下のようにエラーになってくれるのでちゃんとExcludeされている。
❯ vgo get -u vgo: github.com/you/hello() depends on excluded rsc.io/sampler(v1.99.99) with no newer version available
これでテストが通る。
❯ vgo test all ? github.com/you/hello 0.016s [no test files] ? golang.org/x/text/internal/gen 0.021s [no test files] ok golang.org/x/text/internal/tag (cached) ? golang.org/x/text/internal/testtext 0.021s [no test files] ok golang.org/x/text/internal/ucd (cached) ok golang.org/x/text/language (cached) ok golang.org/x/text/unicode/cldr (cached) ok rsc.io/quote (cached) ok rsc.io/sampler (cached)
Replace
依存していたrsc.io/quote
を置き換えてみる。
❯ git clone https://github.com/rsc/quote ../quote
../quote/quote.go
を以下のように書き換える。
// Hello returns a greeting. func Hello() string { // return sampler.Hello() // これを消して return sampler.Glass() // こっちを追加 }
go.mod
の末尾にreplace "rsc.io/quote" v1.5.2 => "../quote"
を追記する。
すると以下のようにreplaceされていることが確認できる。
❯ vgo list -m all github.com/you/hello golang.org/x/text v0.3.0 rsc.io/quote v1.5.2 => ../quote rsc.io/sampler v1.3.1
buildして実行する。
❯ vgo build ❯ ./hello 私はガラスを食べられます。それは私を傷つけません。