fix dependency sorting

This commit is contained in:
dfsek
2021-11-18 21:38:33 -07:00
parent c53aa12377
commit 84537e2f99
3 changed files with 23 additions and 20 deletions
@@ -13,39 +13,41 @@ import com.dfsek.terra.api.addon.BaseAddon;
public class DependencySorter { public class DependencySorter {
private final Map<String, BaseAddon> addons = new HashMap<>(); private final Map<String, BaseAddon> addons = new HashMap<>();
private final Map<BaseAddon, Boolean> visited = new HashMap<>(); private final Map<String, Boolean> visited = new HashMap<>();
private final List<BaseAddon> addonList = new ArrayList<>(); private final List<BaseAddon> addonList = new ArrayList<>();
public void add(BaseAddon addon) { public void add(BaseAddon addon) {
addons.put(addon.getID(), addon); addons.put(addon.getID(), addon);
visited.put(addon, false); visited.put(addon.getID(), false);
addonList.add(addon); addonList.add(addon);
} }
private void sortDependencies(BaseAddon addon, List<BaseAddon> sort) { private void sortDependencies(BaseAddon addon, List<BaseAddon> sort) {
addon.getDependencies().forEach((id, range) -> { addon.getDependencies().forEach((id, range) -> {
if(!addons.containsKey(id)) { if(!addons.containsKey(id)) {
throw new DependencyException("Addon " + addon.getID() + " specifies dependency on " + id + ", versions " + range + ", but no such addon is installed."); throw new DependencyException("Addon " + addon.getID() + " specifies dependency on " + id + ", versions " + range +
", but no such addon is installed.");
} }
BaseAddon dependency = addons.get(id); BaseAddon dependency = addons.get(id);
if(!range.isSatisfiedBy(dependency.getVersion())) { if(!range.isSatisfiedBy(dependency.getVersion())) {
throw new DependencyVersionException("Addon " + addon.getID() + " specifies dependency on " + id + ", versions " + range + ", but non-matching version " + dependency.getVersion() + " is installed.."); throw new DependencyVersionException("Addon " + addon.getID() + " specifies dependency on " + id + ", versions " + range +
", but non-matching version " + dependency.getVersion() + " is installed..");
} }
if(!visited.get(dependency)) { // if we've not visited it yet if(!visited.get(dependency.getID())) { // if we've not visited it yet
visited.put(dependency, true); // we've visited it now visited.put(dependency.getID(), true); // we've visited it now
if(!dependency.getDependencies().isEmpty()) { // if this addon has dependencies... sortDependencies(dependency, sort);
sortDependencies(dependency, sort); // sort them first.
}
if(sort.contains(dependency)) { if(sort.contains(dependency)) {
throw new CircularDependencyException("Addon " + addon.getID() + " has circular dependency beginning with " + dependency.getID()); throw new CircularDependencyException(
"Addon " + addon.getID() + " has circular dependency beginning with " + dependency.getID());
} }
sort.add(dependency); // add it to the list. sort.add(dependency); // add it to the list.
} }
}); });
@@ -58,14 +60,15 @@ public class DependencySorter {
BaseAddon addon = addonList.get(i); BaseAddon addon = addonList.get(i);
addonList.remove(i); addonList.remove(i);
if(!visited.get(addon)) { // if we've not visited it yet System.out.println(addon.getID() + ": " + visited.get(addon.getID()));
visited.put(addon, true); // we've visited it now if(!visited.get(addon.getID())) {
if(!addon.getDependencies().isEmpty()) { // if this addon has dependencies... sortDependencies(addon, sorted);
sortDependencies(addon, sorted);
}
} }
sorted.add(addon); if(!visited.get(addon.getID())) {
sorted.add(addon);
visited.put(addon.getID(), true);
}
} }
return sorted; return sorted;