seanchai

package module
v0.19.1 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: BSD-3-Clause-Clear Imports: 9 Imported by: 0

README

Seanchai

Go Reference

A small thread-safe rollback scope for explicitly managing filesystem rollback in Go.

Seanchai lets you record filesystem states and rollback actions so that operations can be safely reverted if they fail. Changes are only kept when the scope is committed.

Seanchai does not automatically track filesystem modifications. Instead, it provides a lightweight mechanism for recording what should happen during rollback.

The name comes from seanchai (Irish: storyteller/keeper of history), reflecting the library's purpose of remembering previous filesystem state so it can be restored later.

Installation

go get codeberg.org/its-astro/seanchai

Usage

A typical pattern is to create a scope, register rollback actions before making changes, and commit when all operations succeed.

scope := seanchai.New()
defer scope.Close()

// Register what should happen if rollback is needed.
err := scope.RemoveOnRollback(
    "temporary-file",
    "/path/to/file",
)
if err != nil {
    return err
}

// Perform operations that may fail...

scope.Commit()
return nil

If Commit() is not called, Close() will execute the registered rollback actions.

Restoring existing files

For files that already exist and will be modified, use a restore node.

scope := seanchai.New()
defer scope.Close()

// Save the current state as the rollback point.
err := scope.RestoreOnRollback(
    "config",
    "/etc/myapp/config.yaml",
)
if err != nil {
    return err
}

// Modify config.yaml...

scope.Commit()

If the operation fails, the original file contents are restored.

Updating restore points

Restore states can be updated as work progresses.

scope.UpdateRestoreState("config")

This replaces the saved rollback state with the file's current contents.

This is useful for staged operations where an intermediate state should become the new recovery point.

Example:

Initial state
      |
RestoreOnRollback()
      |
Stage 1 changes
      |
UpdateRestoreState()
      |
Stage 2 changes
      |
Rollback restores Stage 1 state

Rollback actions

Seanchai supports two types of rollback actions:

Action Behavior
Remove Deletes a file or directory (recursively) during rollback
Restore Restores a file to a previously saved state

Important behavior

Seanchai only knows about rollback actions that are explicitly registered.

For example:

RestoreOnRollback(file)

Another process modifies file

Rollback()

The other process's changes may be overwritten because rollback restores the saved state without knowing about external modifications.

Avoid modifying the same filesystem paths from unrelated operations or multiple rollback scopes while a scope is active unless overwriting those changes is acceptable.

Thread safety

Seanchai scopes are thread-safe. Multiple goroutines can safely interact with the same scope.

This does not provide synchronization for the underlying filesystem. Concurrent changes to the same files can still conflict.

Design

Seanchai intentionally has a small API and uses standard library filesystem operations.

It provides a lightweight mechanism for recording filesystem states and rollback actions. It does not provide filesystem transactions, automatic change tracking, locking, or conflict resolution.

Callers are responsible for ensuring that registered paths are not modified unexpectedly while a rollback scope is active.

Versioning

Seanchai follows Universal Versioning.

License

BSD 3-Clause License

Documentation

Overview

Package seanchai provides a thread-safe rollback scope for explicitly registering filesystem rollback actions.

A scope records restore points and removal actions that are executed when the scope is closed without being committed. Seanchai does not monitor filesystem changes automatically; callers are responsible for registering rollback actions before modifying affected paths.

Index

Constants

View Source
const (
	OpRestore = iota
	OpRemove
)

Variables

View Source
var (
	ErrPathAlreadySeen      = errors.New("path already seen")
	ErrChangeNotFound       = errors.New("change not found")
	ErrIdAlreadySeen        = errors.New("id already seen")
	ErrInvalidKind          = errors.New("invalid kind")
	ErrUnsupportedHardLink  = errors.New("unsupported hard link")
	ErrUnsupportedDirectory = errors.New("unsupported directory")
)

Functions

This section is empty.

Types

type ChangeError

type ChangeError struct {
	Path      []string
	Err       error
	ID        string
	Operation Operation
}

func (*ChangeError) Error

func (e *ChangeError) Error() string

func (*ChangeError) Unwrap

func (e *ChangeError) Unwrap() error

type Operation

type Operation uint8

type RemoveOption

type RemoveOption func(*removeConfig)

func WithRecursive

func WithRecursive() RemoveOption

type RollbackError

type RollbackError struct {
	SuccessfulRollbacks int
	TotalRollbacks      int
	ErrorList           []ChangeError
}

func (*RollbackError) Error

func (e *RollbackError) Error() string

func (*RollbackError) Unwrap

func (e *RollbackError) Unwrap() []error

type Seanchai

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

func New

func New() *Seanchai

New creates a new rollback scope.

Rollback actions can be registered with the scope before performing filesystem operations. If the scope is closed without being committed, all registered rollback actions are executed.

Seanchai does not track filesystem changes automatically. Any changes made to registered paths outside of the scope's registered actions may be overwritten during rollback.

func (*Seanchai) Close

func (s *Seanchai) Close() error

Close closes the rollback scope.

If the scope has not been committed, all registered rollback actions are executed. If rollback fails, Close returns a *RollbackError and the filesystem may be left partially rolled back.

The caller is responsible for handling rollback failures.

func (*Seanchai) Commit

func (s *Seanchai) Commit()

Commit marks the scope as successful and prevents rollback when Close is called.

After Commit returns, closing the scope will only clean up internal state and temporary files. Registered rollback actions will not be executed.

func (*Seanchai) RemoveChange

func (s *Seanchai) RemoveChange(id string) error

RemoveChange removes a registered rollback action from the scope.

After removal, the action will no longer be executed during rollback.

Returns ErrChangeNotFound if no rollback action exists with the given id.

func (*Seanchai) RemoveOnRollback

func (s *Seanchai) RemoveOnRollback(id, path string, opts ...RemoveOption) error

RemoveOnRollback registers a path to be removed if the scope is rolled back.

The path must exist when this function is called. If rollback occurs, the path is removed.

By default, directories are only removed if they are empty. To recursively remove directories and their contents, pass WithRecursive. Recursive removal is destructive and may permanently delete data that cannot be restored by the rollback scope.

The id and path must be unique within the scope.

func (*Seanchai) RestoreOnRollback

func (s *Seanchai) RestoreOnRollback(id, path string) error

RestoreOnRollback records the current state of a file so it can be restored if the scope is rolled back.

The file contents, permissions, and symbolic link target (if applicable) are saved when this function is called. If rollback occurs, the file is replaced with the saved state.

Hard links and directories are not supported and will return an error.

This function must be called before modifying the file.

The id and path must be unique within the scope.

func (*Seanchai) UpdateRestoreState

func (s *Seanchai) UpdateRestoreState(id string) error

UpdateRestoreState replaces the saved rollback state for a restore action with the file's current state.

This allows a caller to create staged rollback points during a larger operation. The change must already exist and must have been registered with RestoreOnRollback.

Hard links and directories are not supported and will return an error.

The updated state will be restored if the scope is later rolled back.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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