Go Modulesの仕組み Bundler(Ruby)との比較を添えて
by
どすこい
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Go Modulesの仕組み ~Bundler(Ruby)との⽐較を添えて~ 1 どすこい Fukuoka.go#21
Slide 2
Slide 2 text
2 GMOペパボ Webエンジニア どすこい Daisuke Takeda k1low⽒の弟⼦に習って(=孫弟⼦)、 Goが好きになっちゃったエンジニア 配属先はRails/PHPですが、 そこでもGo⾰命を起こします!! Goコミュニティに参加してくぞ〜! X: @doskoi64
Slide 3
Slide 3 text
PythonやRubyで、 考えなしにパッケージを⼊れると 依存関係解消が失敗することがある... マイナーバージョンアップでも 壊れることある.... ある⽇ イントロダクション 3
Slide 4
Slide 4 text
Railsの場合 イントロダクション 4 Railsガイド https://railsguides.jp/maintenance_policy.html 破壊的変更するんだ...?🤔
Slide 5
Slide 5 text
⼀⽅で Goではあんまり気にしたことないなぁ なんで気にしなくていいんだろ...? ある⽇ イントロダクション 5
Slide 6
Slide 6 text
Go 1.11より イントロダクション 6 https://github.com/golang/go/issues/24301
Slide 7
Slide 7 text
Go 1.11より イントロダクション 7
Slide 8
Slide 8 text
Go 1.11より イントロダクション 8 (前略)、Bundler/Cargo/Depのアプローチの詳 細と、それをGoに組み込むことの意味をより深 く理解し、(中略)、いくつかの細部がGoには適 していないと次第に感じるようになりました。 最初は同じ感じだったんだ? 何が違うんだ?
Slide 9
Slide 9 text
9 今⽇話すこと ● Go Modulesの依存解決の仕組み ● Bundler(Ruby)との⽐較 今⽇話さないこと ● Go Modulesでどこがどう動いてるのか ● Bundlerがどこでどう動いてるのか ● これらの歴史的な経緯
Slide 10
Slide 10 text
Go Modulesの仕組み Go Modulesとは ● Go 1.11から導⼊ ● モジュール:複数のパッケージをまとめてリリース/バージョン管理/配布するための 単位。GitHubやモジュールプロキシサーバからダウンロードが可能 ● モジュールパスによって⼀意に識別してgo.modで宣⾔ ● go.sumにモジュールのハッシュが保持され、ダウンロードしたモジュールの内容が 相違ないかチェック 10 https://go.googlesource.com/proposal/+/master/ design/24301-versioned-go.md ref: Go Modules Reference (https://go.dev/ref/mod)
Slide 11
Slide 11 text
11 Go Modulesの仕組み https://github.com/golang/go/issues/24301 昔はdep, glideなど外部 ツールを⽤いていた。 標準化しようぜ!
Slide 12
Slide 12 text
Go Modulesの仕組み ● go.modに列挙された直接依存から、それぞれが要求す る他の依存(間接依存)を再帰的に集めてビルドリストを 作成 ● 各モジュールでは必要最低限のバージョンを宣⾔ ● これを⽤いてMinimal Version Selection (MVS)で最終 的な依存バージョンを決定 依存解決 12
Slide 13
Slide 13 text
Go Modulesの仕組み ● go.modに記載された直接依存が必要とする依存(間接依 存)を再帰的に収集 ○ 各モジュールは必要最低限なバージョンを指定するた め、すべての依存先から集まった最⼩の要件の中で、 最⼤値となるバージョンが選ばれる ○ module Aではhoge v1.2.3が、module Bでは hoge v1.5.0が要求される時はv1.5.0を採⽤ Minimal Version Selection (MVS) 13
Slide 14
Slide 14 text
Go Modulesの仕組み module Aでhoge v1.2.3が、 module Bでhoge v1.5.0が使われてる→v1.5.0を採⽤ そぼぎ(素朴な疑問) 14 けど、なんでmodule Aでは v1.5.0で動く前提なの?
Slide 15
Slide 15 text
Go Modulesの仕組み module Aでhoge v1.2.3が、 module Bでhoge v1.5.0が使われてる→v1.5.0を採⽤ そぼぎ(素朴な疑問) 15 けど、なんでmodule Aでは v1.5.0で動く前提なの? Semantic Versioningのルールより モジュールパスが同じなら後⽅互換がある! (逆に⾔えばこれが前提のシステム)
Slide 16
Slide 16 text
Go Modulesの仕組み そぼぎ(素朴な疑問) 16 じゃあmodule Aではv1.2.3が、module Bではv2.1.0が 使われてる時、v2.1.0を採⽤するの?(A壊れない?)
Slide 17
Slide 17 text
Go Modulesの仕組み そぼぎ(素朴な疑問) 17 じゃあmodule Aではv1.2.3が、module Bではv2.1.0が 使われてる時、v2.1.0を採⽤するの?(A壊れない?) モジュールパスが異なるv1, v2両⽅採⽤する! ex) gihub.com/oklog/ulidとgithub.com/oklog/ulid/v2 別モジュールとして扱われるので、 v1.2.3とv2.1.0の両⽅をimportすることで 対処できる
Slide 18
Slide 18 text
Go Modulesの仕組み 詳しくはGO Conference2024ののびしーさんの発表があります! 18 https://gocon.jp/2024/sessions/13/
Slide 19
Slide 19 text
Rubyとの⽐較 ● gem の依存関係とバージョンを管理するための ツール ● Gemfileで任意にgemのバージョン を指定できる ○ = のほかに、<=, >などで⼤⼩関係で指定できる Bundler 19
Slide 20
Slide 20 text
Rubyとの⽐較 Gemfileに指定された制約を解析し、 全ての制約を満たすバージョンの 組み合わせを探す ⼤変らしい(NP完全) https://arxiv.org/pdf/2011.07851 (⾼速な解法がないとも⾔えるかも) Bundlerの依存解決アルゴリズム 20
Slide 21
Slide 21 text
Rubyとの⽐較 ● Aでは ○ Cについて”>= 1.0, < 3.0” ● Bでは ○ Cについて”>= 3.0, < 3.5” Bundlerが困る時: 解がないとき 21 最適なバージョンがない場合が発⽣しうる ※ (補⾜) 別gemとして別バージョンを利⽤する⽅法はあるらしい けどGo Modulesはシンプルで⼀意に決まります → 解なし...
Slide 22
Slide 22 text
⽭盾の例 ● Aでは ○ Cについて”>= 1.0, < 3.0” ● Bでは ○ Cについて”>= 3.0, < 3.5” Rubyとの⽐較 なんでGoだとこうならないの? 22 Goでは、C v1.0とC v3.0を 別モジュールとしてimportできる
Slide 23
Slide 23 text
⽭盾の例2 ● Aでは ○ Cについて”>= 1.0, < 1.5” ● Bでは ○ Cについて”>= 1.6, < 2.0” Rubyとの⽐較 なんでGoだとこうならないの? 23
Slide 24
Slide 24 text
⽭盾の例2 ● Aでは ○ Cについて”>= 1.0, < 1.5” ● Bでは ○ Cについて”>= 1.6, < 2.0” Rubyとの⽐較 なんでGoだとこうならないの? 24 Semantic Versioningの後⽅互換の前提があるので マイナーバージョンの上限を指定しないので起こらない → v1.6になる
Slide 25
Slide 25 text
まとめ Go ModulesはSemantiv Versioning を前提に依存関係解消をしている 任意にバージョンを指定できる⾔語の 場合、最適なバージョンをソルバーが 解く必要がある Go Modulesはルールによってシンプル さを獲得した具体例かもしれない 25 今⽇話したこと
Slide 26
Slide 26 text
26 Let’s Go