plainfs

package
v0.59.2 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package plainfs writes, reads, renames and removes files and folders inside a project folder only as plain files in plain folders.

A project folder may have been cloned from someone else, so nothing below it can be trusted to be what it looks like: a command writes only plain files in plain folders of the project, and does not write through a link. Every method of a Tree takes a path inside the project folder (the root of the tree, trusted as the person gave it), walks from the root down to the path with Lstat, and refuses a folder that is a link or is not a plain folder, and a target that exists and is not a plain file. A file is opened so that a link put in its place after the check is not followed where the platform has O_NOFOLLOW (every Unix); on Windows, which has none, the Lstat check alone applies, and it also refuses a junction. A rename lands only on a path that was checked the same way.

A refusal wraps ErrNotPlain and names the path inside the project; it never says where a link leads. Every error of the operating system is returned, without the absolute path it carries.

This is the one walk of the CLI. datatug-core's file store has the same rule for what it writes (its helper is internal to that module), and the commands that write into a project without the store use this one.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotPlain = errors.New("not a plain file or folder of the project")

ErrNotPlain is wrapped by every refusal: a path outside the project, a link, or an entry of another kind where a plain file or folder is needed.

Functions

This section is empty.

Types

type File

type File interface {
	io.ReadWriteCloser
}

File is an opened file.

type Ops

type Ops struct {
	Lstat     func(name string) (fs.FileInfo, error)
	Mkdir     func(name string, perm fs.FileMode) error
	Remove    func(name string) error
	RemoveAll func(name string) error
	Rename    func(oldpath, newpath string) error
	OpenFile  func(name string, flag int, perm fs.FileMode) (File, error)

	// AfterCheck, when it is set, runs between the Lstat of a file and the open of it: a test
	// uses it to put a link in the file's place at exactly that moment.
	AfterCheck func(name string)
}

Ops are the calls of the operating system that a Tree makes, so that a test can inject the failures and the entries (a link on a platform that cannot make one) that a real folder cannot produce on demand. OSOps has the real ones.

func OSOps

func OSOps() Ops

OSOps is the real operating system.

type Tree

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

A Tree is a project folder and how to change it. The project folder is trusted as it was given (it may itself be a link: that is the person's to choose); everything below it is not.

func New

func New(root string, folderPerm fs.FileMode) Tree

New is the project folder root, whose folders are made with folderPerm.

func NewWithOps

func NewWithOps(root string, folderPerm fs.FileMode, ops Ops) Tree

NewWithOps is New with other calls of the operating system, for a test.

func (Tree) CheckFolders

func (t Tree) CheckFolders(dir string) (found bool, err error)

CheckFolders is whether dir, which must be the project folder or inside it, is there, and an error when a folder of the way down to it is a link or is not a plain folder. It makes nothing. A folder that is not there is not a link: found is false and there is no error.

func (Tree) MakeFolders

func (t Tree) MakeFolders(dir string) (made []string, err error)

MakeFolders is MkdirAll that returns the folders it made, outermost first, as full paths. When it fails it returns the ones it made before, so that the caller can take them back.

func (Tree) MkdirAll

func (t Tree) MkdirAll(dir string) error

MkdirAll makes dir, which must be the project folder or inside it, and every missing folder between them, refusing any existing one that is not a plain folder.

func (Tree) ReadFile

func (t Tree) ReadFile(path string) ([]byte, error)

ReadFile reads the file at path, which must be inside the project folder, without following a link: a link, or a folder or anything else that is not a plain file, is refused. A file that is not there, or a folder above it that is not there, is an error that is fs.ErrNotExist.

func (Tree) Remove

func (t Tree) Remove(path string) error

Remove deletes the plain file at path, which must be inside the project folder. A file that is not there, or a folder above it that is not there, is not an error.

func (Tree) RemoveAll

func (t Tree) RemoveAll(dir string) error

RemoveAll deletes the plain folder dir, which must be inside the project folder, with everything in it. A folder that is not there is not an error; the project folder itself is never removed.

func (Tree) RemoveEmptyFolder

func (t Tree) RemoveEmptyFolder(dir string) error

RemoveEmptyFolder deletes the plain folder dir, which must be inside the project folder, when nothing is in it. A folder that is not there is not an error, and a folder that holds something is left as it is: it is somebody else's now.

func (Tree) Rename

func (t Tree) Rename(from, to string) error

Rename moves the plain file from to the path to, both inside the project folder: the folders above each must be plain folders that are there, the file must be there and be a plain file, and to must be a plain file or not be there. A rename lands only on a checked path.

func (Tree) WriteFile

func (t Tree) WriteFile(path string, data []byte, perm fs.FileMode) error

WriteFile writes data to the file at path, which must be inside the project folder: it makes the missing folders above it, refuses a target that exists and is not a plain file, and creates or truncates the file without following a link. It returns the error of the write, or else the error of the close.

Jump to

Keyboard shortcuts

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