clean out scope value chaff (#731)
This commit is contained in:
parent
25ce11b2c6
commit
a226035c23
@ -92,7 +92,7 @@ func (b Backup) MinimumPrintable() any {
|
|||||||
StartedAt: b.StartedAt,
|
StartedAt: b.StartedAt,
|
||||||
Status: b.Status,
|
Status: b.Status,
|
||||||
Version: "0",
|
Version: "0",
|
||||||
Selectors: b.Selectors.Printable(),
|
Selectors: b.Selectors.ToPrintable(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +117,6 @@ func (b Backup) Values() []string {
|
|||||||
common.FormatTime(b.StartedAt),
|
common.FormatTime(b.StartedAt),
|
||||||
string(b.ID),
|
string(b.ID),
|
||||||
status,
|
status,
|
||||||
b.Selectors.Printable().Resources(),
|
b.Selectors.ToPrintable().Resources(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,7 +90,7 @@ func (suite *BackupSuite) TestBackup_MinimumPrintable() {
|
|||||||
assert.Equal(t, now, result.StartedAt, "started at")
|
assert.Equal(t, now, result.StartedAt, "started at")
|
||||||
assert.Equal(t, b.Status, result.Status, "status")
|
assert.Equal(t, b.Status, result.Status, "status")
|
||||||
|
|
||||||
bselp := b.Selectors.Printable()
|
bselp := b.Selectors.ToPrintable()
|
||||||
assert.Equal(t, bselp, result.Selectors, "selectors")
|
assert.Equal(t, bselp, result.Selectors, "selectors")
|
||||||
assert.Equal(t, bselp.Resources(), result.Selectors.Resources(), "selector resources")
|
assert.Equal(t, bselp.Resources(), result.Selectors.Resources(), "selector resources")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,6 +80,11 @@ func (s Selector) ToExchangeRestore() (*ExchangeRestore, error) {
|
|||||||
return &src, nil
|
return &src, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Printable creates the minimized display of a selector, formatted for human readability.
|
||||||
|
func (s exchange) Printable() Printable {
|
||||||
|
return toPrintable[ExchangeScope](s.Selector)
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------
|
// -------------------
|
||||||
// Exclude/Includes
|
// Exclude/Includes
|
||||||
|
|
||||||
@ -169,7 +174,7 @@ func (s *exchange) Contacts(users, folders, contacts []string) []ExchangeScope {
|
|||||||
|
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[ExchangeScope](Item, ExchangeContact, users, contacts).
|
makeScope[ExchangeScope](ExchangeContact, users, contacts).
|
||||||
set(ExchangeContactFolder, folders),
|
set(ExchangeContactFolder, folders),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -185,7 +190,7 @@ func (s *exchange) ContactFolders(users, folders []string) []ExchangeScope {
|
|||||||
|
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[ExchangeScope](Group, ExchangeContactFolder, users, folders),
|
makeScope[ExchangeScope](ExchangeContactFolder, users, folders),
|
||||||
)
|
)
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
@ -200,7 +205,7 @@ func (s *exchange) Events(users, calendars, events []string) []ExchangeScope {
|
|||||||
|
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[ExchangeScope](Item, ExchangeEvent, users, events).
|
makeScope[ExchangeScope](ExchangeEvent, users, events).
|
||||||
set(ExchangeEventCalendar, calendars),
|
set(ExchangeEventCalendar, calendars),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -217,7 +222,7 @@ func (s *exchange) EventCalendars(users, events []string) []ExchangeScope {
|
|||||||
|
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[ExchangeScope](Group, ExchangeEventCalendar, users, events),
|
makeScope[ExchangeScope](ExchangeEventCalendar, users, events),
|
||||||
)
|
)
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
@ -232,7 +237,7 @@ func (s *exchange) Mails(users, folders, mails []string) []ExchangeScope {
|
|||||||
|
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[ExchangeScope](Item, ExchangeMail, users, mails).
|
makeScope[ExchangeScope](ExchangeMail, users, mails).
|
||||||
set(ExchangeMailFolder, folders),
|
set(ExchangeMailFolder, folders),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -248,7 +253,7 @@ func (s *exchange) MailFolders(users, folders []string) []ExchangeScope {
|
|||||||
|
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[ExchangeScope](Group, ExchangeMailFolder, users, folders),
|
makeScope[ExchangeScope](ExchangeMailFolder, users, folders),
|
||||||
)
|
)
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
@ -263,9 +268,9 @@ func (s *exchange) Users(users []string) []ExchangeScope {
|
|||||||
scopes := []ExchangeScope{}
|
scopes := []ExchangeScope{}
|
||||||
|
|
||||||
scopes = append(scopes,
|
scopes = append(scopes,
|
||||||
makeScope[ExchangeScope](Group, ExchangeContactFolder, users, Any()),
|
makeScope[ExchangeScope](ExchangeContactFolder, users, Any()),
|
||||||
makeScope[ExchangeScope](Item, ExchangeEventCalendar, users, Any()),
|
makeScope[ExchangeScope](ExchangeEventCalendar, users, Any()),
|
||||||
makeScope[ExchangeScope](Group, ExchangeMailFolder, users, Any()),
|
makeScope[ExchangeScope](ExchangeMailFolder, users, Any()),
|
||||||
)
|
)
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
@ -618,12 +623,6 @@ func (s ExchangeScope) FilterCategory() exchangeCategory {
|
|||||||
return exchangeCategory(getFilterCategory(s))
|
return exchangeCategory(getFilterCategory(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Granularity describes the granularity (directory || item)
|
|
||||||
// of the data in scope.
|
|
||||||
func (s ExchangeScope) Granularity() string {
|
|
||||||
return getGranularity(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IncludeCategory checks whether the scope includes a certain category of data.
|
// IncludeCategory checks whether the scope includes a certain category of data.
|
||||||
// Ex: to check if the scope includes mail data:
|
// Ex: to check if the scope includes mail data:
|
||||||
// s.IncludesCategory(selector.ExchangeMail)
|
// s.IncludesCategory(selector.ExchangeMail)
|
||||||
|
|||||||
@ -88,8 +88,7 @@ func (ms mockScope) matchesEntry(
|
|||||||
func (ms mockScope) setDefaults() {}
|
func (ms mockScope) setDefaults() {}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
shouldMatch = "should-match-entry"
|
shouldMatch = "should-match-entry"
|
||||||
stubResource = "stubResource"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// helper funcs
|
// helper funcs
|
||||||
@ -102,8 +101,6 @@ func stubScope(match string) mockScope {
|
|||||||
return mockScope{
|
return mockScope{
|
||||||
rootCatStub.String(): passAny,
|
rootCatStub.String(): passAny,
|
||||||
scopeKeyCategory: filters.Identity(rootCatStub.String()),
|
scopeKeyCategory: filters.Identity(rootCatStub.String()),
|
||||||
scopeKeyGranularity: filters.Identity(Item),
|
|
||||||
scopeKeyResource: filters.Identity(stubResource),
|
|
||||||
scopeKeyDataType: filters.Identity(rootCatStub.String()),
|
scopeKeyDataType: filters.Identity(rootCatStub.String()),
|
||||||
shouldMatch: filters.Identity(sm),
|
shouldMatch: filters.Identity(sm),
|
||||||
}
|
}
|
||||||
@ -113,15 +110,25 @@ func stubScope(match string) mockScope {
|
|||||||
// selectors
|
// selectors
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
func stubSelector() Selector {
|
type mockSel struct {
|
||||||
return Selector{
|
Selector
|
||||||
Service: ServiceExchange,
|
}
|
||||||
Excludes: []scope{scope(stubScope(""))},
|
|
||||||
Filters: []scope{scope(stubScope(""))},
|
func stubSelector() mockSel {
|
||||||
Includes: []scope{scope(stubScope(""))},
|
return mockSel{
|
||||||
|
Selector: Selector{
|
||||||
|
Service: ServiceExchange,
|
||||||
|
Excludes: []scope{scope(stubScope(""))},
|
||||||
|
Filters: []scope{scope(stubScope(""))},
|
||||||
|
Includes: []scope{scope(stubScope(""))},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s mockSel) Printable() Printable {
|
||||||
|
return toPrintable[mockScope](s.Selector)
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// helper funcs
|
// helper funcs
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@ -46,6 +46,11 @@ func (s Selector) ToOneDriveBackup() (*OneDriveBackup, error) {
|
|||||||
return &src, nil
|
return &src, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Printable creates the minimized display of a selector, formatted for human readability.
|
||||||
|
func (s oneDrive) Printable() Printable {
|
||||||
|
return toPrintable[OneDriveScope](s.Selector)
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------
|
// -------------------
|
||||||
// Scope Factories
|
// Scope Factories
|
||||||
|
|
||||||
@ -113,7 +118,7 @@ func (s *oneDrive) Filter(scopes ...[]OneDriveScope) {
|
|||||||
func (s *oneDrive) Users(users []string) []OneDriveScope {
|
func (s *oneDrive) Users(users []string) []OneDriveScope {
|
||||||
scopes := []OneDriveScope{}
|
scopes := []OneDriveScope{}
|
||||||
|
|
||||||
scopes = append(scopes, makeScope[OneDriveScope](Group, OneDriveUser, users, users))
|
scopes = append(scopes, makeScope[OneDriveScope](OneDriveUser, users, users))
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
@ -238,12 +243,6 @@ func (s OneDriveScope) FilterCategory() oneDriveCategory {
|
|||||||
return oneDriveCategory(getFilterCategory(s))
|
return oneDriveCategory(getFilterCategory(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Granularity describes the granularity (directory || item)
|
|
||||||
// of the data in scope.
|
|
||||||
func (s OneDriveScope) Granularity() string {
|
|
||||||
return getGranularity(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IncludeCategory checks whether the scope includes a
|
// IncludeCategory checks whether the scope includes a
|
||||||
// certain category of data.
|
// certain category of data.
|
||||||
// Ex: to check if the scope includes file data:
|
// Ex: to check if the scope includes file data:
|
||||||
|
|||||||
@ -117,15 +117,12 @@ type (
|
|||||||
|
|
||||||
// makeScope produces a well formatted, typed scope that ensures all base values are populated.
|
// makeScope produces a well formatted, typed scope that ensures all base values are populated.
|
||||||
func makeScope[T scopeT](
|
func makeScope[T scopeT](
|
||||||
granularity string,
|
|
||||||
cat categorizer,
|
cat categorizer,
|
||||||
resources, vs []string,
|
resources, vs []string,
|
||||||
) T {
|
) T {
|
||||||
s := T{
|
s := T{
|
||||||
scopeKeyCategory: filters.Identity(cat.String()),
|
scopeKeyCategory: filters.Identity(cat.String()),
|
||||||
scopeKeyDataType: filters.Identity(cat.leafCat().String()),
|
scopeKeyDataType: filters.Identity(cat.leafCat().String()),
|
||||||
scopeKeyGranularity: filters.Identity(granularity),
|
|
||||||
scopeKeyResource: filters.Identity(join(resources...)),
|
|
||||||
cat.String(): filterize(vs...),
|
cat.String(): filterize(vs...),
|
||||||
cat.rootCat().String(): filterize(resources...),
|
cat.rootCat().String(): filterize(resources...),
|
||||||
}
|
}
|
||||||
@ -141,12 +138,10 @@ func makeFilterScope[T scopeT](
|
|||||||
f func([]string) filters.Filter,
|
f func([]string) filters.Filter,
|
||||||
) T {
|
) T {
|
||||||
return T{
|
return T{
|
||||||
scopeKeyCategory: filters.Identity(cat.String()),
|
scopeKeyCategory: filters.Identity(cat.String()),
|
||||||
scopeKeyDataType: filters.Identity(cat.leafCat().String()),
|
scopeKeyDataType: filters.Identity(cat.leafCat().String()),
|
||||||
scopeKeyGranularity: filters.Identity(Filter),
|
scopeKeyInfoFilter: filters.Identity(filterCat.String()),
|
||||||
scopeKeyInfoFilter: filters.Identity(filterCat.String()),
|
filterCat.String(): f(clean(vs)),
|
||||||
scopeKeyResource: filters.Identity(Filter),
|
|
||||||
filterCat.String(): f(clean(vs)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,11 +174,6 @@ func getFilterCategory[T scopeT](s T) string {
|
|||||||
return s[scopeKeyInfoFilter].Target
|
return s[scopeKeyInfoFilter].Target
|
||||||
}
|
}
|
||||||
|
|
||||||
// getGranularity returns the scope's granularity value.
|
|
||||||
func getGranularity[T scopeT](s T) string {
|
|
||||||
return s[scopeKeyGranularity].Target
|
|
||||||
}
|
|
||||||
|
|
||||||
// getCatValue takes the value of s[cat], split it by the standard
|
// getCatValue takes the value of s[cat], split it by the standard
|
||||||
// delimiter, and returns the slice. If s[cat] is nil, returns
|
// delimiter, and returns the slice. If s[cat] is nil, returns
|
||||||
// None().
|
// None().
|
||||||
@ -203,12 +193,6 @@ func set[T scopeT](s T, cat categorizer, v []string) T {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// granularity describes the granularity (directory || item)
|
|
||||||
// of the data in scope.
|
|
||||||
func granularity[T scopeT](s T) string {
|
|
||||||
return s[scopeKeyGranularity].Target
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns true if the category is included in the scope's category type,
|
// returns true if the category is included in the scope's category type,
|
||||||
// and the value is set to Any().
|
// and the value is set to Any().
|
||||||
func isAnyTarget[T scopeT, C categoryT](s T, cat C) bool {
|
func isAnyTarget[T scopeT, C categoryT](s T, cat C) bool {
|
||||||
|
|||||||
@ -110,12 +110,6 @@ func (suite *SelectorScopesSuite) TestGetCatValue() {
|
|||||||
assert.Equal(t, None(), getCatValue(stub, leafCatStub))
|
assert.Equal(t, None(), getCatValue(stub, leafCatStub))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SelectorScopesSuite) TestGranularity() {
|
|
||||||
t := suite.T()
|
|
||||||
stub := stubScope("")
|
|
||||||
assert.Equal(t, Item, granularity(stub))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *SelectorScopesSuite) TestIsAnyTarget() {
|
func (suite *SelectorScopesSuite) TestIsAnyTarget() {
|
||||||
t := suite.T()
|
t := suite.T()
|
||||||
stub := stubScope("")
|
stub := stubScope("")
|
||||||
@ -125,13 +119,13 @@ func (suite *SelectorScopesSuite) TestIsAnyTarget() {
|
|||||||
|
|
||||||
var reduceTestTable = []struct {
|
var reduceTestTable = []struct {
|
||||||
name string
|
name string
|
||||||
sel func() Selector
|
sel func() mockSel
|
||||||
expectLen int
|
expectLen int
|
||||||
expectPasses assert.BoolAssertionFunc
|
expectPasses assert.BoolAssertionFunc
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "include all",
|
name: "include all",
|
||||||
sel: func() Selector {
|
sel: func() mockSel {
|
||||||
sel := stubSelector()
|
sel := stubSelector()
|
||||||
sel.Filters = nil
|
sel.Filters = nil
|
||||||
sel.Excludes = nil
|
sel.Excludes = nil
|
||||||
@ -142,7 +136,7 @@ var reduceTestTable = []struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "include none",
|
name: "include none",
|
||||||
sel: func() Selector {
|
sel: func() mockSel {
|
||||||
sel := stubSelector()
|
sel := stubSelector()
|
||||||
sel.Includes[0] = scope(stubScope("none"))
|
sel.Includes[0] = scope(stubScope("none"))
|
||||||
sel.Filters = nil
|
sel.Filters = nil
|
||||||
@ -154,7 +148,7 @@ var reduceTestTable = []struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "filter and include all",
|
name: "filter and include all",
|
||||||
sel: func() Selector {
|
sel: func() mockSel {
|
||||||
sel := stubSelector()
|
sel := stubSelector()
|
||||||
sel.Excludes = nil
|
sel.Excludes = nil
|
||||||
return sel
|
return sel
|
||||||
@ -164,7 +158,7 @@ var reduceTestTable = []struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "include all filter none",
|
name: "include all filter none",
|
||||||
sel: func() Selector {
|
sel: func() mockSel {
|
||||||
sel := stubSelector()
|
sel := stubSelector()
|
||||||
sel.Filters[0] = scope(stubScope("none"))
|
sel.Filters[0] = scope(stubScope("none"))
|
||||||
sel.Excludes = nil
|
sel.Excludes = nil
|
||||||
@ -175,7 +169,7 @@ var reduceTestTable = []struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "include all exclude all",
|
name: "include all exclude all",
|
||||||
sel: func() Selector {
|
sel: func() mockSel {
|
||||||
sel := stubSelector()
|
sel := stubSelector()
|
||||||
sel.Filters = nil
|
sel.Filters = nil
|
||||||
return sel
|
return sel
|
||||||
@ -185,7 +179,7 @@ var reduceTestTable = []struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "include all exclude none",
|
name: "include all exclude none",
|
||||||
sel: func() Selector {
|
sel: func() mockSel {
|
||||||
sel := stubSelector()
|
sel := stubSelector()
|
||||||
sel.Filters = nil
|
sel.Filters = nil
|
||||||
sel.Excludes[0] = scope(stubScope("none"))
|
sel.Excludes[0] = scope(stubScope("none"))
|
||||||
@ -196,7 +190,7 @@ var reduceTestTable = []struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "filter all exclude all",
|
name: "filter all exclude all",
|
||||||
sel: func() Selector {
|
sel: func() mockSel {
|
||||||
sel := stubSelector()
|
sel := stubSelector()
|
||||||
sel.Includes = nil
|
sel.Includes = nil
|
||||||
return sel
|
return sel
|
||||||
@ -206,7 +200,7 @@ var reduceTestTable = []struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "filter all exclude none",
|
name: "filter all exclude none",
|
||||||
sel: func() Selector {
|
sel: func() mockSel {
|
||||||
sel := stubSelector()
|
sel := stubSelector()
|
||||||
sel.Includes = nil
|
sel.Includes = nil
|
||||||
sel.Excludes[0] = scope(stubScope("none"))
|
sel.Excludes[0] = scope(stubScope("none"))
|
||||||
@ -234,7 +228,7 @@ func (suite *SelectorScopesSuite) TestReduce() {
|
|||||||
for _, test := range reduceTestTable {
|
for _, test := range reduceTestTable {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
ds := deets()
|
ds := deets()
|
||||||
result := reduce[mockScope](&ds, test.sel(), dataCats)
|
result := reduce[mockScope](&ds, test.sel().Selector, dataCats)
|
||||||
require.NotNil(t, result)
|
require.NotNil(t, result)
|
||||||
assert.Len(t, result.Entries, test.expectLen)
|
assert.Len(t, result.Entries, test.expectLen)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -22,20 +22,9 @@ const (
|
|||||||
var ErrorBadSelectorCast = errors.New("wrong selector service type")
|
var ErrorBadSelectorCast = errors.New("wrong selector service type")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
scopeKeyCategory = "category"
|
scopeKeyCategory = "category"
|
||||||
scopeKeyGranularity = "granularity"
|
scopeKeyInfoFilter = "info_filter"
|
||||||
scopeKeyInfoFilter = "info_filter"
|
scopeKeyDataType = "type"
|
||||||
scopeKeyResource = "resource"
|
|
||||||
scopeKeyDataType = "type"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The granularity exprerssed by the scope. Groups imply non-item granularity,
|
|
||||||
// such as a directory. Items are individual files or objects.
|
|
||||||
// Filters are properties that search over service-specific info
|
|
||||||
const (
|
|
||||||
Group = "group"
|
|
||||||
Item = "item"
|
|
||||||
Filter = "filter"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The granularity exprerssed by the scope. Groups imply non-item granularity,
|
// The granularity exprerssed by the scope. Groups imply non-item granularity,
|
||||||
@ -191,23 +180,43 @@ type Printable struct {
|
|||||||
Includes map[string][]string `json:"includes,omitempty"`
|
Includes map[string][]string `json:"includes,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Printable is the minimized display of a selector, formatted for human readability.
|
// ToPrintable creates the minimized display of a selector, formatted for human readability.
|
||||||
// This transformer assumes that the scopeKeyResource and scopeKeyDataType have been
|
func (s Selector) ToPrintable() Printable {
|
||||||
// added to all scopes as they were created. It is unable to infer resource or data
|
switch s.Service {
|
||||||
// type values from existing scope values.
|
case ServiceExchange:
|
||||||
func (s Selector) Printable() Printable {
|
r, err := s.ToExchangeRestore()
|
||||||
|
if err != nil {
|
||||||
|
return Printable{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.Printable()
|
||||||
|
|
||||||
|
case ServiceOneDrive:
|
||||||
|
r, err := s.ToOneDriveBackup()
|
||||||
|
if err != nil {
|
||||||
|
return Printable{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.Printable()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Printable{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// toPrintable creates the minimized display of a selector, formatted for human readability.
|
||||||
|
func toPrintable[T scopeT](s Selector) Printable {
|
||||||
return Printable{
|
return Printable{
|
||||||
Service: s.Service.String(),
|
Service: s.Service.String(),
|
||||||
Excludes: toResourceTypeMap(s.Excludes),
|
Excludes: toResourceTypeMap[T](s.Excludes),
|
||||||
Filters: toResourceTypeMap(s.Filters),
|
Filters: toResourceTypeMap[T](s.Filters),
|
||||||
Includes: toResourceTypeMap(s.Includes),
|
Includes: toResourceTypeMap[T](s.Includes),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resources generates a tabular-readable output of the resources in Printable.
|
// Resources generates a tabular-readable output of the resources in Printable.
|
||||||
// Only the first (arbitrarily picked) resource is displayed. All others are
|
// Only the first (arbitrarily picked) resource is displayed. All others are
|
||||||
// simply counted. If no inclusions exist, uses Filters. If no filters exist,
|
// simply counted. If no inclusions exist, uses Filters. If no filters exist,
|
||||||
// defaults to "All".
|
// defaults to "None".
|
||||||
// Resource refers to the top-level entity in the service. User for Exchange,
|
// Resource refers to the top-level entity in the service. User for Exchange,
|
||||||
// Site for sharepoint, etc.
|
// Site for sharepoint, etc.
|
||||||
func (p Printable) Resources() string {
|
func (p Printable) Resources() string {
|
||||||
@ -217,7 +226,7 @@ func (p Printable) Resources() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
s = "All"
|
s = "None"
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
@ -243,22 +252,23 @@ func resourcesShortFormat(m map[string][]string) string {
|
|||||||
// Transforms the slice to a single map.
|
// Transforms the slice to a single map.
|
||||||
// Keys are each map's scopeKeyResource value.
|
// Keys are each map's scopeKeyResource value.
|
||||||
// Values are the set of all scopeKeyDataTypes for a given resource.
|
// Values are the set of all scopeKeyDataTypes for a given resource.
|
||||||
func toResourceTypeMap(ms []scope) map[string][]string {
|
func toResourceTypeMap[T scopeT](s []scope) map[string][]string {
|
||||||
if len(ms) == 0 {
|
if len(s) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
r := make(map[string][]string)
|
r := make(map[string][]string)
|
||||||
|
|
||||||
for _, m := range ms {
|
for _, sc := range s {
|
||||||
res := m[scopeKeyResource]
|
t := T(sc)
|
||||||
|
res := sc[t.categorizer().rootCat().String()]
|
||||||
k := res.Target
|
k := res.Target
|
||||||
|
|
||||||
if res.Target == AnyTgt {
|
if res.Target == AnyTgt {
|
||||||
k = All
|
k = All
|
||||||
}
|
}
|
||||||
|
|
||||||
r[k] = addToSet(r[k], split(m[scopeKeyDataType].Target))
|
r[k] = addToSet(r[k], split(sc[scopeKeyDataType].Target))
|
||||||
}
|
}
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|||||||
@ -53,13 +53,21 @@ func (suite *SelectorSuite) TestPrintable_IncludedResources() {
|
|||||||
p := sel.Printable()
|
p := sel.Printable()
|
||||||
res := p.Resources()
|
res := p.Resources()
|
||||||
|
|
||||||
assert.Equal(t, stubResource, res, "resource should state only the stub")
|
assert.Equal(t, "All", res, "stub starts out as an all-pass")
|
||||||
|
|
||||||
|
stubWithResource := func(resource string) scope {
|
||||||
|
ss := stubScope("")
|
||||||
|
ss[rootCatStub.String()] = filterize(resource)
|
||||||
|
|
||||||
|
return scope(ss)
|
||||||
|
}
|
||||||
|
|
||||||
sel.Includes = []scope{
|
sel.Includes = []scope{
|
||||||
scope(stubScope("")),
|
stubWithResource("foo"),
|
||||||
{scopeKeyResource: filterize("smarf"), scopeKeyDataType: filterize(unknownCatStub.String())},
|
stubWithResource("smarf"),
|
||||||
{scopeKeyResource: filterize("smurf"), scopeKeyDataType: filterize(unknownCatStub.String())},
|
stubWithResource("fnords"),
|
||||||
}
|
}
|
||||||
|
|
||||||
p = sel.Printable()
|
p = sel.Printable()
|
||||||
res = p.Resources()
|
res = p.Resources()
|
||||||
|
|
||||||
@ -68,12 +76,12 @@ func (suite *SelectorSuite) TestPrintable_IncludedResources() {
|
|||||||
p.Includes = nil
|
p.Includes = nil
|
||||||
res = p.Resources()
|
res = p.Resources()
|
||||||
|
|
||||||
assert.Equal(t, stubResource, res, "resource on filters should state only the stub")
|
assert.Equal(t, "All", res, "filters is also an all-pass")
|
||||||
|
|
||||||
p.Filters = nil
|
p.Filters = nil
|
||||||
res = p.Resources()
|
res = p.Resources()
|
||||||
|
|
||||||
assert.Equal(t, "All", res, "resource with no Includes or Filters should state All")
|
assert.Equal(t, "None", res, "resource with no Includes or Filters should state None")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SelectorSuite) TestToResourceTypeMap() {
|
func (suite *SelectorSuite) TestToResourceTypeMap() {
|
||||||
@ -86,7 +94,7 @@ func (suite *SelectorSuite) TestToResourceTypeMap() {
|
|||||||
name: "single scope",
|
name: "single scope",
|
||||||
input: []scope{scope(stubScope(""))},
|
input: []scope{scope(stubScope(""))},
|
||||||
expect: map[string][]string{
|
expect: map[string][]string{
|
||||||
stubResource: {rootCatStub.String()},
|
"All": {rootCatStub.String()},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -94,13 +102,13 @@ func (suite *SelectorSuite) TestToResourceTypeMap() {
|
|||||||
input: []scope{
|
input: []scope{
|
||||||
scope(stubScope("")),
|
scope(stubScope("")),
|
||||||
{
|
{
|
||||||
scopeKeyResource: filterize("smarf"),
|
rootCatStub.String(): filterize("smarf"),
|
||||||
scopeKeyDataType: filterize(unknownCatStub.String()),
|
scopeKeyDataType: filterize(unknownCatStub.String()),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expect: map[string][]string{
|
expect: map[string][]string{
|
||||||
stubResource: {rootCatStub.String()},
|
"All": {rootCatStub.String()},
|
||||||
"smarf": {unknownCatStub.String()},
|
"smarf": {unknownCatStub.String()},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -108,18 +116,18 @@ func (suite *SelectorSuite) TestToResourceTypeMap() {
|
|||||||
input: []scope{
|
input: []scope{
|
||||||
scope(stubScope("")),
|
scope(stubScope("")),
|
||||||
{
|
{
|
||||||
scopeKeyResource: filterize(stubResource),
|
rootCatStub.String(): filterize(AnyTgt),
|
||||||
scopeKeyDataType: filterize("other"),
|
scopeKeyDataType: filterize("other"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expect: map[string][]string{
|
expect: map[string][]string{
|
||||||
stubResource: {rootCatStub.String(), "other"},
|
"All": {rootCatStub.String(), "other"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
rtm := toResourceTypeMap(test.input)
|
rtm := toResourceTypeMap[mockScope](test.input)
|
||||||
assert.Equal(t, test.expect, rtm)
|
assert.Equal(t, test.expect, rtm)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user