package cms import ( "errors" "fmt" "io/fs" "os" "path/filepath" "sort" "strings" ) func AddPath(root string, opts AddOptions) (AddReport, error) { sourcePath, err := expandPath(opts.Path) if err != nil { return AddReport{}, err } info, err := os.Stat(sourcePath) if err != nil { return AddReport{}, err } if !info.IsDir() { doc, err := AddFile(root, opts) if err != nil { return AddReport{}, err } return AddReport{Documents: []Document{doc}}, nil } if opts.Title != "" || opts.Slug != "" { return AddReport{}, errors.New("--title and --slug can only be used when importing one file") } files, err := importableFiles(sourcePath) if err != nil { return AddReport{}, err } if len(files) == 0 { return AddReport{}, fmt.Errorf("%s has no .md or .gmi files", sourcePath) } report := AddReport{} for _, file := range files { fileOpts := opts fileOpts.Path = file doc, err := AddFile(root, fileOpts) if err != nil { return report, fmt.Errorf("import %s: %w", file, err) } report.Documents = append(report.Documents, doc) } return report, nil } func importableFiles(root string) ([]string, error) { var files []string err := filepath.WalkDir(root, func(pathName string, entry fs.DirEntry, err error) error { if err != nil { return err } if entry.IsDir() { if strings.HasPrefix(entry.Name(), ".") && pathName != root { return filepath.SkipDir } return nil } if isImportableContent(pathName) { files = append(files, pathName) } return nil }) sort.Strings(files) return files, err } func isImportableContent(pathName string) bool { switch strings.ToLower(filepath.Ext(pathName)) { case ".md", ".markdown", ".gmi", ".gemini": return true default: return false } }