Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more unit tests #26

Merged
merged 1 commit into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
items/
README.tpl

dist/
bin/
.idea/
Expand Down
8 changes: 8 additions & 0 deletions function/data/README-group.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{{- range $key, $val := .}}
Year: {{$key}}
| Zh | En |
|---|---|
{{- range $item := $val}}
| {{$item.zh}} | {{$item.en}} |
{{- end}}
{{end}}
5 changes: 5 additions & 0 deletions function/data/README.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
|中文名称|英文名称|JD|
|---|---|---|
{{- range $val := .}}
|{{$val.zh}}|{{$val.en}}|{{$val.jd}}|
{{- end}}
4 changes: 4 additions & 0 deletions function/data/item-2022.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
zh: zh
en: en
jd: jd
year: 2022
4 changes: 4 additions & 0 deletions function/data/item-ignore.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
zh: zh
en: en
jd: jd
ignore: true
4 changes: 4 additions & 0 deletions function/data/item.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
zh: zh
en: en
jd: jd
year: 2021
114 changes: 75 additions & 39 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"html/template"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
Expand All @@ -18,6 +19,8 @@ import (
"strings"
)

var logger *log.Logger

type option struct {
pattern string
templateFile string
Expand All @@ -29,33 +32,23 @@ type option struct {
printVariables bool
}

func (o *option) runE(cmd *cobra.Command, args []string) (err error) {
if o.printFunctions {
printFunctions(cmd.OutOrStdout())
return
}

if o.printVariables {
printVariables(cmd.OutOrStdout())
return
}

var items []map[string]interface{}
groupData := make(map[string][]map[string]interface{})
func loadMetadata(pattern, groupBy string) (items []map[string]interface{},
groupData map[string][]map[string]interface{}, err error) {
groupData = make(map[string][]map[string]interface{})

// find YAML files
var files []string
var data []byte
if files, err = filepath.Glob(o.pattern); err == nil {
if files, err = filepath.Glob(pattern); err == nil {
for _, metaFile := range files {
if data, err = ioutil.ReadFile(metaFile); err != nil {
cmd.PrintErrf("failed to read file [%s], error: %v\n", metaFile, err)
logger.Printf("failed to read file [%s], error: %v\n", metaFile, err)
continue
}

metaMap := make(map[string]interface{})
if err = yaml.Unmarshal(data, metaMap); err != nil {
cmd.PrintErrf("failed to parse file [%s] as a YAML, error: %v\n", metaFile, err)
logger.Printf("failed to parse file [%s] as a YAML, error: %v\n", metaFile, err)
continue
}

Expand All @@ -73,7 +66,7 @@ func (o *option) runE(cmd *cobra.Command, args []string) (err error) {
metaMap["parentname"] = parentname
metaMap["fullpath"] = metaFile

if val, ok := metaMap[o.groupBy]; ok && val != "" {
if val, ok := metaMap[groupBy]; ok && val != "" {
var strVal string
switch val.(type) {
case string:
Expand All @@ -94,39 +87,74 @@ func (o *option) runE(cmd *cobra.Command, args []string) (err error) {
items = append(items, metaMap)
}
}
return
}

if o.sortBy != "" {
descending := true
if strings.HasPrefix(o.sortBy, "!") {
o.sortBy = strings.TrimPrefix(o.sortBy, "!")
descending = false
}
sortBy(items, o.sortBy, descending)
func sortMetadata(items []map[string]interface{}, sortByField string) {
descending := true
if strings.HasPrefix(sortByField, "!") {
sortByField = strings.TrimPrefix(sortByField, "!")
descending = false
}
sortBy(items, sortByField, descending)
}

func loadTemplate(templateFile string, includeHeader bool) (readmeTpl string, err error) {
// load readme template
var readmeTpl string
if data, err = ioutil.ReadFile(o.templateFile); err != nil {
var data []byte
if data, err = ioutil.ReadFile(templateFile); err != nil {
fmt.Printf("failed to load README template, error: %v\n", err)
readmeTpl = `
|中文名称|英文名称|JD|
err = nil
readmeTpl = `|中文名称|英文名称|JD|
|---|---|---|
{{- range $val := .}}
|{{$val.zh}}|{{$val.en}}|{{$val.jd}}|
{{end}}
`
{{- end}}`
}
if o.includeHeader {
if includeHeader {
readmeTpl = fmt.Sprintf("> This file was generated by [%s](%s) via [yaml-readme](https://github.com/LinuxSuRen/yaml-readme), please don't edit it directly!\n\n",
filepath.Base(o.templateFile), filepath.Base(o.templateFile))
filepath.Base(templateFile), filepath.Base(templateFile))
}
readmeTpl = readmeTpl + string(data)
return
}

func (o *option) runE(cmd *cobra.Command, args []string) (err error) {
logger = log.New(cmd.OutOrStdout(), "", log.LstdFlags)
if o.printFunctions {
printFunctions(cmd.OutOrStdout())
return
}

if o.printVariables {
printVariables(cmd.OutOrStdout())
return
}

// load metadata from YAML files
var items []map[string]interface{}
var groupData map[string][]map[string]interface{}
if items, groupData, err = loadMetadata(o.pattern, o.groupBy); err != nil {
err = fmt.Errorf("failed to load metadat from %q", o.pattern)
return
}

if o.sortBy != "" {
sortMetadata(items, o.sortBy)
}

// load readme template
var readmeTpl string
if readmeTpl, err = loadTemplate(o.templateFile, o.includeHeader); err != nil {
err = fmt.Errorf("failed to load template file from %q", o.templateFile)
return
}

// render it with grouped data
if o.groupBy != "" {
err = renderTemplate(readmeTpl, groupData, os.Stdout)
err = renderTemplate(readmeTpl, groupData, cmd.OutOrStdout())
} else {
err = renderTemplate(readmeTpl, items, os.Stdout)
err = renderTemplate(readmeTpl, items, cmd.OutOrStdout())
}
return
}
Expand Down Expand Up @@ -157,9 +185,14 @@ fullpath`))

func printFunctions(stdout io.Writer) {
funcMap := getFuncMap("")
var funcs []string
for k := range funcMap {
_, _ = stdout.Write([]byte(fmt.Sprintf("%s\n", k)))
funcs = append(funcs, k)
}
sort.SliceStable(funcs, func(i, j int) bool {
return strings.Compare(funcs[i], funcs[j]) < 0
})
_, _ = stdout.Write([]byte(strings.Join(funcs, "\n")))
}

func getFuncMap(readmeTpl string) template.FuncMap {
Expand Down Expand Up @@ -260,13 +293,14 @@ func dataRender(data interface{}) string {
return ""
}

func main() {
func newRootCommand() (cmd *cobra.Command) {
opt := &option{}
cmd := cobra.Command{
cmd = &cobra.Command{
Use: "yaml-readme",
Short: "A helper to generate a README file from Golang-based template",
RunE: opt.runE,
}
cmd.SetOut(os.Stdout)
flags := cmd.Flags()
flags.StringVarP(&opt.pattern, "pattern", "p", "items/*.yaml",
"The glob pattern with Golang spec to find files")
Expand All @@ -282,9 +316,11 @@ func main() {
"Print all the functions and exit")
flags.BoolVarP(&opt.printVariables, "print-variables", "", false,
"Print all the variables and exit")
return
}

err := cmd.Execute()
if err != nil {
func main() {
if err := newRootCommand().Execute(); err != nil {
os.Exit(1)
}
}
Loading