Skip to content

Commit

Permalink
feat(kernel): add folder navigator (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
plastikfan committed Jul 3, 2024
1 parent 01885f1 commit d809edd
Show file tree
Hide file tree
Showing 19 changed files with 341 additions and 176 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"shogo",
"sidewalk",
"snivilised",
"sortables",
"staticcheck",
"struct",
"structcheck",
Expand Down
8 changes: 8 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ tasks:
- go build ./...

# === test =================================================
# to see how to select tests by label, refer to:
# https://onsi.github.io/ginkgo/#spec-labels
#
# equal: --label-filter="foo"
# not: --label-filter="!foo"
# and: --label-filter="!foo && bar"
# or: --label-filter="!foo || bar"
# regex: --label-filter="/pattern/"

dry:
cmds:
Expand Down
25 changes: 25 additions & 0 deletions enums/entry-type-en-auto.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions enums/entry-type-en.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ const (
// EntryTypeFile
//
EntryTypeFile // file-entry

// EntryTypeAll
//
EntryTypeAll // all-entries
)
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ require (
github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
github.com/pkg/errors v0.9.1
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/samber/lo v1.39.0 // indirect
github.com/samber/lo v1.39.0
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
Expand Down
24 changes: 16 additions & 8 deletions internal/helpers/directory-tree-builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,28 @@ const (
doWrite = true
)

func Musico(portion string, verbose bool) (fsys fstest.MapFS, root string) {
func Musico(verbose bool, portions ...string) (fsys fstest.MapFS, root string) {
fsys = fstest.MapFS{
".": &fstest.MapFile{
Mode: os.ModeDir,
},
}

return fsys, Provision(
NewMemWriteProvider(fsys, os.ReadFile, portion),
portion,
NewMemWriteProvider(fsys, os.ReadFile, portions...),
verbose,
portions...,
)
}

func Provision(provider *IOProvider, portion string, verbose bool) (root string) {
func Provision(provider *IOProvider, verbose bool, portions ...string) (root string) {
repo := Repo(filepath.Join("..", "..", "test", "data", "MUSICO"))
utils.Must(ensure(repo, provider, verbose))

if verbose {
fmt.Printf("\n🤖 re-generated tree at '%v' (filter: '%v')\n\n", repo, portion)
fmt.Printf("\n🤖 re-generated tree at '%v' (filters: '%v')\n\n",
repo, strings.Join(portions, ", "),
)
}

return repo
Expand Down Expand Up @@ -89,11 +91,17 @@ func TrimRoot(root string) string {
// NewMemWriteProvider
func NewMemWriteProvider(store fstest.MapFS,
indexReader readFile,
portion string,
portions ...string,
) *IOProvider {
filter := lo.Ternary(portion != "",
filter := lo.Ternary(len(portions) > 0,
matcher(func(path string) bool {
return strings.Contains(path, portion)
for _, portion := range portions {
if strings.Contains(path, portion) {
return true
}
}

return false
}),
matcher(func(string) bool {
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,39 @@ import (
"github.com/snivilised/traverse/pref"
)

func newDirectoryContents(o *pref.Options,
func newContents(o *pref.Options,
entries []fs.DirEntry,
) *DirectoryContents {
contents := DirectoryContents{
) *Contents {
contents := Contents{
o: o,
}

contents.Arrange(entries)
contents.arrange(entries)

return &contents
}

// DirectoryContents represents the contents of a directory's contents and
// Contents represents the contents of a directory's contents and
// handles sorting order which by default is different between various
// operating systems. This abstraction removes the differences in sorting
// behaviour on different platforms.
type DirectoryContents struct {
type Contents struct {
folders []fs.DirEntry
files []fs.DirEntry
o *pref.Options
}

func (c *DirectoryContents) Folders() []fs.DirEntry {
func (c *Contents) Folders() []fs.DirEntry {
return c.folders
}

func (c *DirectoryContents) Files() []fs.DirEntry {
func (c *Contents) Files() []fs.DirEntry {
return c.files
}

// All returns the contents of a directory respecting the directory sorting
// order defined in the traversal options.
func (c *DirectoryContents) All() []fs.DirEntry {
func (c *Contents) All() []fs.DirEntry {
result := make([]fs.DirEntry, 0, len(c.files)+len(c.folders))

switch c.o.Core.Behaviours.Sort.DirectoryEntryOrder {
Expand All @@ -56,40 +56,35 @@ func (c *DirectoryContents) All() []fs.DirEntry {
return result
}

// Sort will sort either the folders or files or if no
// entry type is specified, sort both.
func (c *DirectoryContents) Sort(ents ...enums.EntryType) {
// This looks complicated, but it really isn't. The reason is
// we only want to sort only what's really required and the sorting
// of entries must be separated by type, ie we dont want all the
// files and folders sorted into a single collection and the
// requested entry types need to be mapped into the corresponding
// internal directory entries.
//
for _, entries := range lo.TernaryF(len(ents) == 0,
func() [][]fs.DirEntry {
// Sort will sort either the folders or files or both.
func (c *Contents) Sort(et enums.EntryType) {
type selectors map[enums.EntryType]func() [][]fs.DirEntry

sortables := selectors{
enums.EntryTypeAll: func() [][]fs.DirEntry {
return [][]fs.DirEntry{
c.folders, c.files,
}
},
func() [][]fs.DirEntry {
if ents[0] == enums.EntryTypeFolder {
return [][]fs.DirEntry{c.folders}
}

enums.EntryTypeFolder: func() [][]fs.DirEntry {
return [][]fs.DirEntry{c.folders}
},
enums.EntryTypeFile: func() [][]fs.DirEntry {
return [][]fs.DirEntry{c.files}
},
) {
}

for _, entries := range sortables[et]() {
c.o.Hooks.Sort.Invoke()(entries)
}
}

func (c *DirectoryContents) Clear() {
func (c *Contents) Clear() {
c.files = []fs.DirEntry{}
c.folders = []fs.DirEntry{}
}

func (c *DirectoryContents) Arrange(entries []fs.DirEntry) {
func (c *Contents) arrange(entries []fs.DirEntry) {
grouped := lo.GroupBy(entries, func(entry fs.DirEntry) bool {
return entry.IsDir()
})
Expand All @@ -106,19 +101,19 @@ func (c *DirectoryContents) Arrange(entries []fs.DirEntry) {
}
}

func newEmptyDirectoryEntries(o *pref.Options,
func newEmptyContents(o *pref.Options,
prealloc ...*pref.EntryQuantities,
) *DirectoryContents {
) *Contents {
return lo.TernaryF(len(prealloc) == 0,
func() *DirectoryContents {
return &DirectoryContents{
func() *Contents {
return &Contents{
o: o,
files: []fs.DirEntry{},
folders: []fs.DirEntry{},
}
},
func() *DirectoryContents {
return &DirectoryContents{
func() *Contents {
return &Contents{
o: o,
files: make([]fs.DirEntry, 0, prealloc[0].Files),
folders: make([]fs.DirEntry, 0, prealloc[0].Folders),
Expand Down
31 changes: 22 additions & 9 deletions internal/kernel/kernel-defs.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
type (
// NavigatorImpl
NavigatorImpl interface {
// Starting
Starting(session core.Session)

// Top
Expand All @@ -27,6 +28,7 @@ type (
current *core.Node,
) (bool, error)

// Result
Result(ctx context.Context, err error) *types.KernelResult
}

Expand Down Expand Up @@ -99,10 +101,10 @@ type (
// navigationVapour represents short-lived navigation data whose state relates
// only to the current Node. (equivalent to inspection in extendio)
navigationVapour struct { // after content has been read
ns *navigationStatic
currentNode *core.Node
directoryContents *DirectoryContents
ents []fs.DirEntry
ns *navigationStatic
present *core.Node
cargo *Contents
ents []fs.DirEntry
}

navigationInfo struct { // pre content read
Expand All @@ -127,21 +129,32 @@ func (v *navigationVapour) static() *navigationStatic {
}

func (v *navigationVapour) current() *core.Node {
return v.currentNode
return v.present
}

func (v *navigationVapour) contents() core.DirectoryContents {
return v.directoryContents
return v.cargo
}

func (v *navigationVapour) entries() []fs.DirEntry {
return v.ents
}

func (v *navigationVapour) clear() {
if v.directoryContents != nil {
v.directoryContents.Clear()
if v.cargo != nil {
v.cargo.Clear()
} else {
newEmptyDirectoryEntries(v.ns.mediator.o)
newEmptyContents(v.ns.mediator.o)
}
}

func (v *navigationVapour) pick(et enums.EntryType) {
switch et {
case enums.EntryTypeAll:
v.ents = v.cargo.All()
case enums.EntryTypeFolder:
v.ents = v.cargo.folders
case enums.EntryTypeFile:
v.ents = v.cargo.files
}
}
Loading

0 comments on commit d809edd

Please sign in to comment.