-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate.go
122 lines (100 loc) · 3.27 KB
/
create.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package main
import (
"fmt"
"os"
"strings"
"text/template"
log "github.com/sirupsen/logrus"
)
const (
keyValueDelimiter = "="
openBracket = "["
closeBracket = "]"
newRecipeTemplate = "---\nname: {{.Name}}{{range .Fields}}\n{{.Key}}: {{.Value}}{{end}}\nsource: [\"\"]\n---\n# {{.Name}}\n\n## INGREDIENTS\n\n## INSTRUCTIONS\n"
)
type RecipeField struct {
Key string
Value string
}
type RecipeSkeleton struct {
Name string
Fields []RecipeField
}
func validateFieldValue(value string) string {
// First, validate that we were given something in a format that we expect.
valueContent := strings.Trim(value, strings.Join([]string{openBracket, closeBracket}, ""))
valueArray := strings.Split(valueContent, ",")
var trimmedValueArray []string
for _, s := range valueArray {
trimmedValueArray = append(trimmedValueArray, strings.TrimSpace(s))
}
// Then, put it all back together in a standard format.
normalizedFieldValue := fmt.Sprintf("[%s]", strings.Join(trimmedValueArray, ", "))
return normalizedFieldValue
}
func validateFields(fieldFlags []string) (map[string]interface{}, error) {
fields := make(map[string]interface{})
for _, rawField := range fieldFlags {
splitValueArray := strings.Split(rawField, keyValueDelimiter)
// If there's a third item in the array, we don't care about it. :)
key := splitValueArray[0]
value := splitValueArray[1]
fields[key] = validateFieldValue(value)
}
return fields, nil
}
func validateNewRecipe(filename string) string {
if filename == "" {
errMsg := "You must provide at least a filename in order to create a new recipe."
log.Fatal(errMsg)
}
if strings.HasSuffix(filename, suffix) {
filename = strings.TrimSuffix(filename, suffix)
}
filepath := GetFullFilepath(filename)
_, err := os.Stat(filepath)
// Not the same as os.IsExist! This is because os.Stat doesn't throw an
// error if the file exists, so os.IsExist would receive a nil value for err.
// So, an os.IsExist(err) block would never execute for a file that exists.
if !os.IsNotExist(err) {
errMsg := fmt.Sprintf("There already exists a file at the path: %s\n", filepath)
log.Fatal(errMsg)
}
return filepath
}
func writeNewRecipeFile(filepath string, name string, fields map[string]interface{}) {
var recipeFields []RecipeField
for k, v := range fields {
recipeFields = append(recipeFields, RecipeField{Key: k, Value: v.(string)})
}
recipeVariables := RecipeSkeleton{
Name: name,
Fields: recipeFields,
}
f, err := os.Create(filepath)
if err != nil {
fmt.Printf("An error occurred creating a file at: %s\n", filepath)
}
defer f.Close()
tpl, err := template.New("newrecipe").Parse(newRecipeTemplate)
if err != nil {
log.Fatal("Error parsing recipe template.")
}
err = tpl.Execute(f, recipeVariables)
if err != nil {
log.Fatal("Error executing template.")
}
}
func CreateNewRecipe(filename string, name string, fieldFlags []string) {
filepath := validateNewRecipe(filename)
var validatedFields map[string]interface{}
var validateFieldsErr error
if len(fieldFlags) > 0 {
validatedFields, validateFieldsErr = validateFields(fieldFlags)
if validateFieldsErr != nil {
log.Fatal("An error occurred while validating the new recipe fields.")
}
}
writeNewRecipeFile(filepath, name, validatedFields)
EditRecipe(filepath)
}