少し前にGo言語に興味を持った時期がありまして、業務用に簡単なツールを作りました。
せっかくなので忘れないように書き残しておきます。
現在の業務ではJavaを使っているのですが、
valueObjectという似たようなクラスを大量に作成することがありました。
��valueObjectとは下記のような値を持つためだけのクラスです。)
変わるのはクラス名とコメントとパッケージ名だけなので、
ファイルをコピペする以外で簡単に作成することはできないか考えた結果、
Goでコマンドラインツールを作ることにしました。
・コピー元のvalueObject
package jp.co.domain.sample;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
/**
* sample
*/
@ToString(includeFieldNames = false)
@EqualsAndHashCode
@AllArgsConstructor
public class sample {
@Getter
private final String value;
}
作成したツール(createCopyFile)
コピー元ファイル名、作成先のディレクトリ、作成したいファイル名を指定して実行すると、
「sample」の文字列を指定した名前に変換したファイルを作成します。
・createCopyFile.go
package main
import (
"os"
"bufio"
"strings"
)
func main() {
copyName := os.Args[1]
pkgName := os.Args[2]
createFile := os.Args[3]
// 新規ファイルを作成
newFile, err := os.Create(pkgName + "/" + createFile)
if err != nil {
panic(err)
}
defer newFile.Close()
// コピー元ファイルの中身を読込
cpFile, err := os.Open(copyName)
if err != nil {
panic(err)
}
defer cpFile.Close()
// コピー元ファイルを一行ずつ読込
lines := make([]byte, 0)
// 拡張子を除いたクラス名を取得
className := strings.Split(createFile, ".")[0]
scanner := bufio.NewScanner(cpFile)
for scanner.Scan() {
line := scanner.Text()
// パッケージ名を置換
if strings.Contains(line, "package") && strings.Contains(line, "sample") {
pkg := strings.Split(pkgName, "/")
line = strings.Replace(line, "sample", pkg[len(pkg)-1], 1) + "\n"
// クラス名を置換
} else if strings.Contains(line, "sample") {
line = strings.Replace(line, "sample", className, 1) + "\n"
} else {
line = line + "\n"
}
lines = append(lines, []byte(line)...)
}
newFile.Write(lines)
}
実行方法
コピー元となるsampleファイルを、このツールと同じディレクトリに配置します。
コピー元ファイルを開き、置換したい文字を
sample
に修正します。下記の引数を渡して createCopyFile.go を実行します。
go run createCopyFile.go {コピー元ファイル} {作成先のディレクトリパス} {作成するファイル名}
コピー元ファイル :拡張子も入れて指定してください。
(java以外のファイルもコピーできます)作成するファイル名 :拡張子も入れて指定してください。
サンプル
試しに下記のコマンドを実行します。
go run createClassFile.go sample.java /Users/tomi/git/go-study/src/github.com/tool/member NewUser.java
指定したディレクトリに「NewUser.java」が作成されます。
package jp.co.domain.member;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
/**
* NewUser
*/
@ToString(includeFieldNames = false)
@EqualsAndHashCode
@AllArgsConstructor
public class NewUser {
@Getter
private final String value;
}
Goをつかってみた感想
作成するクラスに対して1こずつ実行する点では手間がかかりますが、
コマンドラインで実行することで、1つ前に叩いたコマンドのクラス名を変更するだけで複製することができたので、
コピペで作成するよりも早く作業を進めることができました。
Go言語はコードの量が少なくてすみ、理解しやすいコードになることが良いところかと思っています。
エラーハンドリングにpanic
という関数を使っていますが、
これは実質的にプログラムを停止させるGo言語におけるランタイムエラーです。
Go言語についての理解はまだ浅いので簡単なものしか作れませんが、
機会があったらまた使ってみようかと思います。