WIP: Good progress on better sync

This commit is contained in:
Nikolai Rodionov
2023-10-12 18:02:14 +02:00
parent c67a9c84e4
commit eb7abefc89
6 changed files with 418 additions and 350 deletions

View File

@ -1,6 +1,7 @@
package diff
import (
"fmt"
"reflect"
"git.badhouseplants.net/allanger/shoebill/pkg/lockfile"
@ -9,138 +10,170 @@ import (
"github.com/sirupsen/logrus"
)
type Diff struct {
AddedReleases release.Releases
DeletedReleases release.Releases
UpdatedReleases release.Releases
PreservedReleases release.Releases
AddedRepositories repository.Repositories
DeletedRepositories repository.Repositories
UpdatedRepositories repository.Repositories
PreservedRepositories repository.Repositories
type ReleasesDiff struct {
Action string
Current *release.Release
Wished *release.Release
}
type ReleasesDiffs []*ReleasesDiff
type RepositoriesDiff struct {
Action string
Current *repository.Repository
Wished *repository.Repository
}
type RepositoriesDiffs []*RepositoriesDiff
const (
ACTION_ADD = "add"
ACTION_UPDATE = "update"
ACTION_DELETE = "delete"
ACTION_PRESERVE = "preserve"
ACTION_ADD = "add"
ACTION_UPDATE = "update"
ACTION_DELETE = "delete"
)
// TODO(@allanger): Naming should be better
func DiffReleases(src, dest release.Releases) (*Diff, error) {
diff := &Diff{}
func DiffReleases(currentReleases, wishedReleases release.Releases) (ReleasesDiffs, error) {
newDiff := ReleasesDiffs{}
for _, rSrc := range src {
for _, currentRelease := range currentReleases {
found := false
for _, rDest := range dest {
if rSrc.Release == rDest.Release {
for _, wishedRelease := range wishedReleases {
if currentRelease.Release == wishedRelease.Release {
found = true
if reflect.DeepEqual(rSrc, rDest) {
diff.PreservedReleases = append(diff.PreservedReleases, rSrc)
if reflect.DeepEqual(currentRelease, wishedRelease) {
newDiff = append(newDiff, &ReleasesDiff{
Action: ACTION_PRESERVE,
Current: currentRelease,
Wished: wishedRelease,
})
continue
} else {
if err := rDest.RepositoryObj.KindFromUrl(); err != nil {
if err := wishedRelease.RepositoryObj.KindFromUrl(); err != nil {
return nil, err
}
diff.UpdatedReleases = append(diff.UpdatedReleases, rDest)
newDiff = append(newDiff, &ReleasesDiff{
Action: ACTION_UPDATE,
Current: currentRelease,
Wished: wishedRelease,
})
}
}
}
logrus.Info(rSrc.Release)
if !found {
logrus.Info(rSrc.Release)
// for i, entry := range lockFile {
// if entry.Release == rSrc.Release {
// lockFile[i] = lockFile[len(lockFile)-1]
// lockFile = lockFile[:len(lockFile)-1]
// }
// }
diff.DeletedReleases = append(diff.DeletedReleases, rSrc)
if !found {
newDiff = append(newDiff, &ReleasesDiff{
Action: ACTION_DELETE,
Current: currentRelease,
Wished: nil,
})
}
}
for _, rDest := range dest {
for _, wishedRelease := range wishedReleases {
found := false
for _, rSrc := range src {
if rSrc.Release == rDest.Release {
for _, rSrc := range currentReleases {
if rSrc.Release == wishedRelease.Release {
found = true
continue
}
}
if !found {
if err := rDest.RepositoryObj.KindFromUrl(); err != nil {
if err := wishedRelease.RepositoryObj.KindFromUrl(); err != nil {
return nil, err
}
diff.AddedReleases = append(diff.AddedReleases, rDest)
newDiff = append(newDiff, &ReleasesDiff{
Action: ACTION_ADD,
Current: nil,
Wished: wishedRelease,
})
}
}
return diff, nil
return newDiff, nil
}
func (diff *Diff) Resolve(repositories repository.Repositories, path string) (lockfile.LockFile, error) {
func (diff ReleasesDiffs) Resolve(currentRepositories repository.Repositories, path string) (lockfile.LockFile, RepositoriesDiffs, error) {
lockfile := lockfile.LockFile{}
reposWished := repository.Repositories{}
wishedRepos := repository.Repositories{}
repoDiffs := RepositoriesDiffs{}
for _, p := range diff.PreservedReleases {
logrus.Infof("preserving %s", p.Release)
lockfile = append(lockfile, p.LockEntry())
reposWished = append(reposWished, p.RepositoryObj)
for _, diff := range diff {
switch diff.Action {
case ACTION_ADD:
logrus.Infof("adding %s", diff.Wished.Release)
lockfile = append(lockfile, diff.Wished.LockEntry())
wishedRepos = append(wishedRepos, diff.Wished.RepositoryObj)
case ACTION_PRESERVE:
logrus.Infof("preserving %s", diff.Wished.Release)
lockfile = append(lockfile, diff.Wished.LockEntry())
wishedRepos = append(wishedRepos, diff.Wished.RepositoryObj)
case ACTION_UPDATE:
logrus.Infof("updating %s", diff.Wished.Release)
lockfile = append(lockfile, diff.Wished.LockEntry())
wishedRepos = append(wishedRepos, diff.Wished.RepositoryObj)
case ACTION_DELETE:
logrus.Infof("removing %s", diff.Current.Release)
default:
return nil, nil, fmt.Errorf("unknown action is requests: %s", diff.Action)
}
}
for _, a := range diff.AddedReleases {
logrus.Infof("adding %s", a.Release)
lockfile = append(lockfile, a.LockEntry())
reposWished = append(reposWished, a.RepositoryObj)
}
for _, u := range diff.UpdatedReleases {
logrus.Infof("updating %s", u.Release)
lockfile = append(lockfile, u.LockEntry())
reposWished = append(reposWished, u.RepositoryObj)
}
for _, d := range diff.DeletedReleases {
logrus.Infof("removing %s", d.Release)
}
// Repo Wished is the list of all repos that are required by the current setup
// Existing repos are all the repos in the lockfile
for _, repoExisting := range repositories {
for _, currentRepo := range currentRepositories {
found := false
i := 0
for _, repoWished := range reposWished {
for _, wishedRepo := range wishedRepos {
// If there is the same repo in the wished repos and in the lockfile
// We need either to udpate, or preserve. If it can't be found, just remove
// from the reposWished slice
if repoWished.Name == repoExisting.Name {
if wishedRepo.Name == currentRepo.Name {
// If !found, should be gone from the repo
found = true
if err := repoWished.ValidateURL(); err != nil {
return nil, err
if err := wishedRepo.ValidateURL(); err != nil {
return nil, nil, err
}
if err := repoWished.KindFromUrl(); err != nil {
return nil, err
if err := wishedRepo.KindFromUrl(); err != nil {
return nil, nil, err
}
if !reflect.DeepEqual(reposWished, repoExisting) {
diff.UpdatedRepositories = append(diff.UpdatedRepositories, repoWished)
if !reflect.DeepEqual(wishedRepos, currentRepo) {
repoDiffs = append(repoDiffs, &RepositoriesDiff{
Action: ACTION_UPDATE,
Current: currentRepo,
Wished: wishedRepo,
})
} else {
diff.PreservedRepositories = append(diff.PreservedRepositories, repoWished)
repoDiffs = append(repoDiffs, &RepositoriesDiff{
Action: ACTION_PRESERVE,
Current: currentRepo,
Wished: wishedRepo,
})
}
// Delete the
} else {
reposWished[i] = repoWished
wishedRepos[i] = wishedRepo
i++
}
}
reposWished = reposWished[:i]
wishedRepos = wishedRepos[:i]
if !found {
diff.DeletedRepositories = append(diff.DeletedRepositories, repoExisting)
repoDiffs = append(repoDiffs, &RepositoriesDiff{
Action: ACTION_DELETE,
Current: currentRepo,
Wished: nil,
})
}
}
for _, addedRepo := range wishedRepos {
repoDiffs = append(repoDiffs, &RepositoriesDiff{
Action: ACTION_ADD,
Current: nil,
Wished: addedRepo,
})
}
diff.AddedRepositories = append(diff.AddedRepositories, reposWished...)
return lockfile, nil
return lockfile, repoDiffs, nil
}