loader

package
v2.0.0-rc16 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2024 License: MIT Imports: 10 Imported by: 0

README

Loader

This package loads markdown files from a file system into memory, retaining the file system tree structure.

ldr := loader.NewFsLoader(afero.NewOsFs())
folder, err := ldr.LoadTrees(args)
if err != nil {
  return err
}
visitor.VisitFolder(folder)

LoadTrees returns an instance of MyFolder.

MyFolder holds slices of MyFile and MyFolder.

Each of these is a tree node with a Name, a full Path, and a visitor acceptance method.

Documentation

Index

Constants

View Source
const (
	ReadmeFileName   = "README.md"
	OrderingFileName = "README_ORDER.txt"
	RootSlash        = FilePath(filepath.Separator)
	CurrentDir       = FilePath(".")
)
View Source
const (
	// WildCardLabel matches any label.
	WildCardLabel = Label(`__wildcard__`)

	// AnonLabel may be used as a label placeholder when a label is needed but not specified.
	AnonLabel = Label(`__anonymous__`)

	// SleepLabel indicates the author wants a sleep after the block in a test context
	// where there is no natural human-caused pause.
	SleepLabel = Label(`sleep`)
)

Variables

View Source
var IsADotDirErr = fmt.Errorf("not allowed to load from dot folder")
View Source
var NotMarkDownErr = fmt.Errorf("not a simple markdown file")

Functions

func CommentBody

func CommentBody(s string) string

func DirBase

func DirBase(path string) (dir, base string)

DirBase behavior:

	             path  |       dir  | base
	-------------------+------------+-----------
	   {empty string}  |         .  |  .
	                .  |         .  |  .
	               ./  |         .  |  .
                 /  |         /  |  /
	            ./foo  |         .  | foo
	           ../foo  |        ..  | foo
	             /foo  |         /  | foo
	   /usr/local/foo  | /usr/local | foo

func DumpBlocks

func DumpBlocks(wr io.Writer, blocks []*CodeBlock)

func EqualFileSlice

func EqualFileSlice(s1 []*MyFile, s2 []*MyFile) bool

func EqualFolderSlice

func EqualFolderSlice(s1 []*MyFolder, s2 []*MyFolder) bool

func IsMarkDownFile

func IsMarkDownFile(info os.FileInfo) error

IsMarkDownFile passes markdown files.

func IsNotADotDir

func IsNotADotDir(info os.FileInfo) error

IsNotADotDir returns an error if FileInfo happens to be a dot directory (.git, .config, etc.)

func IsOrderingFile

func IsOrderingFile(info os.FileInfo) bool

IsOrderingFile returns true if the file appears to be an "ordering" file specifying which files should come first in a directory.

func LoadOrderFile

func LoadOrderFile(fs *afero.Afero, path string) ([]string, error)

LoadOrderFile returns a list of names specify file name order priority.

Types

type CodeBlock

type CodeBlock struct {
	// contains filtered or unexported fields
}

CodeBlock groups an ast.FencedCodeBlock with a set of labels.

func NewCodeBlock

func NewCodeBlock(
	fi *MyFile, code string, index int, language string, labels ...Label) *CodeBlock

func (*CodeBlock) AddLabels

func (cb *CodeBlock) AddLabels(labels []Label)

func (*CodeBlock) Code

func (cb *CodeBlock) Code() string

func (*CodeBlock) Dump

func (cb *CodeBlock) Dump(wr io.Writer, index int)

func (*CodeBlock) Equals

func (cb *CodeBlock) Equals(other *CodeBlock) bool

Equals is true if the block have the same content, ignoring the parent.

func (*CodeBlock) FirstLabel

func (cb *CodeBlock) FirstLabel() Label

FirstLabel attempts to return the first human-authored label, and failing that makes up a label using the index.

func (*CodeBlock) HasLabel

func (cb *CodeBlock) HasLabel(label Label) bool

HasLabel is true if the block has the given label argument.

type FilePath

type FilePath string

FilePath helps w/ type safety and readability

type FsLoader

type FsLoader struct {
	IsAllowedFile, IsAllowedFolder filter
	// contains filtered or unexported fields
}

FsLoader navigates and reads a file system.

func New

func New(fs afero.Fs) *FsLoader

New returns a file system (FS) loader with default filters. For an in-memory FS, inject afero.NewMemMapFs(). For a "real" disk-based system, inject afero.NewOsFs().

func (*FsLoader) LoadFolder

func (fsl *FsLoader) LoadFolder(rawPath FilePath) (*MyFolder, error)

LoadFolder loads the files at or below a path into memory, returning them inside an MyFolder instance. LoadFolder must return a folder, even if its argument is a path to a file instead of a path to a folder.

