feat(backup): add random suffix for resources with the same name

This commit is contained in:
Denis Gukov 2024-02-10 18:21:39 +05:00
parent 1fd655258a
commit 813358b266
2 changed files with 99 additions and 1 deletions

View File

@ -2,8 +2,8 @@ package project
import ( import (
"fmt" "fmt"
"github.com/ansible-semaphore/semaphore/db" "github.com/ansible-semaphore/semaphore/db"
"math/rand"
) )
func findNameByID[T db.BackupEntity](ID int, items []T) (*string, error) { func findNameByID[T db.BackupEntity](ID int, items []T) (*string, error) {
@ -46,6 +46,55 @@ func getScheduleByTemplate(templateID int, schedules []db.Schedule) *string {
return nil return nil
} }
func getRandomName(name string) string {
const chars = "abcdefghijklmnopqrstuvwxyz0123456789"
suffix := ""
for i := 0; i < 10; i++ {
index := rand.Intn(len(chars))
suffix += chars[index : index+1]
}
return name + " - " + suffix
}
func makeUniqueNames[T any](items []T, getter func(item *T) string, setter func(item *T, name string)) {
for i := len(items) - 1; i >= 0; i-- {
for k, other := range items {
if k == i {
break
}
name := getter(&items[i])
if name == getter(&other) {
randomName := getRandomName(name)
setter(&items[i], randomName)
break
}
}
}
}
func (b *BackupDB) makeUniqueNames() {
makeUniqueNames(b.templates, func(item *db.Template) string {
return item.Name
}, func(item *db.Template, name string) {
item.Name = name
})
makeUniqueNames(b.repositories, func(item *db.Repository) string {
return item.Name
}, func(item *db.Repository, name string) {
item.Name = name
})
makeUniqueNames(b.keys, func(item *db.AccessKey) string {
return item.Name
}, func(item *db.AccessKey, name string) {
item.Name = name
})
}
func (b *BackupDB) new(projectID int, store db.Store) (*BackupDB, error) { func (b *BackupDB) new(projectID int, store db.Store) (*BackupDB, error) {
var err error var err error
@ -87,6 +136,9 @@ func (b *BackupDB) new(projectID int, store db.Store) (*BackupDB, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
b.makeUniqueNames()
return b, nil return b, nil
} }

View File

@ -0,0 +1,46 @@
package project
import (
"testing"
)
type testItem struct {
Name string
}
func isUnique(items []testItem) bool {
for i, item := range items {
for k, other := range items {
if i == k {
continue
}
if item.Name == other.Name {
return false
}
}
}
return true
}
func TestMakeUniqueNames(t *testing.T) {
items := []testItem{
{Name: "Project"},
{Name: "Solution"},
{Name: "Project"},
{Name: "Project"},
{Name: "Project"},
{Name: "Project"},
}
makeUniqueNames(items, func(item *testItem) string {
return item.Name
}, func(item *testItem, name string) {
item.Name = name
})
if !isUnique(items) {
t.Fatal("Not unique names")
}
}