From eb67db2fa53f2669ecbf1c4e4b8536fc256d33ba Mon Sep 17 00:00:00 2001 From: Keepers Date: Tue, 29 Nov 2022 11:32:52 -0700 Subject: [PATCH] add a discrete clone method to scopes (#1626) ## Description Adds a method to all scopes that produces a discrete clone of the original scope. The result is a shallow clone of the scope, thus retaining all original values, but is made discrete by replacing the resource owner target with a specific value. ## Type of change - [x] :sunflower: Feature ## Issue(s) * #1621 ## Test Plan - [x] :zap: Unit test --- src/pkg/selectors/exchange.go | 6 +++++ src/pkg/selectors/onedrive.go | 40 +++++++++++++++++------------- src/pkg/selectors/scopes.go | 15 ++++++++++++ src/pkg/selectors/scopes_test.go | 17 +++++++++++++ src/pkg/selectors/sharepoint.go | 42 ++++++++++++++++++-------------- 5 files changed, 85 insertions(+), 35 deletions(-) diff --git a/src/pkg/selectors/exchange.go b/src/pkg/selectors/exchange.go index ca98fefe5..36f01747b 100644 --- a/src/pkg/selectors/exchange.go +++ b/src/pkg/selectors/exchange.go @@ -686,6 +686,12 @@ func (s ExchangeScope) setDefaults() { } } +// DiscreteCopy makes a shallow clone of the scope, then replaces the clone's +// user comparison with only the provided user. +func (s ExchangeScope) DiscreteCopy(user string) ExchangeScope { + return discreteCopy(s, user) +} + // --------------------------------------------------------------------------- // Backup Details Filtering // --------------------------------------------------------------------------- diff --git a/src/pkg/selectors/onedrive.go b/src/pkg/selectors/onedrive.go index 752ebc85f..5859602b3 100644 --- a/src/pkg/selectors/onedrive.go +++ b/src/pkg/selectors/onedrive.go @@ -459,6 +459,29 @@ func (s OneDriveScope) setDefaults() { } } +// DiscreteCopy makes a clone of the scope, then replaces the clone's user comparison +// with only the provided user. +func (s OneDriveScope) DiscreteCopy(user string) OneDriveScope { + return discreteCopy(s, user) +} + +// --------------------------------------------------------------------------- +// Backup Details Filtering +// --------------------------------------------------------------------------- + +// Reduce filters the entries in a details struct to only those that match the +// inclusions, filters, and exclusions in the selector. +func (s oneDrive) Reduce(ctx context.Context, deets *details.Details) *details.Details { + return reduce[OneDriveScope]( + ctx, + deets, + s.Selector, + map[path.CategoryType]oneDriveCategory{ + path.FilesCategory: OneDriveItem, + }, + ) +} + // matchesInfo handles the standard behavior when comparing a scope and an oneDriveInfo // returns true if the scope and info match for the provided category. func (s OneDriveScope) matchesInfo(dii details.ItemInfo) bool { @@ -480,20 +503,3 @@ func (s OneDriveScope) matchesInfo(dii details.ItemInfo) bool { return s.Matches(filterCat, i) } - -// --------------------------------------------------------------------------- -// Backup Details Filtering -// --------------------------------------------------------------------------- - -// Reduce filters the entries in a details struct to only those that match the -// inclusions, filters, and exclusions in the selector. -func (s oneDrive) Reduce(ctx context.Context, deets *details.Details) *details.Details { - return reduce[OneDriveScope]( - ctx, - deets, - s.Selector, - map[path.CategoryType]oneDriveCategory{ - path.FilesCategory: OneDriveItem, - }, - ) -} diff --git a/src/pkg/selectors/scopes.go b/src/pkg/selectors/scopes.go index 291f2657d..8084d73c7 100644 --- a/src/pkg/selectors/scopes.go +++ b/src/pkg/selectors/scopes.go @@ -243,6 +243,21 @@ func set[T scopeT](s T, cat categorizer, v []string, opts ...option) T { return s } +// discreteCopy makes a shallow clone of the scocpe, and sets the resource +// owner filter target in the clone to the provided string. +func discreteCopy[T scopeT](s T, resourceOwner string) T { + clone := T{} + + for k, v := range s { + clone[k] = v + } + + return set( + clone, + clone.categorizer().rootCat(), + []string{resourceOwner}) +} + // returns true if the category is included in the scope's category type, // and the value is set to None(). func isNoneTarget[T scopeT, C categoryT](s T, cat C) bool { diff --git a/src/pkg/selectors/scopes_test.go b/src/pkg/selectors/scopes_test.go index 4670e7ce8..7ef752c33 100644 --- a/src/pkg/selectors/scopes_test.go +++ b/src/pkg/selectors/scopes_test.go @@ -513,3 +513,20 @@ func (suite *SelectorScopesSuite) TestScopeConfig() { }) } } + +func (suite *SelectorScopesSuite) TestDiscreteCopy() { + var ( + t = suite.T() + orig = stubScope(AnyTgt) + clone = discreteCopy(orig, "fnords") + ) + + for k, v := range orig { + if k != rootCatStub.String() { + assert.Equal(t, v.Target, clone[k].Target) + } else { + assert.Equal(t, AnyTgt, v.Target) + assert.Equal(t, "fnords", clone[k].Target) + } + } +} diff --git a/src/pkg/selectors/sharepoint.go b/src/pkg/selectors/sharepoint.go index fb1df33f4..ef7d12a7a 100644 --- a/src/pkg/selectors/sharepoint.go +++ b/src/pkg/selectors/sharepoint.go @@ -407,6 +407,30 @@ func (s SharePointScope) setDefaults() { } } +// DiscreteCopy makes a shallow clone of the scope, then replaces the clone's +// site comparison with only the provided site. +func (s SharePointScope) DiscreteCopy(site string) SharePointScope { + return discreteCopy(s, site) +} + +// --------------------------------------------------------------------------- +// Backup Details Filtering +// --------------------------------------------------------------------------- + +// Reduce filters the entries in a details struct to only those that match the +// inclusions, filters, and exclusions in the selector. +func (s sharePoint) Reduce(ctx context.Context, deets *details.Details) *details.Details { + return reduce[SharePointScope]( + ctx, + deets, + s.Selector, + map[path.CategoryType]sharePointCategory{ + path.LibrariesCategory: SharePointLibraryItem, + // TODO: list category type + }, + ) +} + // matchesInfo handles the standard behavior when comparing a scope and an sharePointInfo // returns true if the scope and info match for the provided category. func (s SharePointScope) matchesInfo(dii details.ItemInfo) bool { @@ -428,21 +452,3 @@ func (s SharePointScope) matchesInfo(dii details.ItemInfo) bool { return s.Matches(filterCat, i) } - -// --------------------------------------------------------------------------- -// Backup Details Filtering -// --------------------------------------------------------------------------- - -// Reduce filters the entries in a details struct to only those that match the -// inclusions, filters, and exclusions in the selector. -func (s sharePoint) Reduce(ctx context.Context, deets *details.Details) *details.Details { - return reduce[SharePointScope]( - ctx, - deets, - s.Selector, - map[path.CategoryType]sharePointCategory{ - path.LibrariesCategory: SharePointLibraryItem, - // TODO: list category type - }, - ) -}