-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
152 lines (134 loc) · 4.76 KB
/
main.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"text/template"
recipe "github.com/compybara/paprika2markdown/recipe"
yaml "gopkg.in/yaml.v2"
)
// Use constants for default values
const defaultTemplate string = "./templates/template.md"
const defaultRecipes string = "./recipes"
const defaultOutput string = "./recipes.wiki"
const pathSeparator = string(os.PathSeparator)
// Instantiate variables to store command-line flag values.
var templateFile string
var recipesFolder string
var outputFolder string
func init() {
// Setup the command-line flags.
flag.StringVar(&templateFile, "t", defaultTemplate,
"The template to use for generating output.")
flag.StringVar(&recipesFolder, "r", defaultRecipes,
"The folder containing the recipe YAML files.")
flag.StringVar(&outputFolder, "o", defaultOutput, "Folder to store the"+
" generated recipes. Existing files will be overwritten.")
}
func promptYesNo(question string) (answer bool) {
// Ask the user for input for a Yes or No question. Returns true if the user
// responds with "y, Y, yes, Yes", false for anything else.
fmt.Printf("%v (y/N): ", question)
var response string
fmt.Scanln(&response)
if strings.ToLower(string(response[0])) == "y" {
return true
}
return false
}
func getYAMLFiles(path string, files []os.FileInfo) (yamlFiles []string) {
// Take the list of files from ioutil.ReadDir and filter out only the
// non-empty YAML files. Return a slice of strings with the full path.
for _, file := range files {
// Split the filename at the . and check if the last element is a correct
// file extension (yml or yaml).
split := strings.Split(file.Name(), ".")
extension := strings.ToLower(split[len(split)-1])
if extension == "yml" || extension == "yaml" {
if file.Size() > 0 {
fullPath := fmt.Sprintf("%s%s%s", path, pathSeparator, file.Name())
yamlFiles = append(yamlFiles, fullPath)
}
}
}
return yamlFiles
}
func parseRecipes(yamlFiles []string) (recipes []recipe.Recipe) {
// Read in each recipe file and parse to a recipe.Recipe struct.
// Return a slice containing the Recipe objects.
for _, file := range yamlFiles {
data, err := ioutil.ReadFile(file)
if err != nil {
fmt.Printf("Cannot read recipe file %v, skipping.\n%v\n", file, err)
continue
}
var r recipe.Recipe
if err := yaml.Unmarshal(data, &r); err != nil {
fmt.Printf("Error parsing YAML for %v\n%v\n", file, err)
continue
}
r.ParseIngredientsList()
recipes = append(recipes, r)
}
return recipes
}
func main() {
flag.Parse()
// Get the absolute path for each option and make sure they exist.
templateFileFullPath, _ := filepath.Abs(templateFile)
recipeTemplate := template.Must(template.ParseFiles(templateFileFullPath))
fmt.Printf("Using template file %v\n", templateFile)
recipesFolder, _ = filepath.Abs(recipesFolder)
if _, err := os.Stat(recipesFolder); os.IsNotExist(err) {
fmt.Printf("Recipes folder %v not found.\n", recipesFolder)
os.Exit(1)
}
// If output folder doesn't exist ask the user if it can be created.
outputFolderFullPath, _ := filepath.Abs(outputFolder)
if _, err := os.Stat(outputFolderFullPath); os.IsNotExist(err) {
q := "Output folder does not exist. Should I create it?"
if promptYesNo(q) {
fmt.Printf("Creating folder %v\n", outputFolder)
mkdirErr := os.MkdirAll(outputFolderFullPath, 0755)
if mkdirErr != nil {
fmt.Printf("Error creating output folder: %v\n", mkdirErr)
os.Exit(1)
}
fmt.Printf("Output folder created.\n")
} else {
fmt.Printf("Output folder not created. Quitting.")
os.Exit(0)
}
}
// Get all of the YAML files in the recipes folder.
files, err := ioutil.ReadDir(recipesFolder)
if err != nil {
fmt.Printf("Problem reading recipes folder: %v\n", err)
}
fmt.Printf("Reading recipes from %v\n", recipesFolder)
yamlFiles := getYAMLFiles(recipesFolder, files)
recipes := parseRecipes(yamlFiles)
// Generate a file from the template for each recipe.
for _, recipe := range recipes {
// Use recipe name .md for the output filename.
outputFileName := fmt.Sprintf("%s.md", recipe.Name)
outputFileFullPath := fmt.Sprintf("%s%s%s", outputFolder, pathSeparator, outputFileName)
// Create the output file. Existing files will be truncated. Skip this recipe
// if for some reason the output file cannot be opened. Maybe consider exiting
// with an error here instead?
outputFile, err := os.Create(outputFileFullPath)
if err != nil {
fmt.Printf("Error opening output file %v for writing: %v\n", outputFileName, err)
continue
}
fmt.Printf("Saving recipe for %v to %v\n", recipe.Name, outputFileName)
templateErr := recipeTemplate.Execute(outputFile, recipe)
if templateErr != nil {
fmt.Printf("Error executing template for %v\n%v\n", outputFileName, templateErr)
continue
}
}
}