<commit_before>package main

import (
	"encoding/csv"
	"log"
	"os"

	"github.com/codegangsta/cli"
	"github.com/joliv/spark"
)

const (
	defaultFileName = "health.log"

	delimiter = '\t'
)

func getFileName(fileName string) string {
	if fileName == "" {
		return defaultFileName
	}
	return fileName
}

func main() {
	var fileName string

	app := cli.NewApp()
	app.Name = "merki"
	app.Usage = "Command line personal health tracker"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "file, f",
			Value:       defaultFileName,
			Usage:       "Log file path",
			EnvVar:      "MERKI_FILE",
			Destination: &fileName,
		},
	}
	app.Commands = []cli.Command{
		{
			Name:    "add",
			Aliases: []string{"a"},
			Usage:   "Add measurement value to the file",
			Action: func(c *cli.Context) {
				record, err := NewRecordFromArgs(c.Args())
				if err != nil {
					panic(err)
				}
				f, err := os.OpenFile(getFileName(fileName), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
				if err != nil {
					panic(err)
				}

				defer f.Close()

				w := csv.NewWriter(f)
				w.Comma = delimiter
				if err := w.Write(record.getStrings()); err != nil {
					panic(err)
				}
				w.Flush()
				if err := w.Error(); err != nil {
					log.Fatal(err)
				}
			},
		},
		{
			Name:    "sparkline",
			Aliases: []string{"spark"},
			Usage:   "Draw sparkline graph for a measure",
			Action: func(c *cli.Context) {
				measure := c.Args().First()
				var values []float64
				parser := NewParser(string(delimiter))
				go parser.ParseFile(getFileName(fileName))
				err := func() error {
					for {
						select {
						case record := <-parser.Record:
							if record.Measurement == measure {
								values = append(values, record.Value)
							}
						case err := <-parser.Error:
							return err
						case <-parser.Done:
							return nil
						}
					}
				}()
				if err != nil {
					panic(err)
				}
				sparkline := spark.Line(values)
				println(sparkline)
			},
		},
	}

	app.Run(os.Args)
}<commit_msg>Added list of measurements command<commit_after>package main

import (
	"encoding/csv"
	"log"
	"os"

	"github.com/codegangsta/cli"
	"github.com/joliv/spark"
)

const (
	defaultFileName = "health.log"

	delimiter = '\t'
)

func getFileName(fileName string) string {
	if fileName == "" {
		return defaultFileName
	}
	return fileName
}

func main() {
	var fileName string

	app := cli.NewApp()
	app.Name = "merki"
	app.Usage = "Command line personal health tracker"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "file, f",
			Value:       defaultFileName,
			Usage:       "Log file path",
			EnvVar:      "MERKI_FILE",
			Destination: &fileName,
		},
	}
	app.Commands = []cli.Command{
		{
			Name:    "add",
			Aliases: []string{"a"},
			Usage:   "Add measurement value to the file",
			Action: func(c *cli.Context) {
				record, err := NewRecordFromArgs(c.Args())
				if err != nil {
					panic(err)
				}
				f, err := os.OpenFile(getFileName(fileName), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
				if err != nil {
					panic(err)
				}

				defer f.Close()

				w := csv.NewWriter(f)
				w.Comma = delimiter
				if err := w.Write(record.getStrings()); err != nil {
					panic(err)
				}
				w.Flush()
				if err := w.Error(); err != nil {
					log.Fatal(err)
				}
			},
		},
		{
			Name:    "sparkline",
			Aliases: []string{"spark"},
			Usage:   "Draw sparkline graph for a measure",
			Action: func(c *cli.Context) {
				measure := c.Args().First()
				var values []float64
				parser := NewParser(string(delimiter))
				go parser.ParseFile(getFileName(fileName))
				err := func() error {
					for {
						select {
						case record := <-parser.Record:
							if record.Measurement == measure {
								values = append(values, record.Value)
							}
						case err := <-parser.Error:
							return err
						case <-parser.Done:
							return nil
						}
					}
				}()
				if err != nil {
					panic(err)
				}
				sparkline := spark.Line(values)
				println(sparkline)
			},
		},
		{
			Name:    "measurements",
			Aliases: []string{"m"},
			Usage:   "Return list of all used measurements",
			Action: func(c *cli.Context) {
				measures := make(map[string]bool)
				parser := NewParser(string(delimiter))
				go parser.ParseFile(getFileName(fileName))
				err := func() error {
					for {
						select {
						case record := <-parser.Record:
							measures[record.Measurement] = true
						case err := <-parser.Error:
							return err
						case <-parser.Done:
							return nil
						}
					}
				}()
				if err != nil {
					panic(err)
				}
				for name, _ := range measures {
					println(name)
				}
			},
		},
	}

	app.Run(os.Args)
}
{'fraction_non_alphanumeric': 0.1480925846549507, 'fraction_numerical': 0.002571795970852979, 'mean_word_length': 2.338340486409156, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1097102', 'n_tokens_mistral': 2137, 'n_tokens_neox': 1619, 'n_words': 370}