From 8c281f584a68ec0369774325c43dfbbfd8c31ead Mon Sep 17 00:00:00 2001 From: John Behm Date: Wed, 10 Jul 2024 11:41:21 +0200 Subject: [PATCH 1/2] use option pattern with variadic args for constructors --- backupfs.go | 58 ++++++++++++++++++++++++++++----------------- backupfs_options.go | 13 ++++++++++ 2 files changed, 49 insertions(+), 22 deletions(-) create mode 100644 backupfs_options.go diff --git a/backupfs.go b/backupfs.go index dc50fa8..bbc467e 100644 --- a/backupfs.go +++ b/backupfs.go @@ -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 @@ -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. @@ -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 } diff --git a/backupfs_options.go b/backupfs_options.go new file mode 100644 index 0000000..f38c986 --- /dev/null +++ b/backupfs_options.go @@ -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 + } +} From 1c699248df129b9326232b999ef5924472d02994 Mon Sep 17 00:00:00 2001 From: John Behm Date: Wed, 10 Jul 2024 11:54:59 +0200 Subject: [PATCH 2/2] update ci pipeline --- .github/workflows/test.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f09f0e6..672994b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,4 +1,9 @@ -on: [push, pull_request] +on: + push: + branches: ["master"] + pull_request: + branches: ["master"] + name: Test concurrency: