aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/index
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/index')
-rw-r--r--pkg/index/filters.go40
-rw-r--r--pkg/index/filters_test.go30
-rw-r--r--pkg/index/index.go32
-rw-r--r--pkg/index/index_test.go53
4 files changed, 82 insertions, 73 deletions
diff --git a/pkg/index/filters.go b/pkg/index/filters.go
index 44b12cf..a60a629 100644
--- a/pkg/index/filters.go
+++ b/pkg/index/filters.go
@@ -15,7 +15,7 @@ import (
type DocFilter struct {
Name string
- Filter func(infoPath, io.ReadSeeker) bool
+ Filter func(InfoPath, io.ReadSeeker) bool
}
const FilterHelp string = `
@@ -77,8 +77,8 @@ func ParseFilter(s string) (DocFilter, error) {
func NewExtensionFilter(ext string) DocFilter {
return DocFilter{
ext + " Filter",
- func(ip infoPath, _ io.ReadSeeker) bool {
- return filepath.Ext(ip.path) == ext
+ func(ip InfoPath, _ io.ReadSeeker) bool {
+ return filepath.Ext(ip.Path) == ext
},
}
}
@@ -86,8 +86,8 @@ func NewExtensionFilter(ext string) DocFilter {
func NewMaxFilesizeFilter(size int64) DocFilter {
return DocFilter{
fmt.Sprintf("Max Size Filter %d", size),
- func(ip infoPath, _ io.ReadSeeker) bool {
- return ip.info.Size() <= size
+ func(ip InfoPath, _ io.ReadSeeker) bool {
+ return ip.Info.Size() <= size
},
}
}
@@ -95,8 +95,8 @@ func NewMaxFilesizeFilter(size int64) DocFilter {
func NewExcludeFilenameFilter(excluded []string) DocFilter {
return DocFilter{
"Excluded Filename filter",
- func(ip infoPath, _ io.ReadSeeker) bool {
- filename := filepath.Base(ip.path)
+ func(ip InfoPath, _ io.ReadSeeker) bool {
+ filename := filepath.Base(ip.Path)
return !slices.Contains(excluded, filename)
},
}
@@ -105,8 +105,8 @@ func NewExcludeFilenameFilter(excluded []string) DocFilter {
func NewIncludeFilenameFilter(included []string) DocFilter {
return DocFilter{
"Included Filename filter",
- func(ip infoPath, _ io.ReadSeeker) bool {
- filename := filepath.Base(ip.path)
+ func(ip InfoPath, _ io.ReadSeeker) bool {
+ filename := filepath.Base(ip.Path)
return slices.Contains(included, filename)
},
}
@@ -116,8 +116,8 @@ func NewIncludeFilenameFilter(included []string) DocFilter {
func NewExcludeParentFilter(badParent string) DocFilter {
return DocFilter{
"Excluded Parent Directory filter: " + badParent,
- func(ip infoPath, _ io.ReadSeeker) bool {
- return !slices.Contains(strings.Split(ip.path, string(os.PathSeparator)), badParent)
+ func(ip InfoPath, _ io.ReadSeeker) bool {
+ return !slices.Contains(strings.Split(ip.Path, string(os.PathSeparator)), badParent)
},
}
}
@@ -130,8 +130,8 @@ func NewIncludeRegexFilter(pattern string) (DocFilter, error) {
return DocFilter{
"Included Regex Filter: " + pattern,
- func(ip infoPath, _ io.ReadSeeker) bool {
- return re.MatchString(ip.path)
+ func(ip InfoPath, _ io.ReadSeeker) bool {
+ return re.MatchString(ip.Path)
},
}, nil
}
@@ -143,23 +143,21 @@ func NewExcludeRegexFilter(pattern string) (DocFilter, error) {
return DocFilter{
"Excluded Regex Filter: " + pattern,
- func(ip infoPath, _ io.ReadSeeker) bool {
- return !re.MatchString(ip.path)
+ func(ip InfoPath, _ io.ReadSeeker) bool {
+ return !re.MatchString(ip.Path)
},
}, nil
}
var YamlHeaderFilter = DocFilter{
"YAML Header Filter",
- yamlHeaderFilterFunc,
-}
-
-func yamlHeaderFilterFunc(_ infoPath, r io.ReadSeeker) bool {
- return yamlHeaderPos(r) > 0
+ func(_ InfoPath, rs io.ReadSeeker) bool {
+ return YamlHeaderPos(rs) > 0
+ },
}
// Position of the end of a yaml header, negative
-func yamlHeaderPos(r io.ReadSeeker) int64 {
+func YamlHeaderPos(r io.ReadSeeker) int64 {
const bufSize = 4096
buf := make([]byte, bufSize)
diff --git a/pkg/index/filters_test.go b/pkg/index/filters_test.go
index f46874c..bedf5e9 100644
--- a/pkg/index/filters_test.go
+++ b/pkg/index/filters_test.go
@@ -1,10 +1,12 @@
-package index
+package index_test
import (
"bytes"
"io"
"os"
"testing"
+
+ "github.com/jpappel/atlas/pkg/index"
)
func noYamlHeader() io.ReadSeeker {
@@ -27,7 +29,7 @@ func trailingYamlHeader() io.ReadSeeker {
return bytes.NewReader(buf)
}
-func extensionless(t *testing.T) infoPath {
+func extensionless(t *testing.T) index.InfoPath {
root := t.TempDir()
path := root + "/" + "afile"
f, err := os.Create(path)
@@ -45,10 +47,10 @@ func extensionless(t *testing.T) infoPath {
t.Fatal(err)
}
- return infoPath{path, info}
+ return index.InfoPath{path, info}
}
-func markdownExtension(t *testing.T) infoPath {
+func markdownExtension(t *testing.T) index.InfoPath {
root := t.TempDir()
path := root + "/" + "a.md"
f, err := os.Create(path)
@@ -62,23 +64,23 @@ func markdownExtension(t *testing.T) infoPath {
t.Fatal(err)
}
- return infoPath{path, info}
+ return index.InfoPath{path, info}
}
-func parentDirectory(t *testing.T) infoPath {
+func parentDirectory(t *testing.T) index.InfoPath {
root := t.TempDir()
dir := root + "/parent"
path := dir + "/a"
- return infoPath{path: path}
+ return index.InfoPath{Path: path}
}
-func grandparentDirectory(t *testing.T) infoPath {
+func grandparentDirectory(t *testing.T) index.InfoPath {
root := t.TempDir()
dir := root + "/grandparent/parent"
path := dir + "/a"
- return infoPath{path: path}
+ return index.InfoPath{Path: path}
}
func TestYamlHeaderFilter(t *testing.T) {
@@ -94,7 +96,7 @@ func TestYamlHeaderFilter(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- got := yamlHeaderFilterFunc(infoPath{}, tt.r)
+ got := index.YamlHeaderPos(tt.r) > 0
if got != tt.want {
t.Errorf("YamlHeaderFilter() = %v, want %v", got, tt.want)
}
@@ -105,7 +107,7 @@ func TestYamlHeaderFilter(t *testing.T) {
func TestExtensionFilter(t *testing.T) {
tests := []struct {
name string
- infoGen func(*testing.T) infoPath
+ infoGen func(*testing.T) index.InfoPath
ext string
want bool
}{
@@ -116,7 +118,7 @@ func TestExtensionFilter(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- docFilter := NewExtensionFilter(tt.ext)
+ docFilter := index.NewExtensionFilter(tt.ext)
ip := tt.infoGen(t)
got := docFilter.Filter(ip, nil)
@@ -130,7 +132,7 @@ func TestExtensionFilter(t *testing.T) {
func TestExcludeParentFilter(t *testing.T) {
tests := []struct {
name string
- infoGen func(*testing.T) infoPath
+ infoGen func(*testing.T) index.InfoPath
parent string
want bool
}{
@@ -152,7 +154,7 @@ func TestExcludeParentFilter(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- docFilter := NewExcludeParentFilter(tt.parent)
+ docFilter := index.NewExcludeParentFilter(tt.parent)
ip := tt.infoGen(t)
got := docFilter.Filter(ip, nil)
diff --git a/pkg/index/index.go b/pkg/index/index.go
index 419607c..a35b670 100644
--- a/pkg/index/index.go
+++ b/pkg/index/index.go
@@ -36,9 +36,9 @@ type ParseOpts struct {
IgnoreMetaError bool
}
-type infoPath struct {
- path string
- info os.FileInfo
+type InfoPath struct {
+ Path string
+ Info os.FileInfo
}
type Index struct {
@@ -191,12 +191,12 @@ func (doc Document) Equal(other Document) bool {
return true
}
-func visit(file infoPath, visitQueue chan<- infoPath, filterQueue chan<- infoPath, wg *sync.WaitGroup) {
+func visit(file InfoPath, visitQueue chan<- InfoPath, filterQueue chan<- InfoPath, wg *sync.WaitGroup) {
// TODO: check if symlink, and handle appropriately
// TODO: extract error out of function
- if file.info.IsDir() {
- entries, err := os.ReadDir(file.path)
+ if file.Info.IsDir() {
+ entries, err := os.ReadDir(file.Path)
if err != nil {
panic(err)
}
@@ -209,17 +209,17 @@ func visit(file infoPath, visitQueue chan<- infoPath, filterQueue chan<- infoPat
}
// PERF: prevents deadlock but introduces an additional goroutine overhead per file
go func(path string) {
- visitQueue <- infoPath{path: path, info: entryInfo}
- }(file.path + "/" + entry.Name())
+ visitQueue <- InfoPath{Path: path, Info: entryInfo}
+ }(file.Path + "/" + entry.Name())
}
- } else if file.info.Mode().IsRegular() {
+ } else if file.Info.Mode().IsRegular() {
filterQueue <- file
}
wg.Done()
}
-func workerTraverse(wg *sync.WaitGroup, visitQueue chan infoPath, filterQueue chan<- infoPath) {
+func workerTraverse(wg *sync.WaitGroup, visitQueue chan InfoPath, filterQueue chan<- InfoPath) {
for work := range visitQueue {
visit(work, visitQueue, filterQueue, wg)
}
@@ -236,8 +236,8 @@ func (idx Index) Traverse(numWorkers uint) []string {
panic(err)
}
- jobs := make(chan infoPath, numWorkers)
- filterQueue := make(chan infoPath, numWorkers)
+ jobs := make(chan InfoPath, numWorkers)
+ filterQueue := make(chan InfoPath, numWorkers)
activeJobs := &sync.WaitGroup{}
@@ -248,7 +248,7 @@ func (idx Index) Traverse(numWorkers uint) []string {
// init send
activeJobs.Add(1)
- jobs <- infoPath{path: idx.Root, info: rootInfo}
+ jobs <- InfoPath{Path: idx.Root, Info: rootInfo}
// close jobs queue
go func() {
@@ -259,7 +259,7 @@ func (idx Index) Traverse(numWorkers uint) []string {
// gather
for doc := range filterQueue {
- docs = append(docs, doc.path)
+ docs = append(docs, doc.Path)
}
return docs
@@ -278,7 +278,7 @@ func (idx Index) FilterOne(path string) bool {
defer f.Close()
for _, docFilter := range idx.Filters {
- if !docFilter.Filter(infoPath{string(path), info}, f) {
+ if !docFilter.Filter(InfoPath{string(path), info}, f) {
return false
}
if _, err := f.Seek(0, io.SeekStart); err != nil {
@@ -340,7 +340,7 @@ func ParseDoc(path string, opts ParseOpts) (*Document, error) {
}
doc.FileTime = info.ModTime()
- pos := yamlHeaderPos(f)
+ pos := YamlHeaderPos(f)
f.Seek(0, io.SeekStart)
if pos < 0 {
return nil, fmt.Errorf("Can't find YAML header in %s", path)
diff --git a/pkg/index/index_test.go b/pkg/index/index_test.go
index 3f9b900..0a3239d 100644
--- a/pkg/index/index_test.go
+++ b/pkg/index/index_test.go
@@ -1,4 +1,4 @@
-package index
+package index_test
import (
"errors"
@@ -7,16 +7,18 @@ import (
"slices"
"testing"
"time"
+
+ "github.com/jpappel/atlas/pkg/index"
)
-var indexCases map[string]func(t *testing.T) Index
+var indexCases map[string]func(t *testing.T) index.Index
func init() {
- indexCases = make(map[string]func(t *testing.T) Index)
+ indexCases = make(map[string]func(t *testing.T) index.Index)
- indexCases["single file"] = func(t *testing.T) Index {
+ indexCases["single file"] = func(t *testing.T) index.Index {
root := t.TempDir()
- index := Index{Root: root, Filters: []DocFilter{NewExtensionFilter(".md")}}
+ index := index.Index{Root: root, Filters: []index.DocFilter{index.NewExtensionFilter(".md")}}
f, err := os.Create(root + "/a_file.md")
if err != nil {
@@ -27,16 +29,16 @@ func init() {
return index
}
- indexCases["large file"] = func(t *testing.T) Index {
+ indexCases["large file"] = func(t *testing.T) index.Index {
root := t.TempDir()
- index := Index{Root: root}
+ index := index.Index{Root: root}
return index
}
- indexCases["worker saturation"] = func(t *testing.T) Index {
+ indexCases["worker saturation"] = func(t *testing.T) index.Index {
root := t.TempDir()
- index := Index{Root: root}
+ index := index.Index{Root: root}
permission := os.FileMode(0o777)
for _, dirName := range []string{"a", "b", "c", "d", "e", "f"} {
@@ -61,7 +63,7 @@ func init() {
func TestIndex_Traverse(t *testing.T) {
tests := []struct {
name string
- indexCase func(t *testing.T) Index
+ indexCase func(t *testing.T) index.Index
numWorkers uint
want []string
}{
@@ -104,7 +106,7 @@ func TestIndex_Filter(t *testing.T) {
tests := []struct {
name string
paths []string
- indexCase func(t *testing.T) Index
+ indexCase func(t *testing.T) index.Index
numWorkers uint
want []string
}{
@@ -154,7 +156,8 @@ func TestIndex_ParseOne(t *testing.T) {
tests := []struct {
name string
pathMaker func(t *testing.T) string
- want *Document
+ parseOpts index.ParseOpts
+ want *index.Document
wantErr error
}{
{
@@ -166,7 +169,8 @@ func TestIndex_ParseOne(t *testing.T) {
f.WriteString("---\ntitle: A title\n---\n")
return path
},
- &Document{Title: "A title"},
+ index.ParseOpts{},
+ &index.Document{Title: "A title"},
nil,
},
{
@@ -184,7 +188,8 @@ func TestIndex_ParseOne(t *testing.T) {
return path
},
- &Document{Tags: []string{"a", "b", "c"}},
+ index.ParseOpts{},
+ &index.Document{Tags: []string{"a", "b", "c"}},
nil,
},
{
@@ -197,7 +202,8 @@ func TestIndex_ParseOne(t *testing.T) {
return path
},
- &Document{Date: time.Date(2025, time.May, 1, 0, 0, 0, 0, time.UTC)},
+ index.ParseOpts{},
+ &index.Document{Date: time.Date(2025, time.May, 1, 0, 0, 0, 0, time.UTC)},
nil,
},
{
@@ -210,7 +216,8 @@ func TestIndex_ParseOne(t *testing.T) {
return path
},
- &Document{Authors: []string{"Rob Pike"}},
+ index.ParseOpts{},
+ &index.Document{Authors: []string{"Rob Pike"}},
nil,
},
{
@@ -223,7 +230,8 @@ func TestIndex_ParseOne(t *testing.T) {
return path
},
- &Document{Authors: []string{"Robert Griesemer", "Rob Pike", "Ken Thompson"}},
+ index.ParseOpts{},
+ &index.Document{Authors: []string{"Robert Griesemer", "Rob Pike", "Ken Thompson"}},
nil,
},
{
@@ -238,7 +246,8 @@ func TestIndex_ParseOne(t *testing.T) {
return path
},
- &Document{OtherMeta: "unknownKey: value\n"},
+ index.ParseOpts{ParseMeta: true},
+ &index.Document{OtherMeta: "unknownKey: value\n"},
nil,
},
{
@@ -253,8 +262,9 @@ func TestIndex_ParseOne(t *testing.T) {
return path
},
- &Document{},
- ErrHeaderParse,
+ index.ParseOpts{},
+ &index.Document{},
+ index.ErrHeaderParse,
},
}
for _, tt := range tests {
@@ -262,8 +272,7 @@ func TestIndex_ParseOne(t *testing.T) {
path := tt.pathMaker(t)
tt.want.Path = path
- // TODO: add ParseOpts as test param
- got, gotErr := ParseDoc(path, ParseOpts{ParseMeta: true})
+ got, gotErr := index.ParseDoc(path, tt.parseOpts)
if !errors.Is(gotErr, tt.wantErr) {
t.Errorf("Recieved unexpected error: want %v got %v", tt.wantErr, gotErr)