shoebill/internal/utils/diff/diff.go

180 lines
4.6 KiB
Go
Raw Normal View History

2023-07-20 09:26:25 +00:00
package diff
import (
2023-10-12 16:02:14 +00:00
"fmt"
2023-07-20 09:26:25 +00:00
"reflect"
"git.badhouseplants.net/allanger/shoebill/pkg/lockfile"
"git.badhouseplants.net/allanger/shoebill/pkg/release"
"git.badhouseplants.net/allanger/shoebill/pkg/repository"
2023-07-20 09:26:25 +00:00
"github.com/sirupsen/logrus"
)
2023-10-12 16:02:14 +00:00
type ReleasesDiff struct {
Action string
Current *release.Release
Wished *release.Release
2023-07-20 09:26:25 +00:00
}
2023-10-12 16:02:14 +00:00
type ReleasesDiffs []*ReleasesDiff
type RepositoriesDiff struct {
Action string
Current *repository.Repository
Wished *repository.Repository
}
type RepositoriesDiffs []*RepositoriesDiff
2023-07-20 09:26:25 +00:00
const (
2023-10-12 16:02:14 +00:00
ACTION_PRESERVE = "preserve"
ACTION_ADD = "add"
ACTION_UPDATE = "update"
ACTION_DELETE = "delete"
2023-07-20 09:26:25 +00:00
)
// TODO(@allanger): Naming should be better
2023-10-12 16:02:14 +00:00
func DiffReleases(currentReleases, wishedReleases release.Releases) (ReleasesDiffs, error) {
newDiff := ReleasesDiffs{}
2023-07-20 09:26:25 +00:00
2023-10-12 16:02:14 +00:00
for _, currentRelease := range currentReleases {
2023-07-20 09:26:25 +00:00
found := false
2023-10-12 16:02:14 +00:00
for _, wishedRelease := range wishedReleases {
if currentRelease.Release == wishedRelease.Release {
2023-07-20 09:26:25 +00:00
found = true
2023-10-12 16:02:14 +00:00
if reflect.DeepEqual(currentRelease, wishedRelease) {
newDiff = append(newDiff, &ReleasesDiff{
Action: ACTION_PRESERVE,
Current: currentRelease,
Wished: wishedRelease,
})
2023-07-20 09:26:25 +00:00
continue
} else {
2023-10-12 16:02:14 +00:00
if err := wishedRelease.RepositoryObj.KindFromUrl(); err != nil {
2023-07-20 09:26:25 +00:00
return nil, err
}
2023-10-12 16:02:14 +00:00
newDiff = append(newDiff, &ReleasesDiff{
Action: ACTION_UPDATE,
Current: currentRelease,
Wished: wishedRelease,
})
2023-07-20 09:26:25 +00:00
}
}
}
2023-10-12 16:02:14 +00:00
2023-07-20 09:26:25 +00:00
if !found {
2023-10-12 16:02:14 +00:00
newDiff = append(newDiff, &ReleasesDiff{
Action: ACTION_DELETE,
Current: currentRelease,
Wished: nil,
})
2023-07-20 09:26:25 +00:00
}
}
2023-10-12 16:02:14 +00:00
for _, wishedRelease := range wishedReleases {
2023-07-20 09:26:25 +00:00
found := false
2023-10-12 16:02:14 +00:00
for _, rSrc := range currentReleases {
if rSrc.Release == wishedRelease.Release {
2023-07-20 09:26:25 +00:00
found = true
continue
}
}
if !found {
2023-10-12 16:02:14 +00:00
if err := wishedRelease.RepositoryObj.KindFromUrl(); err != nil {
2023-07-20 09:26:25 +00:00
return nil, err
}
2023-10-12 16:02:14 +00:00
newDiff = append(newDiff, &ReleasesDiff{
Action: ACTION_ADD,
Current: nil,
Wished: wishedRelease,
})
2023-07-20 09:26:25 +00:00
}
}
2023-10-12 16:02:14 +00:00
return newDiff, nil
2023-07-20 09:26:25 +00:00
}
2023-10-12 16:02:14 +00:00
func (diff ReleasesDiffs) Resolve(currentRepositories repository.Repositories, path string) (lockfile.LockFile, RepositoriesDiffs, error) {
2023-07-20 09:26:25 +00:00
lockfile := lockfile.LockFile{}
2023-10-12 16:02:14 +00:00
wishedRepos := repository.Repositories{}
repoDiffs := RepositoriesDiffs{}
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)
}
2023-10-12 11:23:50 +00:00
}
// Repo Wished is the list of all repos that are required by the current setup
2023-07-20 09:26:25 +00:00
// Existing repos are all the repos in the lockfile
2023-10-12 16:02:14 +00:00
for _, currentRepo := range currentRepositories {
2023-07-20 09:26:25 +00:00
found := false
i := 0
2023-10-12 16:02:14 +00:00
for _, wishedRepo := range wishedRepos {
2023-07-20 09:26:25 +00:00
// 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
2023-10-12 16:02:14 +00:00
if wishedRepo.Name == currentRepo.Name {
2023-07-20 09:26:25 +00:00
// If !found, should be gone from the repo
found = true
2023-10-12 16:02:14 +00:00
if err := wishedRepo.ValidateURL(); err != nil {
return nil, nil, err
2023-07-20 09:26:25 +00:00
}
2023-10-12 16:02:14 +00:00
if err := wishedRepo.KindFromUrl(); err != nil {
return nil, nil, err
2023-07-20 09:26:25 +00:00
}
2023-10-12 16:02:14 +00:00
if !reflect.DeepEqual(wishedRepos, currentRepo) {
repoDiffs = append(repoDiffs, &RepositoriesDiff{
Action: ACTION_UPDATE,
Current: currentRepo,
Wished: wishedRepo,
})
2023-07-20 09:26:25 +00:00
} else {
2023-10-12 16:02:14 +00:00
repoDiffs = append(repoDiffs, &RepositoriesDiff{
Action: ACTION_PRESERVE,
Current: currentRepo,
Wished: wishedRepo,
})
2023-07-20 09:26:25 +00:00
}
} else {
2023-10-12 16:02:14 +00:00
wishedRepos[i] = wishedRepo
2023-07-20 09:26:25 +00:00
i++
}
}
2023-10-12 16:02:14 +00:00
wishedRepos = wishedRepos[:i]
2023-07-20 09:26:25 +00:00
if !found {
2023-10-12 16:02:14 +00:00
repoDiffs = append(repoDiffs, &RepositoriesDiff{
Action: ACTION_DELETE,
Current: currentRepo,
Wished: nil,
})
2023-07-20 09:26:25 +00:00
}
}
2023-10-12 16:02:14 +00:00
for _, addedRepo := range wishedRepos {
repoDiffs = append(repoDiffs, &RepositoriesDiff{
Action: ACTION_ADD,
Current: nil,
Wished: addedRepo,
})
}
2023-07-20 09:26:25 +00:00
2023-10-12 16:02:14 +00:00
return lockfile, repoDiffs, nil
2023-07-20 09:26:25 +00:00
}