-
Notifications
You must be signed in to change notification settings - Fork 5
/
render-frontmatter-md.go
123 lines (111 loc) · 2.71 KB
/
render-frontmatter-md.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
package commands
import (
_ "embed"
"fmt"
"os"
"text/template"
"github.com/SierraSoftworks/roadmap"
"github.com/urfave/cli/v2"
yaml "gopkg.in/yaml.v3"
)
//go:embed templates/roadmap.basic.frontmatter.md
var frontmatterMdRoadmapBasicTemplate string
//go:embed templates/roadmap.advanced.frontmatter.md
var frontmatterMdRoadmapAdvancedTemplate string
var frontmatterMdRenderCommand = cli.Command{
Name: "frontmatter-markdown",
Aliases: []string{"fmd"},
Usage: "Generate a Markdown file which can be rendered to visualize your roadmap specification, including a frontmatter preamble.",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "simple",
Usage: "Emits simplified Markdown for maximum compatibility.",
},
&cli.StringFlag{
Name: "frontmatter",
Aliases: []string{"m"},
Usage: "Additional frontmatter fields to include in the frontmatter, should be provided in YAML format.",
Value: "{}",
},
&cli.StringFlag{
Name: "input",
Aliases: []string{"in"},
Usage: "The input roadmap.yml `FILE`.",
Value: "roadmap.yml",
TakesFile: true,
Required: true,
},
&cli.StringFlag{
Name: "output",
Aliases: []string{"out"},
Usage: "The output `FILE` (defaults to stdout).",
TakesFile: true,
},
},
Action: func(c *cli.Context) error {
f, err := os.ReadFile(c.String("input"))
if err != nil {
return err
}
r, err := roadmap.Parse(f)
if err != nil {
return err
}
tmpl := frontmatterMdRoadmapAdvancedTemplate
if c.Bool("simple") {
tmpl = frontmatterMdRoadmapBasicTemplate
}
dot, err := renderTextTemplate(r, tmpl, template.FuncMap{
"stateColor": func(state string) string {
switch state {
case "TODO":
return "#aaa"
case "DOING":
return "#63B2EB"
case "DONE":
return "#3EAF7C"
case "SKIP":
return "#F65BD2"
default:
return "#aaa"
}
},
"requirementColor": func(requirement string) string {
switch requirement {
case "MUST":
return "#E06446"
case "SHOULD":
return "#E0AF2F"
case "MAY":
return "#3ABDE0"
default:
return "#888"
}
},
"metadata": func() map[string]interface{} {
m := map[string]interface{}{}
if err := yaml.Unmarshal([]byte(c.String("frontmatter")), &m); err != nil {
return map[string]interface{}{
"__parse_error": err.Error(),
}
}
if m["title"] == nil {
m["title"] = r.Title
}
if m["description"] == nil {
m["description"] = r.Description
}
return m
},
})
if err != nil {
return err
}
if c.String("output") != "" {
return os.WriteFile(c.String("output"), []byte(dot), os.ModePerm)
} else {
_, err := fmt.Println(dot)
return err
}
},
}