Go の import エイリアスを統一するツール goalias を作った話

に公開

はじめに

みなさん、はじめまして。日頃は主にバックエンド開発をしている @jackchuka です。Zenn では初投稿となりますので、暖かく見守っていただければ幸いです!

今回は、直近 OSS として公開した「Go のインポートエイリアスを統一するための CLI ツール」goalias の公開した経緯と、その技術的な実装についてお話ししたいと思います。

https://github.com/jackchuka/goalias

突然ですが、Go でチーム開発をしていると、こんな光景を見たことはありませんか?

// file1.go
import "encoding/json"

// file2.go
import json "encoding/json"

// file3.go
import ejson "encoding/json"

同じencoding/jsonパッケージなのに、ファイルによってエイリアスがバラバラ...。特に大規模なプロジェクトでは、こういったことがよく起こります。

コードレビューで「ここのインポート、他と揃えてもらえますか?」と指摘したり、されたり。でも、大規模なプロジェクトで手動で全部修正するのは現実的ではありません。

IDE には、ファイル内のエイリアスを一括で変更する機能がありますが、プロジェクト全体を通して整合性を保つ方法がありませんでした。(私調べ)

そこで作ったのが今回の goalias です。

goalias とは

goalias は、Go プロジェクト全体のインポートエイリアスを統一するための CLI ツールです。主な特徴は以下の通り:

  • 🔍 既存パッケージ Alias の確認: どのファイルでどんなエイリアスが使われているか一覧表示してくれます
  • 🔧 Go のパッケージ単位での一括変更: 指定した Go パッケージのエイリアスを一括変更できます
  • 🤖 LSP(gopls)活用: 単純な文字列置換ではなく、Go の文法を理解した上での変更を行います

使い方

実際にどのように使うのか、簡単な例をおみせしましょう。
インストールは通常の Go ツールと同じです。

go install github.com/jackchuka/goalias/cmd/goalias@latest

今回は仮にexample.com/myproject/utilsというパッケージを使って説明します。プロジェクトでどのようにインポートされているか list コマンドで確認してみましょう。

$ goalias list -p "example.com/myproject/utils" ./...
LOCATION                              ALIAS
--------                              -----
<>/example_project/handler/bar.go:6  utils
<>/example_project/handler/foo.go:4  myutils

ここでは、handler/bar.goではutilshandler/foo.goではmyutilsというエイリアスが使われていることがわかります。

これらのエイリアスを、例えばmyutilsに統一したい場合、以下のようにコマンドを実行します。

$ goalias set -p "example.com/myproject/utils" -a myutils ./...

Processing 1 files...
Processing file 1/1: <>/example_project/handler/bar.go

これで、example.com/myproject/utilsのエイリアスがすべてmyutilsに統一されました。再度 list コマンドで確認してみましょう。

$ goalias list -p "example.com/myproject/utils" ./...
LOCATION                              ALIAS
--------                              -----
<>/example_project/handler/bar.go:6  myutils
<>/example_project/handler/foo.go:4  myutils

なぜ goalias を作ったか

既存の方法の問題点

  1. IDE の置換機能: IDE の置換機能は便利ですが、プロジェクト全体の整合性を保つのは難しい。特に、複数人で開発している場合、誰かが手動で変更したエイリアスが他の人のコードと食い違うことがある。

  2. sed や awk などのテキスト処理: 正規表現を使って置換する方法もありますが、Go の文法を理解していないため、誤った置換が発生する可能性がある。特に、コメントや文字列リテラル内のインポート文を誤って変更してしまうリスクがある。

  3. 手動修正: 手動で修正するのは時間がかかり、ミスも起こりやすい。特に大規模なプロジェクトでは、数百、数千のファイルを手動で確認するのは現実的ではない。

これらの問題を解決するために、既存のツールなど調べましたが、自分のニーズに合うものが見つからなかったため、goalias を作成しました。

goalias のアプローチ

作るにあたっても、Go の文法を正確に理解した上での変更が必要でした。そこでたどり着いたのが、Go の公式 Language Server である gopls を活用する方法です。

gopls をバックグラウンドで起動し、LSP(Language Server Protocol)を通じて Go のコードを解析・変更することで、最終的に以下のようなメリットを得ることができました。

  • Go の文法を正確に理解した上での変更しているため、誤った置換が発生しない
  • インポート文だけでなく、コード内の使用箇所も自動で更新
  • gopls を1プロセス起動し、複数のファイルを処理することで、パフォーマンスを向上

まとめ

goalias は「インポートエイリアスがバラバラ」という地味だけど重要な問題を解決するツールです。LSP(gopls)を活用することで、安全で確実なリファクタリングを実現しました。

コードの一貫性は、読みやすさとメンテナンス性に直結すると思います。小さなことかもしれませんが、こういった積み重ねが開発体験を向上させると信じています。

もし興味を持っていただけたら、ぜひGitHubでスター⭐をお願いします!Issue や PR も大歓迎です。

参考リンク

Discussion