【Golang】Templateファイルを使って大容量JSONファイル生成するツール

# お題
[前回](https://qiita.com/sky0621/items/5f4f38b261e2fd050ece)の記事で大きめサイズなJSONを用意するのに適当に書いたコードを少し直したもの。
ツールと言っても、汎用性のあるものではなく、指定した件数分の構造を持つJSONを生成するだけ。

以下のようなテンプレートファイルを「`json.tmpl`」という名前で用意して、ツールと同じパスに配置。

```
{
  "items": [
{{range .}}    {
      "id": "id-{{.No}}",
      "name": "あいてむ{{.No}}",
      "price": {{.No}}
    }{{.Comma}}
{{end}}  ]
}
```

で、コマンドラインで `./tools` と叩けば以下のJSONが出来上がる。ただそれだけ。

```json:[data.json]
{
  "items": [
    {
      "id": "id-1",
      "name": "あいてむ1",
      "price": 1
    },
    {
      "id": "id-2",
      "name": "あいてむ2",
      "price": 2
    },
    {
      "id": "id-3",
      "name": "あいてむ3",
      "price": 3
    },
    {
      "id": "id-4",
      "name": "あいてむ4",
      "price": 4
    },
    {
      "id": "id-5",
      "name": "あいてむ5",
      "price": 5
    },
    {
      "id": "id-6",
      "name": "あいてむ6",
      "price": 6
    },
    {
      "id": "id-7",
      "name": "あいてむ7",
      "price": 7
    },
    {
      "id": "id-8",
      "name": "あいてむ8",
      "price": 8
    },
    {
      "id": "id-9",
      "name": "あいてむ9",
      "price": 9
    },
    {
      "id": "id-10",
      "name": "あいてむ10",
      "price": 10
    }
  ]
}
```

デフォルトは１０件分にしていて、件数変えたければ、 `./tools -c 50` とかすれば５０件分のJSONに変わる。
テンプレートファイル内で指定できる変数は `{{ .No }}` と `{{ .Comma }}` だけなので実質、件数に応じたデータ間のナンバリングくらいしか反映できない。

Windows/Mac/Linuxそれぞれのバイナリは下記。
https://github.com/sky0621/tools/releases/tag/v0.1.0

ソース全量は下記。
https://github.com/sky0621/tools/tree/v0.1.0

# 開発環境
## # OS - Linux(Ubuntu)
```
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
```

## # 言語 - Go
```
$ go version
go version go1.13.3 linux/amd64
```

## # パッケージマネージャ - Go Modules

## # IDE - Goland
```
GoLand 2019.2.5
Build #GO-192.7142.48, built on November 8, 2019
```

# ソース（解説なし）

まあ、要らないとは思うけど、一応。

```go:[main.go]
package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"html/template"
	"log"
	"os"
	"path/filepath"
)

func abs(path string) string {
	p, err := filepath.Abs(filepath.Clean(path))
	if err != nil {
		log.Fatal(err)
	}
	return p
}

func main() {
	var count *int = flag.Int("c", 10, "データ件数")
	var templatePath *string = flag.String("t", "./json.tmpl", "テンプレートファイルパス")
	var outputPath *string = flag.String("o", "./data.json", "生成JSONパス")
	flag.Parse()

	fmt.Println("Start")
	fmt.Printf("[Args][count:%d][templatePath:%s][outputPath:%s]\n", *count, *templatePath, *outputPath)

	var items []*Item
	for i := 1; i < *count+1; i++ {
		comma := ""
		if i < *count {
			comma = ","
		}
		items = append(items, &Item{No: i, Comma: comma})
	}
	fmt.Printf("item length: %d\n", len(items))

	tpath := abs(*templatePath)
	fmt.Printf("templatePath: %s\n", tpath)

	tmpl := template.Must(template.ParseFiles(tpath))
	buf := &bytes.Buffer{}
	err := tmpl.Execute(buf, items)
	if err != nil {
		log.Fatal(err)
	}

	opath := abs(*outputPath)
	_, err = os.Stat(opath)
	if !os.IsNotExist(err) {
		if err := os.Remove(opath); err != nil {
			log.Fatal(err)
		}
	}
	fmt.Printf("outputPath: %s\n", opath)

	file, err := os.OpenFile(opath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		log.Fatal(err)
	}
	w := bufio.NewWriter(file)
	w.WriteString(buf.String())
	w.Flush()

	fmt.Println("End")
}

type Item struct {
	No    int
	Comma string
}
```

# まとめ
まとめてないけど、まとめ。
自分の持ってるのがLinux端末しかないので、リリースしたバイナリで動作確認済みなのは「`tools_0.1.0_Linux_x86_64.tar.gz`」だけ。
今回、 [GoReleaser](https://github.com/goreleaser/goreleaser)使ってツールのリリースしたけど、めちゃくちゃ便利だった。。。