Don't display folders in restore output (#3414)

#### Does this PR need a docs update or release note?

- [x]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [ ]  No

#### Type of change

- [ ] 🌻 Feature
- [x] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup

#### Issue(s)

* closes #3281

#### Test Plan

- [x] 💪 Manual
- [ ]  Unit test
- [ ] 💚 E2E
This commit is contained in:
ashmrtn 2023-05-15 16:28:04 -07:00 committed by GitHub
parent ecb1fdc40a
commit 04a30ac662
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 12 deletions

View File

@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Refined oneDrive rate limiter controls to reduce throttling errors.
- Fix handling of duplicate folders at the same hierarchy level in Exchange. Duplicate folders will be merged during restore operations.
- Fix backup for mailboxes that has used up all their storage quota
- Restored folders no longer appear in the Restore results. Only restored items will be displayed.
### Known Issues
- Restore operations will merge duplicate Exchange folders at the same hierarchy level into a single folder.

View File

@ -116,7 +116,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
return Only(ctx, clues.Wrap(err, "Failed to run Exchange restore"))
}
ds.PrintEntries(ctx)
ds.Items().PrintEntries(ctx)
return nil
}

View File

@ -117,7 +117,7 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error {
return Only(ctx, clues.Wrap(err, "Failed to run OneDrive restore"))
}
ds.PrintEntries(ctx)
ds.Items().PrintEntries(ctx)
return nil
}

View File

@ -122,7 +122,7 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error {
return Only(ctx, clues.Wrap(err, "Failed to run SharePoint restore"))
}
ds.PrintEntries(ctx)
ds.Items().PrintEntries(ctx)
return nil
}

View File

@ -139,25 +139,36 @@ type DetailsModel struct {
// Print writes the DetailModel Entries to StdOut, in the format
// requested by the caller.
func (dm DetailsModel) PrintEntries(ctx context.Context) {
printEntries(ctx, dm.Entries)
}
type infoer interface {
Entry | *Entry
// Need this here so we can access the infoType function without a type
// assertion. See https://stackoverflow.com/a/71378366 for more details.
infoType() ItemType
}
func printEntries[T infoer](ctx context.Context, entries []T) {
if print.DisplayJSONFormat() {
printJSON(ctx, dm)
printJSON(ctx, entries)
} else {
printTable(ctx, dm)
printTable(ctx, entries)
}
}
func printTable(ctx context.Context, dm DetailsModel) {
func printTable[T infoer](ctx context.Context, entries []T) {
perType := map[ItemType][]print.Printable{}
for _, de := range dm.Entries {
it := de.infoType()
for _, ent := range entries {
it := ent.infoType()
ps, ok := perType[it]
if !ok {
ps = []print.Printable{}
}
perType[it] = append(ps, print.Printable(de))
perType[it] = append(ps, print.Printable(ent))
}
for _, ps := range perType {
@ -165,10 +176,10 @@ func printTable(ctx context.Context, dm DetailsModel) {
}
}
func printJSON(ctx context.Context, dm DetailsModel) {
func printJSON[T infoer](ctx context.Context, entries []T) {
ents := []print.Printable{}
for _, ent := range dm.Entries {
for _, ent := range entries {
ents = append(ents, print.Printable(ent))
}
@ -194,7 +205,7 @@ func (dm DetailsModel) Paths() []string {
// Items returns a slice of *ItemInfo that does not contain any FolderInfo
// entries. Required because not all folders in the details are valid resource
// paths, and we want to slice out metadata.
func (dm DetailsModel) Items() []*Entry {
func (dm DetailsModel) Items() entrySet {
res := make([]*Entry, 0, len(dm.Entries))
for i := 0; i < len(dm.Entries); i++ {
@ -457,6 +468,13 @@ func withoutMetadataSuffix(id string) string {
// Entry
// --------------------------------------------------------------------------------
// Add a new type so we can transparently use PrintAll in different situations.
type entrySet []*Entry
func (ents entrySet) PrintEntries(ctx context.Context) {
printEntries(ctx, ents)
}
// Entry describes a single item stored in a Backup
type Entry struct {
// RepoRef is the full storage path of the item in Kopia