package main import ( "bufio" "io/fs" "io/ioutil" "log" "os" "path" "strings" ) type File struct { name string fullPath string category []string description string id string lang string tags []string } type Tree struct { path string dirs []Tree files []File } func BuildTree(dirPath string) Tree { return readPath(dirPath, []string{}) } func readPath(dirPath string, category []string) Tree { tree := Tree{} tree.path = dirPath files, err := ioutil.ReadDir(dirPath) if err != nil { log.Fatal(err) } for _, file := range files { fullPath := path.Join(dirPath, file.Name()) if file.IsDir() { tree.dirs = append(tree.dirs, readPath(fullPath, append(category, file.Name()))) continue } _, err := ioutil.ReadFile(fullPath) if err == nil { tree.files = append(tree.files, readFile(file, fullPath, category)) } } return tree } func readFile(file fs.FileInfo, fullPath string, category []string) File { f := File{ name: file.Name(), fullPath: fullPath, category: category, } osf, err := os.Open(fullPath) if err != nil { log.Fatalf("failed to open %s", fullPath) } scanner := bufio.NewScanner(osf) scanner.Split(bufio.ScanLines) for scanner.Scan() { line := scanner.Text() if line == "---" { break } if strings.HasPrefix(line, "tags:") { line = strings.TrimPrefix(line, "tags:") t := strings.Split(line, ",") tags := []string{} for _, tag := range t { tags = append(tags, strings.Trim(tag, " ")) } f.tags = tags } if strings.HasPrefix(line, "description:") { line = strings.TrimPrefix(line, "description:") f.description = strings.Trim(line, " ") } if strings.HasPrefix(line, "lang:") { line = strings.TrimPrefix(line, "lang:") f.lang = strings.Trim(line, " ") } } osf.Close() return f }