Use short ref during backup (#851)
## Description Short refs allow the user to type less to select an item to restore. This PR * Adds a short ref field to the BackupDetails entries * Populates the short ref field during backup ## Type of change <!--- Please check the type of change your PR introduces: ---> - [x] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Test - [ ] 💻 CI/Deployment - [ ] 🐹 Trivial/Minor ## Issue(s) <!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. --> * #572 ## Test Plan <!-- How will this be tested prior to merging.--> - [ ] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
f8a10b4de6
commit
4cf5fcab5a
@ -278,7 +278,7 @@ func (suite *PreparedBackupExchangeIntegrationSuite) TestExchangeDetailsCmd() {
|
|||||||
|
|
||||||
for i, ent := range deets.Entries {
|
for i, ent := range deets.Entries {
|
||||||
t.Run(fmt.Sprintf("detail %d", i), func(t *testing.T) {
|
t.Run(fmt.Sprintf("detail %d", i), func(t *testing.T) {
|
||||||
assert.Contains(t, result, ent.RepoRef)
|
assert.Contains(t, result, ent.ShortRef)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -56,7 +56,7 @@ func manifestToStats(man *snapshot.Manifest) BackupStats {
|
|||||||
|
|
||||||
type itemDetails struct {
|
type itemDetails struct {
|
||||||
info details.ItemInfo
|
info details.ItemInfo
|
||||||
repoRef string
|
repoPath path.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
type corsoProgress struct {
|
type corsoProgress struct {
|
||||||
@ -89,7 +89,7 @@ func (cp *corsoProgress) FinishedFile(relativePath string, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cp.deets.Add(d.repoRef, d.info)
|
cp.deets.Add(d.repoPath.String(), d.repoPath.ShortRef(), d.info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *corsoProgress) put(k string, v *itemDetails) {
|
func (cp *corsoProgress) put(k string, v *itemDetails) {
|
||||||
@ -192,7 +192,7 @@ func getStreamItemFunc(
|
|||||||
// element. Add to pending set before calling the callback to avoid race
|
// element. Add to pending set before calling the callback to avoid race
|
||||||
// conditions when the item is completed.
|
// conditions when the item is completed.
|
||||||
p := itemPath.PopFront().String()
|
p := itemPath.PopFront().String()
|
||||||
d := &itemDetails{info: ei.Info(), repoRef: itemPath.String()}
|
d := &itemDetails{info: ei.Info(), repoPath: itemPath}
|
||||||
|
|
||||||
progress.put(p, d)
|
progress.put(p, d)
|
||||||
|
|
||||||
|
|||||||
@ -144,8 +144,22 @@ func (suite *CorsoProgressUnitSuite) TestFinishedFile() {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
targetFileName := "testFile"
|
targetFilePath, err := path.Builder{}.Append(
|
||||||
deets := &itemDetails{details.ItemInfo{}, targetFileName}
|
"Inbox",
|
||||||
|
"testFile",
|
||||||
|
).ToDataLayerExchangePathForCategory(
|
||||||
|
testTenant,
|
||||||
|
testUser,
|
||||||
|
path.EmailCategory,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
require.NoError(suite.T(), err)
|
||||||
|
|
||||||
|
relativePath, err := targetFilePath.Dir()
|
||||||
|
require.NoError(suite.T(), err)
|
||||||
|
|
||||||
|
targetFileName := relativePath.String()
|
||||||
|
deets := &itemDetails{details.ItemInfo{}, targetFilePath}
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@ -86,10 +86,14 @@ type Details struct {
|
|||||||
mu sync.Mutex `json:"-"`
|
mu sync.Mutex `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Details) Add(repoRef string, info ItemInfo) {
|
func (d *Details) Add(repoRef, shortRef string, info ItemInfo) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
d.Entries = append(d.Entries, DetailsEntry{RepoRef: repoRef, ItemInfo: info})
|
d.Entries = append(d.Entries, DetailsEntry{
|
||||||
|
RepoRef: repoRef,
|
||||||
|
ShortRef: shortRef,
|
||||||
|
ItemInfo: info,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
@ -101,6 +105,7 @@ type DetailsEntry struct {
|
|||||||
// TODO: `RepoRef` is currently the full path to the item in Kopia
|
// TODO: `RepoRef` is currently the full path to the item in Kopia
|
||||||
// This can be optimized.
|
// This can be optimized.
|
||||||
RepoRef string `json:"repoRef"`
|
RepoRef string `json:"repoRef"`
|
||||||
|
ShortRef string `json:"shortRef"`
|
||||||
ItemInfo
|
ItemInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +125,7 @@ func (de DetailsEntry) MinimumPrintable() any {
|
|||||||
// Headers returns the human-readable names of properties in a DetailsEntry
|
// Headers returns the human-readable names of properties in a DetailsEntry
|
||||||
// for printing out to a terminal in a columnar display.
|
// for printing out to a terminal in a columnar display.
|
||||||
func (de DetailsEntry) Headers() []string {
|
func (de DetailsEntry) Headers() []string {
|
||||||
hs := []string{"Repo Ref"}
|
hs := []string{"Reference"}
|
||||||
|
|
||||||
if de.ItemInfo.Exchange != nil {
|
if de.ItemInfo.Exchange != nil {
|
||||||
hs = append(hs, de.ItemInfo.Exchange.Headers()...)
|
hs = append(hs, de.ItemInfo.Exchange.Headers()...)
|
||||||
@ -139,7 +144,7 @@ func (de DetailsEntry) Headers() []string {
|
|||||||
|
|
||||||
// Values returns the values matching the Headers list.
|
// Values returns the values matching the Headers list.
|
||||||
func (de DetailsEntry) Values() []string {
|
func (de DetailsEntry) Values() []string {
|
||||||
vs := []string{de.RepoRef}
|
vs := []string{de.ShortRef}
|
||||||
|
|
||||||
if de.ItemInfo.Exchange != nil {
|
if de.ItemInfo.Exchange != nil {
|
||||||
vs = append(vs, de.ItemInfo.Exchange.Values()...)
|
vs = append(vs, de.ItemInfo.Exchange.Values()...)
|
||||||
|
|||||||
@ -38,14 +38,16 @@ func (suite *DetailsUnitSuite) TestDetailsEntry_HeadersValues() {
|
|||||||
name: "no info",
|
name: "no info",
|
||||||
entry: details.DetailsEntry{
|
entry: details.DetailsEntry{
|
||||||
RepoRef: "reporef",
|
RepoRef: "reporef",
|
||||||
|
ShortRef: "deadbeef",
|
||||||
},
|
},
|
||||||
expectHs: []string{"Repo Ref"},
|
expectHs: []string{"Reference"},
|
||||||
expectVs: []string{"reporef"},
|
expectVs: []string{"deadbeef"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "exchange event info",
|
name: "exchange event info",
|
||||||
entry: details.DetailsEntry{
|
entry: details.DetailsEntry{
|
||||||
RepoRef: "reporef",
|
RepoRef: "reporef",
|
||||||
|
ShortRef: "deadbeef",
|
||||||
ItemInfo: details.ItemInfo{
|
ItemInfo: details.ItemInfo{
|
||||||
Exchange: &details.ExchangeInfo{
|
Exchange: &details.ExchangeInfo{
|
||||||
ItemType: details.ExchangeEvent,
|
ItemType: details.ExchangeEvent,
|
||||||
@ -56,13 +58,14 @@ func (suite *DetailsUnitSuite) TestDetailsEntry_HeadersValues() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectHs: []string{"Repo Ref", "Organizer", "Subject", "Starts", "Recurring"},
|
expectHs: []string{"Reference", "Organizer", "Subject", "Starts", "Recurring"},
|
||||||
expectVs: []string{"reporef", "organizer", "subject", nowStr, "true"},
|
expectVs: []string{"deadbeef", "organizer", "subject", nowStr, "true"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "exchange contact info",
|
name: "exchange contact info",
|
||||||
entry: details.DetailsEntry{
|
entry: details.DetailsEntry{
|
||||||
RepoRef: "reporef",
|
RepoRef: "reporef",
|
||||||
|
ShortRef: "deadbeef",
|
||||||
ItemInfo: details.ItemInfo{
|
ItemInfo: details.ItemInfo{
|
||||||
Exchange: &details.ExchangeInfo{
|
Exchange: &details.ExchangeInfo{
|
||||||
ItemType: details.ExchangeContact,
|
ItemType: details.ExchangeContact,
|
||||||
@ -70,13 +73,14 @@ func (suite *DetailsUnitSuite) TestDetailsEntry_HeadersValues() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectHs: []string{"Repo Ref", "Contact Name"},
|
expectHs: []string{"Reference", "Contact Name"},
|
||||||
expectVs: []string{"reporef", "contactName"},
|
expectVs: []string{"deadbeef", "contactName"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "exchange mail info",
|
name: "exchange mail info",
|
||||||
entry: details.DetailsEntry{
|
entry: details.DetailsEntry{
|
||||||
RepoRef: "reporef",
|
RepoRef: "reporef",
|
||||||
|
ShortRef: "deadbeef",
|
||||||
ItemInfo: details.ItemInfo{
|
ItemInfo: details.ItemInfo{
|
||||||
Exchange: &details.ExchangeInfo{
|
Exchange: &details.ExchangeInfo{
|
||||||
ItemType: details.ExchangeMail,
|
ItemType: details.ExchangeMail,
|
||||||
@ -86,24 +90,26 @@ func (suite *DetailsUnitSuite) TestDetailsEntry_HeadersValues() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectHs: []string{"Repo Ref", "Sender", "Subject", "Received"},
|
expectHs: []string{"Reference", "Sender", "Subject", "Received"},
|
||||||
expectVs: []string{"reporef", "sender", "subject", nowStr},
|
expectVs: []string{"deadbeef", "sender", "subject", nowStr},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "sharepoint info",
|
name: "sharepoint info",
|
||||||
entry: details.DetailsEntry{
|
entry: details.DetailsEntry{
|
||||||
RepoRef: "reporef",
|
RepoRef: "reporef",
|
||||||
|
ShortRef: "deadbeef",
|
||||||
ItemInfo: details.ItemInfo{
|
ItemInfo: details.ItemInfo{
|
||||||
Sharepoint: &details.SharepointInfo{},
|
Sharepoint: &details.SharepointInfo{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectHs: []string{"Repo Ref"},
|
expectHs: []string{"Reference"},
|
||||||
expectVs: []string{"reporef"},
|
expectVs: []string{"deadbeef"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "oneDrive info",
|
name: "oneDrive info",
|
||||||
entry: details.DetailsEntry{
|
entry: details.DetailsEntry{
|
||||||
RepoRef: "reporef",
|
RepoRef: "reporef",
|
||||||
|
ShortRef: "deadbeef",
|
||||||
ItemInfo: details.ItemInfo{
|
ItemInfo: details.ItemInfo{
|
||||||
OneDrive: &details.OneDriveInfo{
|
OneDrive: &details.OneDriveInfo{
|
||||||
ItemName: "itemName",
|
ItemName: "itemName",
|
||||||
@ -111,8 +117,8 @@ func (suite *DetailsUnitSuite) TestDetailsEntry_HeadersValues() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectHs: []string{"Repo Ref", "ItemName", "ParentPath"},
|
expectHs: []string{"Reference", "ItemName", "ParentPath"},
|
||||||
expectVs: []string{"reporef", "itemName", "parentPath"},
|
expectVs: []string{"deadbeef", "itemName", "parentPath"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user