Skip to content

Commit

Permalink
feat(kernel): add skeleton navigator (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
plastikfan committed Jun 19, 2024
1 parent 0194298 commit 19fe6e8
Show file tree
Hide file tree
Showing 36 changed files with 1,585 additions and 283 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"astrolib",
"Berthe",
"bodyclose",
"Clonable",
"cmds",
"Cobrass",
"coverpkg",
Expand Down Expand Up @@ -40,6 +41,7 @@
"govet",
"graffico",
"hiber",
"icase",
"ineffassign",
"jibberjabber",
"leaktest",
Expand Down
4 changes: 4 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ tasks:
cmds:
- go test ./...

ta:
cmds:
- go test ./tapable

tc:
cmds:
- go test ./cycle
Expand Down
2 changes: 1 addition & 1 deletion builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (bs *Builders) buildAll() (*buildArtefacts, error) {
}, navErr
}

plugins, pluginsErr := bs.plugins.build(o)
plugins, pluginsErr := bs.plugins.build(o, bs.extent.plugin()) // !!!
if pluginsErr != nil {
had, _ := kernel.HadesNav(pluginsErr)

Expand Down
14 changes: 14 additions & 0 deletions core/directory-contents.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package core

import (
"io/fs"
)

// DirectoryContents 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 {
Folders []fs.DirEntry
Files []fs.DirEntry
}
62 changes: 60 additions & 2 deletions core/errors.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,65 @@
package core

import "errors"
import (
"errors"
"fmt"
)

// Errors defined here are internal errors that are of no value to end
// users (hence not l10n). There are usually programming errors which
// means they only have meaning for client developers.

// ❌ Invalid Notification Mute Requested

// NewInvalidNotificationMuteRequestedNativeError creates an untranslated error to
// indicate invalid notification mute requested (internal error)
func NewInvalidNotificationMuteRequestedNativeError(value string) error {
return fmt.Errorf("internal: invalid notification mute requested (%v)", value)
}

// ❌ Invalid Resume State Transition Detected

// NewItemAlreadyExtendedNativeError creates an untranslated error to
// indicate invalid resume state transition occurred (internal error)
func NewInvalidResumeStateTransitionNativeError(state string) error {
return fmt.Errorf("internal: invalid resume state transition detected (%v)", state)
}

// ❌ Item already extended

// NewItemAlreadyExtendedNativeError creates an untranslated error to
// indicate traverse-item already extended (internal error)
func NewItemAlreadyExtendedNativeError(path string) error {
return fmt.Errorf("internal: item already extended for item at: '%v'", path)
}

// ❌ Missing listen detacher function

// NewMissingListenDetacherFunctionNativeError creates an untranslated error to
// indicate invalid resume state transition occurred (internal error)
func NewMissingListenDetacherFunctionNativeError(state string) error {
return fmt.Errorf("internal: missing listen detacher function (%v)", state)
}

// ❌ Invalid Periscope Root Path

// NewInvalidPeriscopeRootPathNativeError creates an untranslated error to
// indicate invalid resume state transition occurred (internal error)
func NewInvalidPeriscopeRootPathNativeError(root, current string) error {
return fmt.Errorf("internal: root path '%v' can't be longer than current '%v'", root, current)
}

// ❌ Resume controller not set

// NewResumeControllerNotSetNativeError creates an untranslated error to
// indicate resume controller not set (internal error)
func NewResumeControllerNotSetNativeError(from string) error {
return fmt.Errorf("internal: resume controller not set (from: '%v')", from)
}

var (
ErrNotImpl = errors.New("NOT-IMPL")
ErrNotImpl = errors.New("NOT-IMPL")
ErrUndefinedSubscriptionType = errors.New(
"undefined subscription type; please set in traverse options (/Options.Store.Subscription)",
)
)
30 changes: 30 additions & 0 deletions core/hooks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package core

import (
"io/fs"
)

type (
// QueryStatusHook function signature that enables the default to be overridden.
// (By default, uses Lstat)
QueryStatusHook func(path string) (fs.FileInfo, error)

// ReadDirectoryHook hook function to define implementation of how a directory's
// entries are read. A default implementation is preset, so does not have to be set
// by the client.
ReadDirectoryHook func(sys fs.FS, dirname string) ([]fs.DirEntry, error)

// SortHook hook function to define how directory entries are sorted. Does not
// have to be set explicitly. This will be set according to the IsCaseSensitive on
// the TraverseOptions, but can be overridden if needed.
SortHook func(entries []fs.DirEntry, custom ...any) error

SubPathInfo struct {
Root string
Node *Node
KeepTrailingSep bool
}

// SubPathHook
SubPathHook func(info *SubPathInfo) string
)
50 changes: 42 additions & 8 deletions director.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package tv

import (
"os"

"github.com/snivilised/traverse/core"
"github.com/snivilised/traverse/internal/hiber"
"github.com/snivilised/traverse/internal/kernel"
Expand All @@ -15,30 +17,55 @@ type ifActive func(o *pref.Options) types.Plugin

// activated interrogates options and invokes requests on behalf of the user
// to activate features according to option selections
func activated(o *pref.Options) ([]types.Plugin, error) {
func activated(o *pref.Options, others ...types.Plugin) (plugins []types.Plugin, err error) {
var (
all = []ifActive{
hiber.IfActive, refine.IfActive, sampling.IfActive,
}
plugins = []types.Plugin{}
err error
)

plugins = []types.Plugin{}

for _, active := range all {
if plugin := active(o); plugin != nil {
plugins = append(plugins, plugin)
err = plugin.Init()

if err != nil {
return nil, err
}
}
}

for _, plugin := range others {
if plugin != nil {
plugins = append(plugins, plugin)
err = plugin.Init()

if err != nil {
return nil, err
}
}
}

return plugins, err
return plugins, nil
}

// Prime extent requests that the navigator performs a full
// traversal from the root path specified.
func Prime(using *pref.Using, settings ...pref.Option) *Builders {
sys := os.DirFS(using.Root)

// TODO: we need to create an aux file system, which is bound
// to a pre-defined location, that will be called upon if
// the navigation session is terminated either by a ctrl-c or
// by a panic.

return &Builders{
extent: &primeExtent{
baseExtent: baseExtent{
sys: sys,
},
u: using,
},
options: optionals(func() (*pref.Options, error) {
Expand All @@ -50,9 +77,6 @@ func Prime(using *pref.Using, settings ...pref.Option) *Builders {
return using.O, nil
}

// we probably need to mark something somehow to indicate
// Prime
//
return pref.Get(settings...)
}),
navigator: builder(func(o *pref.Options) (core.Navigator, error) {
Expand All @@ -67,8 +91,18 @@ func Prime(using *pref.Using, settings ...pref.Option) *Builders {
// as a result of it being terminated prematurely via a ctrl-c
// interrupt.
func Resume(was *Was, settings ...pref.Option) *Builders {
aux := os.DirFS(was.From)

// TODO: the navigation file system, baseExtent.sys, will be set for
// resume, only once the resume file has been loaded, as
// its only at this point, we know where the original root
// path was.

return &Builders{
extent: &resumeExtent{
baseExtent: baseExtent{
aux: aux,
},
w: was,
},
// we need state; record the hibernation wake point, so
Expand All @@ -85,7 +119,7 @@ func Resume(was *Was, settings ...pref.Option) *Builders {
// for hibernation condition just needs to be added to
// the extent interface.
//
o, err := pref.Load(was.From, settings...)
o, err := pref.Load(aux, was.From, settings...)

// get the resume point from the resume persistence file
// then set up hibernation with this defined as a hibernation
Expand Down
10 changes: 7 additions & 3 deletions enums/role-en-auto.go

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

8 changes: 6 additions & 2 deletions enums/role-en.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ package enums
type Role uint32

const (
RoleUndefined Role = iota // undefined-role
RoleDirectoryReader // directory-reader-role
RoleUndefined Role = iota // undefined-role
RoleTerminus // terminus-role
RoleClientFilter // client-filter-role
RoleClientHiberWake // client-hiber-wake
RoleClientHiberSleep // client-hiber-sleep
RoleFastward // fastward-role
)
8 changes: 4 additions & 4 deletions enums/subscription-en-auto.go

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

29 changes: 22 additions & 7 deletions extent.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
package tv

import (
"io/fs"

"github.com/snivilised/traverse/internal/resume"
"github.com/snivilised/traverse/internal/types"
"github.com/snivilised/traverse/pref"
)

type extent interface {
using() *pref.Using
was() *pref.Was
plugin() types.Plugin
}

type baseExtent struct {
sys fs.FS
aux fs.FS
}

type primeExtent struct {
baseExtent
u *pref.Using
}

func (pe *primeExtent) using() *pref.Using {
return pe.u
func (ex *primeExtent) using() *pref.Using {
return ex.u
}

func (ex *primeExtent) was() *pref.Was {
return nil
}

func (pe *primeExtent) was() *pref.Was {
func (ex *primeExtent) plugin() types.Plugin {
return nil
}

Expand All @@ -30,10 +41,14 @@ type resumeExtent struct {
w *pref.Was
}

func (re *resumeExtent) using() *pref.Using {
return &re.w.Using
func (ex *resumeExtent) using() *pref.Using {
return &ex.w.Using
}

func (ex *resumeExtent) was() *pref.Was {
return ex.w
}

func (re *resumeExtent) was() *pref.Was {
return re.w
func (ex *resumeExtent) plugin() types.Plugin {
return &resume.Plugin{}
}
Loading

0 comments on commit 19fe6e8

Please sign in to comment.