180 lines
4.6 KiB
Go
180 lines
4.6 KiB
Go
|
package diff
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
|
||
|
"git.badhouseplants.net/allanger/shoebill/pkg/lockfile"
|
||
|
"git.badhouseplants.net/allanger/shoebill/pkg/release"
|
||
|
"git.badhouseplants.net/allanger/shoebill/pkg/repository"
|
||
|
"github.com/sirupsen/logrus"
|
||
|
)
|
||
|
|
||
|
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_PRESERVE = "preserve"
|
||
|
ACTION_ADD = "add"
|
||
|
ACTION_UPDATE = "update"
|
||
|
ACTION_DELETE = "delete"
|
||
|
)
|
||
|
|
||
|
// TODO(@allanger): Naming should be better
|
||
|
func DiffReleases(currentReleases, wishedReleases release.Releases) (ReleasesDiffs, error) {
|
||
|
newDiff := ReleasesDiffs{}
|
||
|
|
||
|
for _, currentRelease := range currentReleases {
|
||
|
found := false
|
||
|
for _, wishedRelease := range wishedReleases {
|
||
|
if currentRelease.Release == wishedRelease.Release {
|
||
|
found = true
|
||
|
if reflect.DeepEqual(currentRelease, wishedRelease) {
|
||
|
newDiff = append(newDiff, &ReleasesDiff{
|
||
|
Action: ACTION_PRESERVE,
|
||
|
Current: currentRelease,
|
||
|
Wished: wishedRelease,
|
||
|
})
|
||
|
|
||
|
continue
|
||
|
} else {
|
||
|
if err := wishedRelease.RepositoryObj.KindFromUrl(); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
newDiff = append(newDiff, &ReleasesDiff{
|
||
|
Action: ACTION_UPDATE,
|
||
|
Current: currentRelease,
|
||
|
Wished: wishedRelease,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if !found {
|
||
|
newDiff = append(newDiff, &ReleasesDiff{
|
||
|
Action: ACTION_DELETE,
|
||
|
Current: currentRelease,
|
||
|
Wished: nil,
|
||
|
})
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for _, wishedRelease := range wishedReleases {
|
||
|
found := false
|
||
|
for _, rSrc := range currentReleases {
|
||
|
if rSrc.Release == wishedRelease.Release {
|
||
|
found = true
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
if !found {
|
||
|
if err := wishedRelease.RepositoryObj.KindFromUrl(); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
newDiff = append(newDiff, &ReleasesDiff{
|
||
|
Action: ACTION_ADD,
|
||
|
Current: nil,
|
||
|
Wished: wishedRelease,
|
||
|
})
|
||
|
|
||
|
}
|
||
|
}
|
||
|
return newDiff, nil
|
||
|
}
|
||
|
|
||
|
func (diff ReleasesDiffs) Resolve(currentRepositories repository.Repositories, path string) (lockfile.LockFile, RepositoriesDiffs, error) {
|
||
|
lockfile := lockfile.LockFile{}
|
||
|
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)
|
||
|
}
|
||
|
}
|
||
|
// 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 _, currentRepo := range currentRepositories {
|
||
|
found := false
|
||
|
i := 0
|
||
|
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 wishedRepo.Name == currentRepo.Name {
|
||
|
// If !found, should be gone from the repo
|
||
|
found = true
|
||
|
if err := wishedRepo.ValidateURL(); err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
if err := wishedRepo.KindFromUrl(); err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
if !reflect.DeepEqual(wishedRepos, currentRepo) {
|
||
|
repoDiffs = append(repoDiffs, &RepositoriesDiff{
|
||
|
Action: ACTION_UPDATE,
|
||
|
Current: currentRepo,
|
||
|
Wished: wishedRepo,
|
||
|
})
|
||
|
} else {
|
||
|
repoDiffs = append(repoDiffs, &RepositoriesDiff{
|
||
|
Action: ACTION_PRESERVE,
|
||
|
Current: currentRepo,
|
||
|
Wished: wishedRepo,
|
||
|
})
|
||
|
}
|
||
|
} else {
|
||
|
wishedRepos[i] = wishedRepo
|
||
|
i++
|
||
|
}
|
||
|
}
|
||
|
wishedRepos = wishedRepos[:i]
|
||
|
if !found {
|
||
|
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,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
return lockfile, repoDiffs, nil
|
||
|
}
|