2019年5月12日日曜日

令和時代のGo開発

たまにはGoの話題でも。

Goで躓くのはGOPATHと外部モジュールの扱いかなと思ってます。
  • Goのソースは全部GOPATHに入れんとアカンの?
    • プロダクトを複数開発している場合はどうすりゃいいの?
  • 外部モジュールってバージョン指定できないの?
    • 外部モジュールに仕様変更があったらどうすりゃいいの?
今日はこのあたりについて書いてみます。

ちょっと前の話

以前のGoは、GOPATHは必ず指定して、Goのソースは全部$GOPATH/src以下に入れておけみたいな感じだったと思います。

1つのプロダクトしか開発しない場合はそれでもいいんですけど、複数のプロダクトを開発している場合だとソースがごっちゃになって、Gitとかのバージョン管理も面倒だったりします。

プロダクトごとに別のマシンとか仮想環境を使えるような状況ならいいですけど、そうじゃない人も多い。Google社内ではきっと使えるんでしょうけど。

外部モジュールについてもバージョン指定はできず、常に最新のバージョンをインストールする仕様です。
これについてはFAQ
  • 公開するパッケージは後方互換性に注意しろよ
  • 別の機能が必要なら、仕様を変更するんじゃなくて別の定数とか関数を追加しろよ
  • 根本的にいろいろ変えるなら新しいパッケージを作れよ
と書いてあります。

まあ分からんでもないんですが、問題はモジュールの作者が後方互換性を守る保証がないというところです。
あるいは、守っているつもりでも間違えて互換性を損ねてしまったり、そもそもバグを入れてしまう可能性もあります。

semverも後方互換性が損なわれることを前提とした仕様ですし、後方互換性が損なわれるたびにパッケージ名を変更していたら更新チェックツールが検出してくれず、せっかくの新機能や機能向上に気づけなかったり、不具合やセキュリティーホールの放置されたバージョンをずっと使い続けることにもなりかねません。

今の話

多分、上で書いた話は他の人も同じようなことを思っていたんでしょうね。
そしてGo開発チームと侃々諤々たる議論をしたんでしょうね(妄想)。

今のGoではこのあたりの問題は解消されています。

Goで開発する場合は、以下の2つのルールだけ覚えてください
  • Goのバージョンは1.12以降を使うこと
  • 新しいプロダクトを作るときは、プロダクト用のディレクトリー内でgo mod init プロダクト名と入力すること
これだけです。
GOPATHを設定する必要もなければ、1つのディレクトリー内で複数のプロダクトのソースを管理する必要もありません。

1.11でモジュール対応モード(module-aware mode)というものが実験的に、1.12で正式にサポートされました。
この機能により、モジュールのバージョン管理プロジェクト別ディレクトリーでの開発ができるようになりました。

外部モジュールは$HOME/go内にバージョン別にインストールされます。GOPATHが設定されている場合はその中にインストールされます。

プロダクト内で作ったモジュールは、プロダクト名/モジュールへのパスで参照できます。

個人的には、環境変数やらの下準備をしたり、プロジェクトに必要なモジュールをroot権限で入れたりといった環境汚染をせずに必要なものはユーザー権限、プロジェクトディレクトリー内で完結させたい派なので、この機能はちょっとうれしい。

それでは令和も楽しいGoライフを。

0 件のコメント:

コメントを投稿