1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-12-08

お題

前回の記事で大きめサイズなJSONを用意するのに適当に書いたコードを少し直したもの。
ツールと言っても、汎用性のあるものではなく、指定した件数分の構造を持つJSONを生成するだけ。

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

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

で、コマンドラインで ./tools と叩けば以下の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
    }
  ]
}

デフォルトは10件分にしていて、件数変えたければ、 ./tools -c 50 とかすれば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

ソース(解説なし)

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

[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使ってツールのリリースしたけど、めちゃくちゃ便利だった。。。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?