The returned folder's name is computed as follows:

           path to file | returned folder name | folder contents
	  ------------------+----------------------+--------------
	             foo.md |                    . | foo.md
	           ./foo.md |                    . | foo.md
	          ../foo.md |            {illegal} | {illegal}
	  /usr/local/foo.md |           /usr/local | foo.md
	         bar/foo.md |                  bar | foo.md

	     path to folder | returned folder name | folder contents
	  ------------------+----------------------+--------------
	     {empty string} |                    . | {contents of .}
	                  . |                    . | {contents of .}
	                foo |                  foo | {contents of foo}
	              ./foo |                  foo | {contents of foo}
	             ../foo |            {illegal} | {illegal}
	     /usr/local/foo |       /usr/local/foo | {contents of foo}
	            bar/foo |              bar/foo | {contents of foo}

The ".." is disallowed in paths because it screws up making the left nav. TODO: consider converting such path to absolute paths.

The returned folder name might have to be abbreviated.

Files or folders that don't pass the loader's filters are excluded. If filtering leaves a folder empty, the folder is discarded. If nothing makes it through, the function returns a nil folder and no error.

If an "OrderingFileName" is found in a folder, it's used to sort the files and sub-folders in that folder's in-memory representation. An ordering file is just lines of text, one name per line. Ordered files appear first, with the remainder in the order imposed by fs.ReadDir.

Any error returned will be from the file system.

func (*FsLoader) LoadOneTree

func (fsl *FsLoader) LoadOneTree(rawPath FilePath) (*MyFolder, error)

LoadOneTree loads a file tree from disk, possibly after first cloning a repo from GitHub.

func (*FsLoader) LoadTrees

func (fsl *FsLoader) LoadTrees(args []string) (*MyFolder, error)

LoadTrees loads several paths, wrapping them all in virtual folder.

type Label

type Label string

Label is used to select code blocks, and group them into categories, e.g. run these blocks under test, run these blocks to do setup, etc.

func ParseLabels

func ParseLabels(s string) (result []Label)

func (Label) String

func (l Label) String() string

String form of the label.

type LabelList

type LabelList []Label

func NewLabelList

func NewLabelList(cbs []*CodeBlock) LabelList

func (LabelList) Contains

func (lst LabelList) Contains(l Label) bool

func (LabelList) Equals

func (lst LabelList) Equals(other LabelList) bool

Equals is true if the slices have the same contents, ordering irrelevant.

type MyFile

type MyFile struct {
	// contains filtered or unexported fields
}

MyFile is named byte array.

func NewEmptyFile

func NewEmptyFile(n string) *MyFile

func NewFile

func NewFile(n string, c []byte) *MyFile

func ReorderFiles

func ReorderFiles(x []*MyFile, ordering []string) []*MyFile

func (*MyFile) Accept

func (fi *MyFile) Accept(v TreeVisitor)

func (*MyFile) C

func (fi *MyFile) C() []byte

C is the contents of the file.

func (*MyFile) Equals

func (fi *MyFile) Equals(other *MyFile) bool

Equals checks for file equality

func (*MyFile) Load

func (fi *MyFile) Load(fsl *FsLoader) (err error)

Load loads the file contents into the file object.

func (*MyFile) Name

func (ti *MyFile) Name() string

Name is the base name of the item.

func (*MyFile) Parent

func (ti *MyFile) Parent() MyTreeNode

Parent is the parent of the item.

func (*MyFile) Path

func (ti *MyFile) Path() FilePath

Path is the fully qualified name of the item, including parents.

func (*MyFile) Root

func (ti *MyFile) Root() MyTreeNode

Root returns the "highest" non-nil tree item.

type MyFolder

type MyFolder struct {
	// contains filtered or unexported fields
}

MyFolder is a named group of files and folders.

func CloneAndLoadRepo

func CloneAndLoadRepo(fsl *FsLoader, arg string) (*MyFolder, error)

CloneAndLoadRepo clones a repo locally and loads it. The FsLoader should be injected with a real file system, since the git command line used here clones to real disk.

func NewFolder

func NewFolder(n string) *MyFolder

func ReorderFolders

func ReorderFolders(x []*MyFolder, ordering []string) []*MyFolder

func (*MyFolder) Accept

func (fl *MyFolder) Accept(v TreeVisitor)

func (*MyFolder) AddFile

func (fl *MyFolder) AddFile(file *MyFile) *MyFolder

func (*MyFolder) AddFolder

func (fl *MyFolder) AddFolder(folder *MyFolder) *MyFolder

func (*MyFolder) Equals

func (fl *MyFolder) Equals(other *MyFolder) bool

func (*MyFolder) HasFile

func (fl *MyFolder) HasFile(name string) bool

func (*MyFolder) IsEmpty

func (fl *MyFolder) IsEmpty() bool

func (*MyFolder) Name

func (ti *MyFolder) Name() string

Name is the base name of the item.

func (*MyFolder) NumFiles

func (fl *MyFolder) NumFiles() int

func (*MyFolder) NumFolders

func (fl *MyFolder) NumFolders() int

func (*MyFolder) Parent

func (ti *MyFolder) Parent() MyTreeNode

Parent is the parent of the item.

func (*MyFolder) Path

func (ti *MyFolder) Path() FilePath

Path is the fully qualified name of the item, including parents.

func (*MyFolder) Root

func (ti *MyFolder) Root() MyTreeNode

Root returns the "highest" non-nil tree item.

func (*MyFolder) VisitChildren

func (fl *MyFolder) VisitChildren(v TreeVisitor)

type MyTopFolder

type MyTopFolder struct {
	MyFolder
}

MyTopFolder is a named group of files and folders. It behaves slightly (but critically) different from a plain folder in that it never has a name.

func NewTopFolder

func NewTopFolder(fld *MyFolder) *MyTopFolder

func (*MyTopFolder) Accept

func (fl *MyTopFolder) Accept(v TreeVisitor)

func (*MyTopFolder) AddFile

func (fl *MyTopFolder) AddFile(file *MyFile) *MyTopFolder

func (*MyTopFolder) AddFolder

func (fl *MyTopFolder) AddFolder(folder *MyFolder) *MyTopFolder

func (*MyTopFolder) Equals

func (fl *MyTopFolder) Equals(other *MyTopFolder) bool

func (*MyTopFolder) Name

func (ti *MyTopFolder) Name() string

Name is the base name of the item.

func (*MyTopFolder) Parent

func (ti *MyTopFolder) Parent() MyTreeNode

Parent is the parent of the item.

func (*MyTopFolder) Path

func (ti *MyTopFolder) Path() FilePath

Path is the fully qualified name of the item, including parents.

func (*MyTopFolder) Root

func (ti *MyTopFolder) Root() MyTreeNode

Root returns the "highest" non-nil tree item.

type MyTreeNode

type MyTreeNode interface {
	Parent() MyTreeNode
	Name() string
	Path() FilePath
	Root() MyTreeNode
	Accept(TreeVisitor)
}

type TreeVisitor

type TreeVisitor interface {
	VisitTopFolder(*MyTopFolder)
	VisitFolder(*MyFolder)
	VisitFile(*MyFile)
	// Error returns the visitation error, if any.
	Error() error
}

TreeVisitor has the ability to visit the items specified in its methods.

type TxtPrinter

type TxtPrinter struct {
	// contains filtered or unexported fields
}

TxtPrinter prints a tutorial as text.

func NewTutorialTxtPrinter

func NewTutorialTxtPrinter(w io.Writer) *TxtPrinter

NewTutorialTxtPrinter makes a new TxtPrinter for the given writer.

func (*TxtPrinter) Depth

func (v *TxtPrinter) Depth() int

Depth is how deep we are in a tutorial tree.

func (*TxtPrinter) Down

func (v *TxtPrinter) Down()

Down goes deeper.

func (*TxtPrinter) Error

func (v *TxtPrinter) Error() error

func (*TxtPrinter) P

func (v *TxtPrinter) P(s string, a ...interface{})

P does a formatted print.

func (*TxtPrinter) Up

func (v *TxtPrinter) Up()

Up is opposite of Down.

func (*TxtPrinter) VisitFile

func (v *TxtPrinter) VisitFile(fi *MyFile)

func (*TxtPrinter) VisitFolder

func (v *TxtPrinter) VisitFolder(fl *MyFolder)

func (*TxtPrinter) VisitTopFolder

func (v *TxtPrinter) VisitTopFolder(fl *MyTopFolder)

type VisitorCounter

type VisitorCounter struct {
	NumFiles   int
	NumFolders int
}

func NewVisitorCounter

func NewVisitorCounter() *VisitorCounter

func (*VisitorCounter) Error

func (v *VisitorCounter) Error() error

func (*VisitorCounter) VisitFile

func (v *VisitorCounter) VisitFile(_ *MyFile)

func (*VisitorCounter) VisitFolder

func (v *VisitorCounter) VisitFolder(fl *MyFolder)

func (*VisitorCounter) VisitTopFolder

func (v *VisitorCounter) VisitTopFolder(fl *MyTopFolder)

type VisitorDump

type VisitorDump struct {
	// contains filtered or unexported fields
}

func NewVisitorDump

func NewVisitorDump(wr io.Writer) *VisitorDump

func (*VisitorDump) Error

func (v *VisitorDump) Error() error

func (*VisitorDump) VisitFile

func (v *VisitorDump) VisitFile(fi *MyFile)

func (*VisitorDump) VisitFolder

func (v *VisitorDump) VisitFolder(fl *MyFolder)

func (*VisitorDump) VisitTopFolder

func (v *VisitorDump) VisitTopFolder(fl *MyTopFolder)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL