io.dangernoodle.grt.utils.RepositoryMerger Maven / Gradle / Ivy
package io.dangernoodle.grt.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import io.dangernoodle.grt.Repository;
import io.dangernoodle.grt.Repository.Settings;
import io.dangernoodle.grt.Repository.Settings.AccessRestrictions;
import io.dangernoodle.grt.Repository.Settings.Branches;
import io.dangernoodle.grt.Repository.Settings.Branches.Protection;
import io.dangernoodle.grt.Repository.Settings.Branches.Protection.RequireReviews;
import io.dangernoodle.grt.Repository.Settings.Branches.Protection.RequiredChecks;
import io.dangernoodle.grt.Repository.Settings.Color;
import io.dangernoodle.grt.Repository.Settings.Permission;
public class RepositoryMerger
{
private final Branches deBranches;
private final Repository deRepository;
private final Settings deSettings;
private final Branches ovBranches;
private final Repository ovRepository;
private final Settings ovSettings;
private final RepositoryBuilder repoBuilder;
public RepositoryMerger(Repository defaults, Repository overrides, RepositoryBuilder builder)
{
this.deRepository = defaults;
this.ovRepository = overrides;
this.deSettings = deRepository.getSettings();
this.ovSettings = ovRepository.getSettings();
this.deBranches = deSettings.getBranches();
this.ovBranches = ovSettings.getBranches();
this.repoBuilder = builder;
}
public Repository merge() throws IllegalStateException
{
// there can be only one
repoBuilder.setName(ovRepository.getName());
mergeOrganization();
mergeAutoInitialize();
mergePrivate();
mergeLabels();
mergeTeams();
mergeColaborators();
mergeBranches();
mergePlugins();
mergeWorkflow();
return repoBuilder.build();
}
private void addBranchProtection(String branch, Protection protection)
{
repoBuilder.requireSignedCommits(branch, merge(protection.getRequireSignedCommits(), false))
.enforceForAdminstrators(branch, merge(protection.getIncludeAdministrators(), false));
if (protection.hasRequireReviews())
{
addRequireReviews(branch, protection.getRequireReviews());
}
if (protection.hasRequiredChecks())
{
addRequireChecks(branch, protection.getRequiredChecks());
}
if (protection.hasRestrictedPushAccess())
{
addRestrictedPushAccess(branch, protection);
}
}
private void addRequireChecks(String branch, RequiredChecks requireChecks)
{
repoBuilder.requireBranchUpToDate(branch, requireChecks.getRequireUpToDate());
if (requireChecks.hasContexts())
{
requireChecks.getContexts()
.forEach(context -> repoBuilder.addRequiredContext(branch, context));
}
}
private void addRequireReviews(String branch, RequireReviews requireReviews)
{
repoBuilder.requireReviews(branch)
.requiredReviewers(branch, merge(requireReviews.getRequiredReviewers(), 1))
.dismissStaleApprovals(branch, merge(requireReviews.getDismissStaleApprovals(), false))
.requireCodeOwnerReview(branch, merge(requireReviews.getRequireCodeOwner(), false));
if (requireReviews.hasDismissalRestrictions())
{
AccessRestrictions restrictions = requireReviews.getDismissalRestrictions();
if (restrictions.hasTeams())
{
restrictions.getTeams()
.forEach(team -> repoBuilder.addTeamReviewDismisser(branch, team));
}
if (restrictions.hasUsers())
{
restrictions.getUsers()
.forEach(user -> repoBuilder.addUserReviewDismisser(branch, user));
}
}
}
private void addRestrictedPushAccess(String branch, Protection protection)
{
repoBuilder.restrictPushAccess(branch);
AccessRestrictions restrictions = protection.getPushAccess();
if (restrictions.hasTeams())
{
restrictions.getTeams()
.forEach(team -> repoBuilder.addTeamPushAccess(branch, team));
}
if (restrictions.hasUsers())
{
restrictions.getUsers()
.forEach(user -> repoBuilder.addUserPushAccess(branch, user));
}
}
private String getPrimaryBranch()
{
String branch = ovBranches.getDefault();
if (branch == null)
{
branch = deBranches.getDefault();
if (branch == null)
{
branch = "master";
}
}
return branch;
}
private boolean merge(Boolean override, Boolean defaults)
{
return merge(override, defaults, false);
}
private Collection merge(Collection override, Collection defaults)
{
return merge(override, defaults, Collections.emptyList());
}
private int merge(Integer override, Integer defaults)
{
return merge(override, defaults, 1);
}
private void merge(Map overrides, Map defaults, Callback callback)
{
Map merged = merge(overrides, defaults, Collections.emptyMap());
if (merged.isEmpty())
{
callback.add();
}
else
{
merged.forEach(callback::add);
}
}
private T merge(T override, T defaults, T dflt)
{
if (override != null)
{
return override;
}
if (defaults != null)
{
return defaults;
}
return dflt;
}
private void mergeAutoInitialize()
{
repoBuilder.setInitialize(merge(ovSettings.autoInitialize(), deSettings.autoInitialize()));
}
private void mergeBranches()
{
String primary = getPrimaryBranch();
repoBuilder.setPrimaryBranch(primary);
Collection branches = new ArrayList<>(merge(deBranches.getOther(), ovBranches.getOther()));
repoBuilder.addOtherBranches(branches);
branches.add(primary);
branches.forEach(this::mergeProtections);
}
private void mergeColaborators()
{
merge(ovSettings.getCollaborators(), deSettings.getCollaborators(), new Callback()
{
@Override
public void add()
{
repoBuilder.addCollaborators();
}
@Override
public void add(String key, Permission value)
{
repoBuilder.addCollaborator(key, value);
}
});
}
private void mergeLabels()
{
merge(ovSettings.getLabels(), deSettings.getLabels(), new Callback()
{
@Override
public void add()
{
repoBuilder.addLabels();
}
@Override
public void add(String key, Color value)
{
repoBuilder.addLabel(key, value);
}
});
}
private void mergeOrganization() throws IllegalStateException
{
String organization = ovRepository.getOrganization();
if (organization == null)
{
organization = deRepository.getOrganization();
if (organization == null)
{
throw new IllegalStateException("organization must be specified");
}
}
repoBuilder.setOrganization(organization);
}
private void mergePlugins()
{
Map dePlugins = Optional.ofNullable(deRepository.getPlugins())
.orElse(Collections.emptyMap());
Map ovPlugins = Optional.ofNullable(ovRepository.getPlugins())
.orElse(Collections.emptyMap());
Map merged = new HashMap<>(dePlugins);
merged.putAll(ovPlugins);
merged.forEach(repoBuilder::addPlugin);
}
private void mergePrivate()
{
repoBuilder.setPrivate(merge(ovSettings.isPrivate(), deSettings.isPrivate()));
}
private void mergeProtections(String branch)
{
Protection deProtection = deBranches.getProtection(branch);
Protection ovProtection = ovBranches.getProtection(branch);
if (ovBranches.hasProtection(branch))
{
if (ovProtection.isEnabled())
{
addBranchProtection(branch, ovProtection);
}
}
else if (deBranches.hasProtection(branch))
{
if (deProtection.isEnabled())
{
addBranchProtection(branch, deProtection);
}
}
}
private void mergeTeams()
{
merge(ovSettings.getTeams(), deSettings.getTeams(), new Callback()
{
@Override
public void add()
{
repoBuilder.addTeams();
}
@Override
public void add(String key, Permission value)
{
repoBuilder.addTeam(key, value);
}
});
}
private void mergeWorkflow()
{
merge(ovRepository.getWorkflow(), deRepository.getWorkflow()).forEach(repoBuilder::addWorkflow);
}
private interface Callback
{
void add();
void add(String key, V value);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy