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 }