ys memos
Blog

Goのgenerateツールを実装したときの後処理メモ


golang

2025/06/03


Goではgeneratorを用いることで、利用時に見通しの良いメタプログラミングを実現できる。

そこで、ツールを作った時に、生成後のコードを整形する後処理が必要になるので、それをメモにしておく。


template構文でインデントや改行を気にすると、テンプレートを必要以上に複雑にしてしまうことがある。 また、importの解決をASTで行うのはかなり大変な実装が必要(そう)である。

そこで、Goの標準で使われている実装を利用させてもらうことで、

  • コードのフォーマット
  • importの整理

をコード内で行う。

これにより、視認性と一貫性があるコードを生成できるようになることが期待される。


Goのコードをフォーマットするには、go/formatパッケージを利用する。

スニペットは以下。

	formattedCode, err := format.Source(code)
	if err != nil {
		log.Fatal(err)
	}

importの整理には、golang.org/x/tools/importsパッケージを利用する。

スニペットは以下。

	output, err := imports.Process(filePath, code, nil)
	if err != nil {
		log.Fatal(err)
	}

このように、

package postgenerate

import (
	"go/format"
	"log"

	"golang.org/x/tools/imports"
)

type PostGenerateArgs struct {
	OutputFilePath string
	Buf            []byte
}

func PostGenerate(args PostGenerateArgs) ([]byte, error) {
	formattedCode, err := format.Source(args.Buf)
	if err != nil {
		log.Fatal(err)
	}

	output, err := imports.Process(args.OutputFilePath, formattedCode, nil)
	if err != nil {
		log.Fatal(err)
	}

	return output, nil
}

Goは公式がツールで提供しているものにも気軽にアクセスできるので、かなり便利だなと思いました。


関連タグを探す