Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use option pattern with variadic args for constructors #35

Merged
merged 2 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
on: [push, pull_request]
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]

name: Test

concurrency:
Expand Down
58 changes: 36 additions & 22 deletions backupfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,44 @@ var (
ErrRollbackFailed = errors.New("rollback failed")
)

// Options in order to manipulate the behavior of the BackupFS
type BackupFSOption func(*backupFSOptions)

// New creates a new layered backup file system that backups files from the OS filesystem the backup location in case that an
// existing file in the OS filesystem is about to be overwritten or removed.
// The backup location is hidden from the user's access in order to prevent infinite backup recursions.
// The returned BackupFS is OS-independent and can also be used with Windows paths.
func New(backupLocation string, opts ...BackupFSOption) *BackupFS {
return NewWithFS(NewOSFS(), backupLocation, opts...)
}

// NewWithFS creates a new layered backup file system that backups files from fs to backup in case that an
// existing file in fs is about to be overwritten or removed.
// The backup location is hidden from the user's access i norder to prevent infinite backup recursions.
// The returned BackupFS is OS-independent and can also be used with Windows paths.
func NewWithFS(baseFS FS, backupLocation string, opts ...BackupFSOption) *BackupFS {
fsys := NewBackupFS(
NewHiddenFS(baseFS, backupLocation),
NewPrefixFS(baseFS, backupLocation),
// put our default option first in order for it to be overwritable later
append([]BackupFSOption{WithVolumePaths(true)}, opts...)...,
)
return fsys
}

// NewBackupFS creates a new layered backup file system that backups files from fs to backup in case that an
// existing file in fs is about to be overwritten or removed.
func NewBackupFS(base, backup FS) *BackupFS {
return &BackupFS{
base: base,
backup: backup,
func NewBackupFS(base, backup FS, opts ...BackupFSOption) *BackupFS {
opt := &backupFSOptions{}

// this map is needed in order to keep track of non existing files
// consecutive changes might lead to files being backed up
// that were never there before
// but could have been written by us in the mean time.
// without this structure we would never know whether there was actually
// no previous file to be backed up.
baseInfos: make(map[string]fs.FileInfo),
for _, o := range opts {
o(opt)
}
}

// NewBackupFSWithVolume creates a new layered backup file system that backups files from fs to backup in case that an
// existing file in fs is about to be overwritten or removed.
// Contrary to the normal BackupFS this variant allows to use absolute windows paths (C:\A\B\C instead of \A\B\C)
func NewBackupFSWithVolume(base, backup FS) *BackupFS {
return &BackupFS{
bfsys := &BackupFS{
windowsVolumePaths: opt.allowWindowsVolumePaths,
base: base,
backup: backup,
windowsVolumePaths: true,

// this map is needed in order to keep track of non existing files
// consecutive changes might lead to files being backed up
Expand All @@ -59,6 +72,7 @@ func NewBackupFSWithVolume(base, backup FS) *BackupFS {
// no previous file to be backed up.
baseInfos: make(map[string]fs.FileInfo),
}
return bfsys
}

// BackupFS is a file system abstraction that takes two underlying filesystems.
Expand All @@ -83,13 +97,13 @@ type BackupFS struct {
windowsVolumePaths bool
}

// GetBaseFS returns the fs layer that is being written to
func (fsys *BackupFS) GetBaseFS() FS {
// BaseFS returns the fs layer that is being written to
func (fsys *BackupFS) BaseFS() FS {
return fsys.base
}

// GetBackupFS returns the fs layer that is used to store the backups
func (fsys *BackupFS) GetBackupFS() FS {
// BackupFS returns the fs layer that is used to store the backups
func (fsys *BackupFS) BackupFS() FS {
return fsys.backup
}

Expand Down
13 changes: 13 additions & 0 deletions backupfs_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package backupfs

type backupFSOptions struct {
allowWindowsVolumePaths bool
}

// WithVolumePaths, contrary to the normal BackupFS, this variant allows
// to use absolute windows paths (C:\A\B\C instead of \A\B\C) when set to true.
func WithVolumePaths(allow bool) BackupFSOption {
return func(bf *backupFSOptions) {
bf.allowWindowsVolumePaths = allow
}
}
Loading