Compare commits

..

No commits in common. "83c2c775fe9553033549d4db7d73c099c1512acd" and "c784a8b2860eb081eca783c0c8e5dcf13d3d7067" have entirely different histories.

View file

@ -7,7 +7,6 @@ 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.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.electronwill.nightconfig.core.CommentedConfig; import com.electronwill.nightconfig.core.CommentedConfig;
@ -17,10 +16,7 @@ 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;
import dev.frogmc.frogloader.api.mod.SemVer;
import dev.frogmc.frogloader.impl.SemVerParseException;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -36,7 +32,7 @@ public class ModPropertiesReader {
CommentedConfig props = PARSER.parse(fs.getPath(PROPERTIES_FILE_NAME), FileNotFoundAction.THROW_ERROR); CommentedConfig props = PARSER.parse(fs.getPath(PROPERTIES_FILE_NAME), FileNotFoundAction.THROW_ERROR);
return Optional.of(readProperties(props, Collections.singleton(mod))); return Optional.of(readProperties(props, Collections.singleton(mod)));
} catch (IOException | InvalidModPropertiesException e) { } catch (IOException e) {
LOGGER.warn("Failed to read mod properties: ", e); LOGGER.warn("Failed to read mod properties: ", e);
} }
@ -64,7 +60,7 @@ public class ModPropertiesReader {
return Optional.empty(); return Optional.empty();
} }
private static ModProperties readProperties(UnmodifiableConfig config, Collection<Path> sources) throws InvalidModPropertiesException { private static ModProperties readProperties(UnmodifiableConfig config, Collection<Path> sources) {
String manifestVer = config.get("frog.format_version"); String manifestVer = config.get("frog.format_version");
try { try {
@ -77,91 +73,53 @@ public class ModPropertiesReader {
@AllArgsConstructor @AllArgsConstructor
private enum FormatVersion { private enum FormatVersion {
V1_0_0("1.0.0", (config, sources) -> { V1_0_0("1.0.0", (config, sources) -> {
List<String> badProperties = new ArrayList<>();
String id = config.get("frog.mod.id"); String id = config.get("frog.mod.id");
String name = config.get("frog.mod.name"); String name = config.get("frog.mod.name");
String icon = config.get("frog.mod.icon"); String icon = config.get("frog.mod.icon");
String version = config.get("frog.mod.version"); String version = config.get("frog.mod.version");
String license = Objects.requireNonNullElse(config.get("frog.mod.license"), ""); String license = config.get("frog.mod.license");
if (id == null || id.isEmpty()) if (license == null) {
badProperties.add("frog.mod.id"); license = "";
if (name == null || name.isEmpty())
badProperties.add("frog.mod.name");
SemVer semVer = null;
if (version == null || version.isEmpty())
badProperties.add("frog.mod.version");
else {
try {
semVer = SemVerImpl.parse(version);
} catch (SemVerParseException e) {
badProperties.add("frog.mod.version");
}
} }
List<UnmodifiableConfig> creditsList = config.get("frog.mod.credits"); List<UnmodifiableConfig> creditsList = config.get("frog.mod.credits");
Map<String, Collection<String>> credits = new HashMap<>(); Map<String, Collection<String>> credits = new HashMap<>();
if (creditsList != null) { if (creditsList != null) {
int i = 0; creditsList.forEach(c -> credits.put(c.get("name"), c.get("roles")));
for (UnmodifiableConfig entry : creditsList) {
String entryName = entry.get("name");
Collection<String> entryRoles = entry.get("roles");
if (entryName == null || entryName.isEmpty())
badProperties.add("frog.mod.credits." + i + ".name");
if (entryRoles == null || entryRoles.isEmpty())
badProperties.add("frog.mod.credits." + i + ".name");
credits.put(entryName, entryRoles);
++i;
}
} }
Function<String, Collection<ModDependencies.Entry>> parseDependencies = key -> { Collection<ModDependencies.Entry> depends = new HashSet<>();
Collection<ModDependencies.Entry> result = new HashSet<>(); List<UnmodifiableConfig> dependsConfig = config.get("frog.dependencies.depends");
if (dependsConfig != null) {
List<UnmodifiableConfig> dependenciesConfig = config.get("frog.dependencies." + key); dependsConfig.forEach(entry -> depends.add(new ModDependencies.Entry(entry.get("id"), entry.get("versions"), entry.get("link"), entry.get("name"))));
if (dependenciesConfig != null) {
int i = 0;
for (UnmodifiableConfig entry : dependenciesConfig) {
String entryId = entry.get("id");
String entryVersions = entry.get("versions");
if (entryId == null || entryId.isEmpty())
badProperties.add("frog.dependencies." + key + '.' + i + ".id");
result.add(new ModDependencies.Entry(entryId, entryVersions, entry.get("link"), entry.get("name")));
++i;
}
} }
return result; Collection<ModDependencies.Entry> breaks = new HashSet<>();
}; List<UnmodifiableConfig> breaksConfig = config.get("frog.dependencies.breaks");
if (breaksConfig != null) {
breaksConfig.forEach(entry -> breaks.add(new ModDependencies.Entry(entry.get("id"), entry.get("versions"), entry.get("link"), entry.get("name"))));
}
Collection<ModDependencies.Entry> suggests = new HashSet<>();
List<UnmodifiableConfig> suggestsConfig = config.get("frog.dependencies.suggests");
if (suggestsConfig != null) {
suggestsConfig.forEach(entry -> suggests.add(new ModDependencies.Entry(entry.get("id"), entry.get("versions"), entry.get("link"), entry.get("name"))));
}
var depends = parseDependencies.apply("depends"); Collection<ModDependencies.Entry> provides = new HashSet<>();
var breaks = parseDependencies.apply("breaks"); List<UnmodifiableConfig> providesConfig = config.get("frog.dependencies.provides");
var suggests = parseDependencies.apply("suggests"); if (providesConfig != null) {
var provides = parseDependencies.apply("provides"); providesConfig.forEach(entry -> provides.add(new ModDependencies.Entry(entry.get("id"), entry.get("version"), entry.get("link"), entry.get("name"))));
}
if (!badProperties.isEmpty())
throw new InvalidModPropertiesException(id, sources, badProperties);
UnmodifiableConfig extensionsConfig = config.get("frog.extensions"); UnmodifiableConfig extensionsConfig = config.get("frog.extensions");
Map<String, Object> extensions = new HashMap<>(); Map<String, Object> extensions = new HashMap<>();
if (extensionsConfig != null) if (extensionsConfig != null) {
extensionsConfig.entrySet().forEach(entry -> extensions.put(entry.getKey(), entry.getValue())); extensionsConfig.entrySet().forEach(entry -> extensions.put(entry.getKey(), entry.getValue()));
}
return new ModPropertiesImpl(id, name, icon, semVer, license, Collections.unmodifiableMap(credits), return new ModPropertiesImpl(id, name, icon, SemVerImpl.parse(version), license, Collections.unmodifiableMap(credits),
new ModDependencies(depends, breaks, suggests, provides), ModExtensions.of(extensions), sources); new ModDependencies(depends, breaks, suggests, provides), ModExtensions.of(extensions), sources);
}); });
@ -175,26 +133,8 @@ public class ModPropertiesReader {
@FunctionalInterface @FunctionalInterface
public interface Parser { public interface Parser {
ModProperties parse(UnmodifiableConfig config, Collection<Path> sources) throws IOException, InvalidModPropertiesException; ModProperties parse(UnmodifiableConfig config, Collection<Path> sources) throws IOException;
} }
}
@Getter
public static class InvalidModPropertiesException extends Exception {
private final Collection<String> invalid;
public InvalidModPropertiesException(String id, Collection<Path> sources, Collection<String> invalid) {
super(
"Invalid properties for %s (%s) - invalid or missing values for: %s".formatted(
Objects.requireNonNullElse(id, "<unknown>"),
sources.stream().map(Path::toString).collect(Collectors.joining(", ")),
String.join(", ", invalid)
)
);
this.invalid = invalid;
}
} }
} }