pachanger を使って構造体の移行を簡単にする方法

pachangerは、Go言語のパッケージを移行する際に非常に役立つツールです。特に、テストファイルの書き換えを自動化できる点が大きなメリットです。

前回のブログではパッケージ名をリネームする方法を紹介しました。

このブログでは、pachangerを使って、Goの構造体に対してどのように自動的にコードを生成し、移行するかの具体例を紹介します。

課題感

pachangerの主要な目的は、構造体を含むコードの移行を効率化することです。特に、パッケージが変わる場合やテストコードを変更する必要がある場合に、手動での修正が面倒なことがよくあります。例えば、あるパッケージfooからfoo_testに移行する際、テストファイルに次のようなコードが含まれているとします。

package foo_test
bar = foo.Bar {
  example: 1, // スコープが違うのでexampleにアクセスできない
}

このコードは、スコープが違うため、パッケージが異なるとエラーになります。pachangerはこのような問題を自動的に修正し、テストファイルを適切に書き換えてくれます。

具体的な実装例

1. 変換前の構造体

最初に、プロダクトコードにある構造体を見てみましょう。

package migrate

type MigrateStruct struct {
	foo    string
	bar    int
	foobar *string
}

この構造体をテストコードから使用する場合、テストパッケージ(migrate_test)で次のようにインスタンス化しようとすると、先の例と同じ用に、スコープが異なるためエラーが発生します。

package migrate_test

import (
	"testing"
	"github.com/pyama86/pachanger/internal/pachanger/testdata/migrate"
)

func TestAddConstructorWithParamsStructRefactored(t *testing.T) {
	f := "abc"
	m := migrate.MigrateStruct{
		foo:    "foo",
		bar:    1,
		foobar: &f,
	}
	fmt.Println(m)
}

2. pachanger を使った移行

pachangerを使うと、構造体のインスタンス化を自動で修正できます。

まず下記のようなコマンドを実行します。

$ pachanger struct --file migrate_test.go --pkg migrate

コマンドが発行されるとまず、構造体に対応するパラメータ構造体とコンストラクタを生成し、定義されているファイルに追記します。

package migrate

type MigrateStruct struct {
	foo    string
	bar    int
	foobar *string
}
// ここから下を自動で追記します。
type MigrateStructParamsForTestMigrate struct {
    Foo    string
    Bar    int
    Foobar *string
}

func NewMigrateStructForTestMigrate(params *MigrateStructParamsForTestMigrate) *MigrateStruct {
    return &MigrateStruct{
        Foo:    params.Foo,
        Bar:    params.Bar,
        Foobar: params.Foobar,
    }
}

これにより、テストコードでは、NewMigrateStructForTestMigrateを使って構造体を簡単に生成できるようになります。
pachangerは作成されたコンストラクタを用いて、既存の実装の書き換えもASTを利用して自動で行います。

package migrate_test

import (
	"fmt"
	"testing"
	"github.com/pyama86/pachanger/internal/pachanger/testdata/migrate"
)

func TestAddConstructorWithParamsStructRefactored(t *testing.T) {
	f := "abc"
	m := migrate.NewMigrateStructForTestMigrate(
      &migrate.MigrateStructParamsForTestMigrate{
        Foo: "foo",
        Bar: 1,
        Foobar: &f,
      }
    )

	fmt.Println(m)
}

これで、migrate_testパッケージでMigrateStructを問題なく使用することができ、スコープの違いによるエラーも解消されます。

pachangerを使うメリット

  • 自動化されたコード修正pachangerは、構造体やテストコードの書き換えを自動化し、手動での修正作業を大幅に削減します。
  • エラーの回避:異なるパッケージ間でのスコープ違いによるエラーを解消できます。
  • 効率的な移行:構造体の変更があっても、pachangerを使うことで簡単に移行できるため、コードの整合性が保たれます。

まとめ

pachangerは、Go言語でのパッケージ移行作業を効率化するツールです。特に、構造体をテストコードに組み込む際に生じるスコープの問題を自動で修正してくれるため、開発者の負担を軽減します。pachangerを使うことで、構造体のパラメータ化やテストコードの修正をスムーズに行うことができ、コードの品質を保ちながら効率的な開発が可能になります。