<commit_before>package parser

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"regexp"

	"github.com/dogtools/dog/types"
	"github.com/ghodss/yaml"
)

var ErrMalformedStringArray = errors.New("Malformed strings array")

type task struct {
	Name        string      `json:"task"`
	Description string      `json:"description,omitempty"`
	Time        bool        `json:"time,omitempty"`
	Run         string      `json:"run"`
	Executor    string      `json:"exec,omitempty"`
	Pre         interface{} `json:"pre,omitempty"`
	Post        interface{} `json:"post,omitempty"`
}

func parseStringSlice(str interface{}) ([]string, error) {
	switch h := str.(type) {
	case string:
		return []string{h}, nil
	case []interface{}:
		s := make([]string, len(h))
		for i, hook := range h {
			sHook, ok := hook.(string)
			if !ok {
				return nil, ErrMalformedStringArray
			}
			s[i] = sHook
		}
		return s, nil
	case nil:
		return []string{}, nil
	default:
		return nil, ErrMalformedStringArray
	}
}

// ParseDogfile takes a byte slice and process it to return a TaskMap.
func ParseDogfile(d []byte) (tm types.TaskMap, err error) {
	var tasksToParse []*task

	err = yaml.Unmarshal(d, &tasksToParse)
	if err != nil {
		return
	}

	tm = make(types.TaskMap, len(tasksToParse))
	for _, t := range tasksToParse {
		if _, ok := tm[t.Name]; ok {
			return tm, fmt.Errorf("Duplicated task name %s", t.Name)
		} else {<commit_msg>Invalidate 🐕  when using spaces in task names (#74)<commit_after>package parser

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"regexp"

	"github.com/dogtools/dog/types"
	"github.com/ghodss/yaml"
)

var ErrMalformedStringArray = errors.New("Malformed strings array")

type task struct {
	Name        string      `json:"task"`
	Description string      `json:"description,omitempty"`
	Time        bool        `json:"time,omitempty"`
	Run         string      `json:"run"`
	Executor    string      `json:"exec,omitempty"`
	Pre         interface{} `json:"pre,omitempty"`
	Post        interface{} `json:"post,omitempty"`
}

func parseStringSlice(str interface{}) ([]string, error) {
	switch h := str.(type) {
	case string:
		return []string{h}, nil
	case []interface{}:
		s := make([]string, len(h))
		for i, hook := range h {
			sHook, ok := hook.(string)
			if !ok {
				return nil, ErrMalformedStringArray
			}
			s[i] = sHook
		}
		return s, nil
	case nil:
		return []string{}, nil
	default:
		return nil, ErrMalformedStringArray
	}
}

// ParseDogfile takes a byte slice and process it to return a TaskMap.
func ParseDogfile(d []byte) (tm types.TaskMap, err error) {
	const validTaskName = "^[a-z-]+$"
	var tasksToParse []*task

	err = yaml.Unmarshal(d, &tasksToParse)
	if err != nil {
		return
	}

	tm = make(types.TaskMap, len(tasksToParse))
	for _, t := range tasksToParse {
		if _, ok := tm[t.Name]; ok {
			return tm, fmt.Errorf("Duplicated task name %s", t.Name)
		} else if matches, _ := regexp.MatchString(validTaskName, t.Name); !matches {
			return tm, fmt.Errorf("Invalid name for task %s", t.Name)
		} else {
{'fraction_non_alphanumeric': 0.14328259430840504, 'fraction_numerical': 0.0006618133686300463, 'mean_word_length': 3.3684971098265897, 'pattern_counts': {'":': 0, '<': 3, '<?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': '1151886', 'n_tokens_mistral': 1101, 'n_tokens_neox': 1036, 'n_words': 289}