remove dependency on guava
Some checks failed
Publish to snapshot maven / build (push) Has been cancelled
Some checks failed
Publish to snapshot maven / build (push) Has been cancelled
This commit is contained in:
parent
1ef8b24764
commit
cea4e8ea01
|
@ -7,7 +7,7 @@ plugins {
|
|||
}
|
||||
|
||||
group = "dev.frogmc"
|
||||
version = "0.0.1-alpha.30"
|
||||
version = "0.0.1-alpha.31"
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
|
@ -27,7 +27,6 @@ dependencies {
|
|||
compileOnly("org.apache.logging.log4j:log4j-api:2.22.1")
|
||||
compileOnly("org.apache.logging.log4j:log4j-core:2.22.1")
|
||||
compileOnly("com.google.code.gson:gson:2.0")
|
||||
compileOnly("com.google.guava:guava:21.0") // Lowest possible version for our code
|
||||
|
||||
api(libs.mixin) {
|
||||
exclude(group = "com.google.code.gson")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
plugins {
|
||||
java
|
||||
id("dev.frogmc.phytotelma") version "0.0.1-alpha.21"
|
||||
id("dev.frogmc.phytotelma") version "0.0.1-alpha.25"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -6,9 +6,6 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
|
||||
import dev.frogmc.frogloader.api.mod.ModDependencies;
|
||||
import dev.frogmc.frogloader.api.mod.ModProperties;
|
||||
import dev.frogmc.frogloader.api.mod.SemVer;
|
||||
|
@ -21,16 +18,15 @@ import org.jetbrains.annotations.Nullable;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class ModDependencyResolver {
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(ModDependencyResolver.class);
|
||||
private static final Pattern COMPARATOR = Pattern.compile("(=|>=|<=|>|<)?(\\d.*)");
|
||||
private final Collection<ModProperties> original;
|
||||
private final Multimap<String, DependencyEntry> dependencies = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||
private final Multimap<String, DependencyEntry> breakings = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||
private final Multimap<String, DependencyEntry> suggests = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||
private final Multimap<String, ProvidedMod> provides = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||
private final Map<String, Collection<DependencyEntry>> dependencies = new HashMap<>();
|
||||
private final Map<String, Collection<DependencyEntry>> breakings = new HashMap<>();
|
||||
private final Map<String, Collection<DependencyEntry>> suggests = new HashMap<>();
|
||||
private final Map<String, Collection<ProvidedMod>> provides = new HashMap<>();
|
||||
private final Map<String, ModProperties> presentMods = new HashMap<>();
|
||||
|
||||
public ModDependencyResolver(Collection<ModProperties> mods) throws ResolverException {
|
||||
|
@ -41,17 +37,17 @@ public class ModDependencyResolver {
|
|||
private void load() throws ResolverException {
|
||||
for (ModProperties props : original) {
|
||||
for (ModDependencies.Entry entry : props.dependencies().getForType(ModDependencies.Type.DEPEND)) {
|
||||
dependencies.put(entry.id(), new DependencyEntry(entry.range(), props, entry.link(), entry.name()));
|
||||
dependencies.computeIfAbsent(entry.id(), i -> new HashSet<>()).add(new DependencyEntry(entry.range(), props, entry.link(), entry.name()));
|
||||
}
|
||||
for (ModDependencies.Entry entry : props.dependencies().getForType(ModDependencies.Type.BREAK)) {
|
||||
breakings.put(entry.id(), new DependencyEntry(entry.range(), props, entry.link(), entry.name()));
|
||||
breakings.computeIfAbsent(entry.id(), i -> new HashSet<>()).add(new DependencyEntry(entry.range(), props, entry.link(), entry.name()));
|
||||
}
|
||||
for (ModDependencies.Entry entry : props.dependencies().getForType(ModDependencies.Type.SUGGEST)) {
|
||||
suggests.put(entry.id(), new DependencyEntry(entry.range(), props, entry.link(), entry.name()));
|
||||
suggests.computeIfAbsent(entry.id(), i -> new HashSet<>()).add(new DependencyEntry(entry.range(), props, entry.link(), entry.name()));
|
||||
}
|
||||
props.dependencies().getForType(ModDependencies.Type.PROVIDE).forEach(e -> {
|
||||
try {
|
||||
provides.put(e.id(), new ProvidedMod(e.id(), SemVerImpl.parse(e.range()), props));
|
||||
provides.computeIfAbsent(e.id(), i -> new HashSet<>()).add(new ProvidedMod(e.id(), SemVerImpl.parse(e.range()), props));
|
||||
} catch (SemVerParseException ex) {
|
||||
LOGGER.warn("Version for {} ({}), provided by mod '{}' ({}) does not meet SemVer specifications. Mod will not be provided.",
|
||||
e.id(), e.range(), props.id(), props.name());
|
||||
|
@ -66,26 +62,28 @@ public class ModDependencyResolver {
|
|||
// Step 1: Combine present and provided mods, always use the latest version available
|
||||
Map<String, SemVer> presentOrProvided = new HashMap<>();
|
||||
presentMods.forEach((s, modProperties) -> presentOrProvided.put(s, modProperties.version()));
|
||||
provides.forEach((s, ver) -> {
|
||||
if (presentMods.containsKey(s)) {
|
||||
if (presentMods.get(s).version().compareTo(ver.version()) < 0) {
|
||||
presentOrProvided.replace(s, ver.version());
|
||||
}
|
||||
} else {
|
||||
presentOrProvided.put(s, ver.version());
|
||||
}
|
||||
});
|
||||
provides.forEach((s, vers) ->
|
||||
vers.forEach(ver -> {
|
||||
if (presentMods.containsKey(s)) {
|
||||
if (presentMods.get(s).version().compareTo(ver.version()) < 0) {
|
||||
presentOrProvided.replace(s, ver.version());
|
||||
}
|
||||
} else {
|
||||
presentOrProvided.put(s, ver.version());
|
||||
}
|
||||
}));
|
||||
|
||||
// Step 2: look for breakage declarations
|
||||
Collection<BreakingModException.Entry> breaks = new HashSet<>();
|
||||
for (Map.Entry<String, DependencyEntry> e : breakings.entries()) {
|
||||
for (Map.Entry<String, Collection<DependencyEntry>> e : breakings.entrySet()) {
|
||||
String key = e.getKey();
|
||||
DependencyEntry dependencyEntry = e.getValue();
|
||||
if (presentOrProvided.containsKey(key) && dependencyEntry.range.versionMatches(presentOrProvided.get(key))) {
|
||||
breaks.add(new BreakingModException.Entry(dependencyEntry.origin(),
|
||||
Optional.ofNullable(presentMods.get(key)).orElseGet(() -> provides.get(key).stream().findFirst().map(ProvidedMod::source).orElseThrow()),
|
||||
dependencyEntry.range));
|
||||
}
|
||||
e.getValue().forEach(dependencyEntry -> {
|
||||
if (presentOrProvided.containsKey(key) && dependencyEntry.range.versionMatches(presentOrProvided.get(key))) {
|
||||
breaks.add(new BreakingModException.Entry(dependencyEntry.origin(),
|
||||
Optional.ofNullable(presentMods.get(key)).orElseGet(() -> provides.get(key).stream().findFirst().map(ProvidedMod::source).orElseThrow()),
|
||||
dependencyEntry.range));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!breaks.isEmpty()) {
|
||||
|
@ -99,13 +97,14 @@ public class ModDependencyResolver {
|
|||
|
||||
|
||||
// Step 3: print out information about suggested mods
|
||||
for (Map.Entry<String, DependencyEntry> e : suggests.entries()) {
|
||||
for (Map.Entry<String, Collection<DependencyEntry>> e : suggests.entrySet()) {
|
||||
String key = e.getKey();
|
||||
DependencyEntry v = e.getValue();
|
||||
if (!presentOrProvided.containsKey(key) || !v.range.versionMatches(presentOrProvided.get(key))) {
|
||||
LOGGER.info("Mod '{}' ({}) suggests range {} of {}, you should install a matching version for the optimal experience!",
|
||||
v.origin().id(), v.origin().name(), v.range(), key);
|
||||
}
|
||||
e.getValue().forEach(v -> {
|
||||
if (!presentOrProvided.containsKey(key) || !v.range.versionMatches(presentOrProvided.get(key))) {
|
||||
LOGGER.info("Mod '{}' ({}) suggests range {} of {}, you should install a matching version for the optimal experience!",
|
||||
v.origin().id(), v.origin().name(), v.range(), key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Step 4.1: Add all mods to the result that do not depend on any other mods
|
||||
|
@ -118,22 +117,23 @@ public class ModDependencyResolver {
|
|||
|
||||
Collection<UnfulfilledDependencyException.Entry> unfulfilled = new HashSet<>();
|
||||
// Step 4.2: Check that all dependencies are satisfied by present or provided mods.
|
||||
for (Map.Entry<String, DependencyEntry> entry : dependencies.entries()) {
|
||||
for (Map.Entry<String, Collection<DependencyEntry>> entry : dependencies.entrySet()) {
|
||||
String s = entry.getKey();
|
||||
DependencyEntry value = entry.getValue();
|
||||
if (!(presentMods.containsKey(s) && value.range.versionMatches(presentOrProvided.get(s)))) { // The dependency isn't fulfilled by any present mods
|
||||
if (!(provides.containsKey(s) && provides.get(s).stream().map(ProvidedMod::version).allMatch(value.range::versionMatches))) { // The dependency also isn't fulfilled by any provided mods
|
||||
if (value.origin.extensions().getOrDefault(Constants.MOD_ID, Constants.EXTENSION_LOADING_TYPE, "required").equals("required")) {
|
||||
unfulfilled.add(new UnfulfilledDependencyException.Entry(value.origin, s, value.range, presentOrProvided.get(s), value.link(), value.name()));
|
||||
} else {
|
||||
LOGGER.debug("Skipping optional mod: {} ({})", value.origin().id(), value.origin().name());
|
||||
continue;
|
||||
entry.getValue().forEach(value -> {
|
||||
if (!(presentMods.containsKey(s) && value.range.versionMatches(presentOrProvided.get(s)))) { // The dependency isn't fulfilled by any present mods
|
||||
if (!(provides.containsKey(s) && provides.get(s).stream().map(ProvidedMod::version).allMatch(value.range::versionMatches))) { // The dependency also isn't fulfilled by any provided mods
|
||||
if (value.origin.extensions().getOrDefault(Constants.MOD_ID, Constants.EXTENSION_LOADING_TYPE, "required").equals("required")) {
|
||||
unfulfilled.add(new UnfulfilledDependencyException.Entry(value.origin, s, value.range, presentOrProvided.get(s), value.link(), value.name()));
|
||||
} else {
|
||||
LOGGER.debug("Skipping optional mod: {} ({})", value.origin().id(), value.origin().name());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// as there hasn't been thrown an exception the dependency must have been fulfilled, add the mod that set the dependency
|
||||
LOGGER.debug("Adding mod to result: {} ({})", value.origin().id(), value.origin().name());
|
||||
result.add(value.origin());
|
||||
// as there hasn't been thrown an exception the dependency must have been fulfilled, add the mod that set the dependency
|
||||
LOGGER.debug("Adding mod to result: {} ({})", value.origin().id(), value.origin().name());
|
||||
result.add(value.origin());
|
||||
});
|
||||
}
|
||||
|
||||
if (!unfulfilled.isEmpty()) {
|
||||
|
|
Loading…
Reference in a new issue