Merge pull request 'Convert ModDependencies to an interface' (#15) from TheKodeToad/mod-dependencies-iface into main
Some checks failed
Publish to snapshot maven / build (push) Failing after 17s
Some checks failed
Publish to snapshot maven / build (push) Failing after 17s
Reviewed-on: #15 Reviewed-by: owlsys <owlsys@noreply.localhost>
This commit is contained in:
commit
b3085264ee
|
@ -1,43 +1,10 @@
|
||||||
package dev.frogmc.frogloader.api.mod;
|
package dev.frogmc.frogloader.api.mod;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
public interface ModDependencies {
|
||||||
* A mod's dependencies.
|
|
||||||
*
|
|
||||||
* <p>Mod dependencies are declared in four types:</p>
|
|
||||||
* <code>Type.DEPEND</code>, <code>Type.BREAK</code>, <code>Type.SUGGEST</code> and <code>Type.PROVIDE</code>
|
|
||||||
*
|
|
||||||
* <p>Note: The <code>Type.PROVIDE</code> is a bit of a special case in the way that it only supports a single SemVer version instead of a full version range.</p>
|
|
||||||
*
|
|
||||||
* @see ModDependencies.Type
|
|
||||||
* @see ModDependencies.Entry
|
|
||||||
* @see ModProperties
|
|
||||||
* @see SemVer
|
|
||||||
*/
|
|
||||||
public final class ModDependencies {
|
|
||||||
|
|
||||||
private final Map<Type, Collection<Entry>> entries = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct new mod dependencies for a mod.
|
|
||||||
* <p><strong>Internal use only.</strong></p>
|
|
||||||
*
|
|
||||||
* @param depends <code>Type.DEPEND</code> entries
|
|
||||||
* @param breaks <code>Type.BREAK</code> entries
|
|
||||||
* @param suggests <code>Type.SUGGEST</code> entries
|
|
||||||
* @param provides <code>Type.PROVIDE</code> entries
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public ModDependencies(Collection<Entry> depends, Collection<Entry> breaks, Collection<Entry> suggests, Collection<Entry> provides) {
|
|
||||||
entries.put(Type.DEPEND, depends);
|
|
||||||
entries.put(Type.BREAK, breaks);
|
|
||||||
entries.put(Type.SUGGEST, suggests);
|
|
||||||
entries.put(Type.PROVIDE, provides);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get dependencies of a specific mod for a specific type
|
* Get dependencies of a specific mod for a specific type
|
||||||
|
@ -45,9 +12,7 @@ public final class ModDependencies {
|
||||||
* @param type the dependency type to query for
|
* @param type the dependency type to query for
|
||||||
* @return a collection of dependency entries
|
* @return a collection of dependency entries
|
||||||
*/
|
*/
|
||||||
public Collection<Entry> getForType(Type type) {
|
Collection<Entry> getForType(Type type);
|
||||||
return entries.get(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get entries that depend on a specific mod's id
|
* Get entries that depend on a specific mod's id
|
||||||
|
@ -55,17 +20,7 @@ public final class ModDependencies {
|
||||||
* @param id the mod id to find dependency entries for
|
* @param id the mod id to find dependency entries for
|
||||||
* @return a collection of entries that depend on the given mod id
|
* @return a collection of entries that depend on the given mod id
|
||||||
*/
|
*/
|
||||||
public Collection<ModEntry> getForModId(String id) {
|
Collection<Entry> getForModId(String id);
|
||||||
List<ModEntry> entries = new ArrayList<>();
|
|
||||||
for (Type type : Type.values()) {
|
|
||||||
for (Entry entry : getForType(type)) {
|
|
||||||
if (entry.id.equals(id)) {
|
|
||||||
entries.add(new ModEntry(type, entry.range, entry.link, entry.name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dependency types to distinguish their variants.
|
* Dependency types to distinguish their variants.
|
||||||
|
@ -90,69 +45,45 @@ public final class ModDependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A data class to handle entries depending on a specific mod id
|
* Represents a mod's dependency.
|
||||||
*/
|
*/
|
||||||
public static class ModEntry {
|
interface Entry {
|
||||||
private final Type type;
|
|
||||||
private final String range;
|
|
||||||
private final String link;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
private ModEntry(Type type, String range, String link, String name) {
|
|
||||||
this.type = type;
|
|
||||||
this.range = range;
|
|
||||||
this.link = link;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get this dependency's type
|
* Get this dependency's type.
|
||||||
*
|
*
|
||||||
* @return This dependency's type
|
* @return This dependency's type.
|
||||||
*/
|
*/
|
||||||
public Type type() {
|
Type type();
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get this dependency's version range
|
* Get this dependency's mod ID.
|
||||||
*
|
*
|
||||||
* @return This dependency's version range
|
* @return This dependency's mod ID.
|
||||||
*/
|
*/
|
||||||
public String range() {
|
String id();
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get this dependency's link
|
* Get this dependency's version range.
|
||||||
* <p>May be null.</p>
|
|
||||||
*
|
*
|
||||||
* @return This dependency's link
|
* @return This dependency's version range.
|
||||||
*/
|
*/
|
||||||
public @Nullable String link() {
|
@Nullable String range();
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get this dependency's (friendly) name
|
* Get this dependency's installation link.
|
||||||
* <p>May be null.</p>
|
|
||||||
*
|
*
|
||||||
* @return This dependency's name
|
* @return This dependency's installation link.
|
||||||
*/
|
*/
|
||||||
public @Nullable String name() {
|
@Nullable String link();
|
||||||
return name;
|
|
||||||
}
|
/**
|
||||||
|
* Get this dependency's friendly name.
|
||||||
|
*
|
||||||
|
* @return This dependency's name.
|
||||||
|
*/
|
||||||
|
@Nullable String name();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* General storage for dependencies
|
|
||||||
*
|
|
||||||
* @param id the mod's id
|
|
||||||
* @param range the dependency's version range
|
|
||||||
* @param link an optional link for information about this dependency
|
|
||||||
* @param name an optional (friendly) name for this dependency
|
|
||||||
*/
|
|
||||||
public record Entry(String id, String range, String link, String name) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import dev.frogmc.frogloader.impl.mod.ModDependenciesImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mod's properties. This class represents a mod at runtime.
|
* A mod's properties. This class represents a mod at runtime.
|
||||||
* It is read from each mod's <code>frog.mod.toml</code> file.
|
* It is read from each mod's <code>frog.mod.toml</code> file.
|
||||||
*
|
*
|
||||||
* @see ModDependencies
|
* @see ModDependenciesImpl
|
||||||
* @see ModExtensions
|
* @see ModExtensions
|
||||||
* @see SemVer
|
* @see SemVer
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +67,7 @@ public interface ModProperties {
|
||||||
* Get this mod's dependencies.
|
* Get this mod's dependencies.
|
||||||
*
|
*
|
||||||
* @return The mod's dependencies
|
* @return The mod's dependencies
|
||||||
* @see ModDependencies
|
* @see ModDependenciesImpl
|
||||||
*/
|
*/
|
||||||
ModDependencies dependencies();
|
ModDependencies dependencies();
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package dev.frogmc.frogloader.impl.mod;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import dev.frogmc.frogloader.api.mod.ModDependencies;
|
|
||||||
import dev.frogmc.frogloader.api.mod.ModExtensions;
|
import dev.frogmc.frogloader.api.mod.ModExtensions;
|
||||||
import dev.frogmc.frogloader.api.mod.ModProperties;
|
import dev.frogmc.frogloader.api.mod.ModProperties;
|
||||||
import dev.frogmc.frogloader.impl.SemVerParseException;
|
import dev.frogmc.frogloader.impl.SemVerParseException;
|
||||||
|
@ -24,7 +23,7 @@ public class JavaModProperties {
|
||||||
SemVerImpl.parse(System.getProperty("java.runtime.version")),
|
SemVerImpl.parse(System.getProperty("java.runtime.version")),
|
||||||
"",
|
"",
|
||||||
Map.of(System.getProperty("java.vm.vendor"), Collections.singleton("Vendor")),
|
Map.of(System.getProperty("java.vm.vendor"), Collections.singleton("Vendor")),
|
||||||
new ModDependencies(Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet()),
|
new ModDependenciesImpl(Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet()),
|
||||||
new ModExtensionsImpl(Collections.emptyMap()), Collections.emptySet());
|
new ModExtensionsImpl(Collections.emptyMap()), Collections.emptySet());
|
||||||
}
|
}
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package dev.frogmc.frogloader.impl.mod;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import dev.frogmc.frogloader.api.mod.ModDependencies;
|
||||||
|
import dev.frogmc.frogloader.api.mod.ModProperties;
|
||||||
|
import dev.frogmc.frogloader.api.mod.SemVer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mod's dependencies.
|
||||||
|
*
|
||||||
|
* <p>Mod dependencies are declared in four types:</p>
|
||||||
|
* <code>Type.DEPEND</code>, <code>Type.BREAK</code>, <code>Type.SUGGEST</code> and <code>Type.PROVIDE</code>
|
||||||
|
*
|
||||||
|
* <p>Note: The <code>Type.PROVIDE</code> is a bit of a special case in the way that it only supports a single SemVer version instead of a full version range.</p>
|
||||||
|
*
|
||||||
|
* @see ModDependenciesImpl.Type
|
||||||
|
* @see ModDependenciesImpl.Entry
|
||||||
|
* @see ModProperties
|
||||||
|
* @see SemVer
|
||||||
|
*/
|
||||||
|
public final class ModDependenciesImpl implements ModDependencies {
|
||||||
|
|
||||||
|
private final Map<Type, Collection<ModDependencies.Entry>> entries = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct new mod dependencies for a mod.
|
||||||
|
* <p><strong>Internal use only.</strong></p>
|
||||||
|
*
|
||||||
|
* @param depends <code>Type.DEPEND</code> entries
|
||||||
|
* @param breaks <code>Type.BREAK</code> entries
|
||||||
|
* @param suggests <code>Type.SUGGEST</code> entries
|
||||||
|
* @param provides <code>Type.PROVIDE</code> entries
|
||||||
|
*/
|
||||||
|
public ModDependenciesImpl(Collection<ModDependencies.Entry> depends, Collection<ModDependencies.Entry> breaks, Collection<ModDependencies.Entry> suggests, Collection<ModDependencies.Entry> provides) {
|
||||||
|
entries.put(Type.DEPEND, depends);
|
||||||
|
entries.put(Type.BREAK, breaks);
|
||||||
|
entries.put(Type.SUGGEST, suggests);
|
||||||
|
entries.put(Type.PROVIDE, provides);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get dependencies of a specific mod for a specific type
|
||||||
|
*
|
||||||
|
* @param type the dependency type to query for
|
||||||
|
* @return a collection of dependency entries
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Collection<ModDependencies.Entry> getForType(Type type) {
|
||||||
|
return entries.get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get entries that depend on a specific mod's id
|
||||||
|
*
|
||||||
|
* @param id the mod id to find dependency entries for
|
||||||
|
* @return a collection of entries that depend on the given mod id
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Collection<ModDependencies.Entry> getForModId(String id) {
|
||||||
|
List<ModDependencies.Entry> entries = new ArrayList<>();
|
||||||
|
for (Type type : Type.values()) {
|
||||||
|
for (ModDependencies.Entry entry : getForType(type)) {
|
||||||
|
if (entry.id().equals(id)) {
|
||||||
|
entries.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Entry(Type type, String id, String range, String link, String name) implements ModDependencies.Entry {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.MultimapBuilder;
|
import com.google.common.collect.MultimapBuilder;
|
||||||
|
|
||||||
import dev.frogmc.frogloader.api.mod.ModDependencies;
|
import dev.frogmc.frogloader.api.mod.ModDependencies;
|
||||||
import dev.frogmc.frogloader.api.mod.ModProperties;
|
import dev.frogmc.frogloader.api.mod.ModProperties;
|
||||||
import dev.frogmc.frogloader.api.mod.SemVer;
|
import dev.frogmc.frogloader.api.mod.SemVer;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.nio.file.FileSystem;
|
||||||
import java.nio.file.FileSystems;
|
import java.nio.file.FileSystems;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ import com.electronwill.nightconfig.core.CommentedConfig;
|
||||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
||||||
import com.electronwill.nightconfig.core.file.FileNotFoundAction;
|
import com.electronwill.nightconfig.core.file.FileNotFoundAction;
|
||||||
import com.electronwill.nightconfig.toml.TomlParser;
|
import com.electronwill.nightconfig.toml.TomlParser;
|
||||||
|
|
||||||
import dev.frogmc.frogloader.api.mod.ModDependencies;
|
import dev.frogmc.frogloader.api.mod.ModDependencies;
|
||||||
import dev.frogmc.frogloader.api.mod.ModExtensions;
|
import dev.frogmc.frogloader.api.mod.ModExtensions;
|
||||||
import dev.frogmc.frogloader.api.mod.ModProperties;
|
import dev.frogmc.frogloader.api.mod.ModProperties;
|
||||||
|
@ -124,7 +126,7 @@ public class ModPropertiesReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Function<String, Collection<ModDependencies.Entry>> parseDependencies = key -> {
|
BiFunction<ModDependencies.Type, String, Collection<ModDependencies.Entry>> parseDependencies = (type, key) -> {
|
||||||
Collection<ModDependencies.Entry> result = new HashSet<>();
|
Collection<ModDependencies.Entry> result = new HashSet<>();
|
||||||
|
|
||||||
List<UnmodifiableConfig> dependenciesConfig = config.get("frog.dependencies." + key);
|
List<UnmodifiableConfig> dependenciesConfig = config.get("frog.dependencies." + key);
|
||||||
|
@ -138,7 +140,7 @@ public class ModPropertiesReader {
|
||||||
if (entryId == null || entryId.isEmpty())
|
if (entryId == null || entryId.isEmpty())
|
||||||
badProperties.add("frog.dependencies." + key + '.' + i + ".id");
|
badProperties.add("frog.dependencies." + key + '.' + i + ".id");
|
||||||
|
|
||||||
result.add(new ModDependencies.Entry(entryId, entryVersions, entry.get("link"), entry.get("name")));
|
result.add(new ModDependenciesImpl.Entry(type, entryId, entryVersions, entry.get("link"), entry.get("name")));
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -148,10 +150,10 @@ public class ModPropertiesReader {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var depends = parseDependencies.apply("depends");
|
var depends = parseDependencies.apply(ModDependencies.Type.DEPEND, "depends");
|
||||||
var breaks = parseDependencies.apply("breaks");
|
var breaks = parseDependencies.apply(ModDependencies.Type.BREAK, "breaks");
|
||||||
var suggests = parseDependencies.apply("suggests");
|
var suggests = parseDependencies.apply(ModDependencies.Type.SUGGEST, "suggests");
|
||||||
var provides = parseDependencies.apply("provides");
|
var provides = parseDependencies.apply(ModDependencies.Type.PROVIDE, "provides");
|
||||||
|
|
||||||
UnmodifiableConfig extensionsConfig = config.get("frog.extensions");
|
UnmodifiableConfig extensionsConfig = config.get("frog.extensions");
|
||||||
Map<ModExtensionsImpl.Key, Object> extensions = new HashMap<>();
|
Map<ModExtensionsImpl.Key, Object> extensions = new HashMap<>();
|
||||||
|
@ -169,7 +171,7 @@ public class ModPropertiesReader {
|
||||||
|
|
||||||
|
|
||||||
return new ModPropertiesImpl(id, name, icon, semVer, license, Collections.unmodifiableMap(credits),
|
return new ModPropertiesImpl(id, name, icon, semVer, license, Collections.unmodifiableMap(credits),
|
||||||
new ModDependencies(depends, breaks, suggests, provides), new ModExtensionsImpl(extensions), sources);
|
new ModDependenciesImpl(depends, breaks, suggests, provides), new ModExtensionsImpl(extensions), sources);
|
||||||
});
|
});
|
||||||
|
|
||||||
private static final Map<String, Parser> versions = Arrays.stream(values()).collect(Collectors.toMap(v -> v.version, v -> v.parser));
|
private static final Map<String, Parser> versions = Arrays.stream(values()).collect(Collectors.toMap(v -> v.version, v -> v.parser));
|
||||||
|
|
|
@ -16,11 +16,11 @@ import java.util.stream.Collectors;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import dev.frogmc.frogloader.api.FrogLoader;
|
import dev.frogmc.frogloader.api.FrogLoader;
|
||||||
import dev.frogmc.frogloader.api.mod.ModDependencies;
|
|
||||||
import dev.frogmc.frogloader.api.mod.ModExtensions;
|
import dev.frogmc.frogloader.api.mod.ModExtensions;
|
||||||
import dev.frogmc.frogloader.api.mod.ModProperties;
|
import dev.frogmc.frogloader.api.mod.ModProperties;
|
||||||
import dev.frogmc.frogloader.api.plugin.GamePlugin;
|
import dev.frogmc.frogloader.api.plugin.GamePlugin;
|
||||||
import dev.frogmc.frogloader.impl.FrogLoaderImpl;
|
import dev.frogmc.frogloader.impl.FrogLoaderImpl;
|
||||||
|
import dev.frogmc.frogloader.impl.mod.ModDependenciesImpl;
|
||||||
import dev.frogmc.frogloader.impl.mod.ModExtensionsImpl;
|
import dev.frogmc.frogloader.impl.mod.ModExtensionsImpl;
|
||||||
import dev.frogmc.frogloader.impl.mod.ModPropertiesImpl;
|
import dev.frogmc.frogloader.impl.mod.ModPropertiesImpl;
|
||||||
import dev.frogmc.frogloader.impl.util.SystemProperties;
|
import dev.frogmc.frogloader.impl.util.SystemProperties;
|
||||||
|
@ -203,7 +203,7 @@ public class MinecraftGamePlugin implements GamePlugin {
|
||||||
return new ModPropertiesImpl("minecraft", "Minecraft", "/assets/minecraft/textures/block/grass_block_side.png",
|
return new ModPropertiesImpl("minecraft", "Minecraft", "/assets/minecraft/textures/block/grass_block_side.png",
|
||||||
MinecraftSemVerImpl.get(version), "MC-EULA",
|
MinecraftSemVerImpl.get(version), "MC-EULA",
|
||||||
Map.of("Mojang AB", Collections.singleton("Author")),
|
Map.of("Mojang AB", Collections.singleton("Author")),
|
||||||
new ModDependencies(Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet()),
|
new ModDependenciesImpl(Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet()),
|
||||||
new ModExtensionsImpl(Collections.emptyMap()), Collections.emptySet());
|
new ModExtensionsImpl(Collections.emptyMap()), Collections.emptySet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue