diff --git a/.gitignore b/.gitignore index cfb128f..690a2c9 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,4 @@ config/ build/ input/ /output/ -modlist.html -modlist.md -manifest.json *.mrpack diff --git a/README.md b/README.md index 8b65a17..2ca1279 100644 --- a/README.md +++ b/README.md @@ -12,75 +12,8 @@ OR 2. Run `gradlew build` 3. Get file from path/build/libs/ -## How to use - Modlist +## Detailed information -1. Put the ModListCreator file into a folder -2. Open terminal/cmd -3. Add `modlist` after `java -jar ModListCreator--fatjar.jar` -4. Set arguments listed below -5. After all arguments, set the input files (`folder/*` for whole folder) -6. Run it and wait for output file(s) - -## Arguments you could use - -| Argument | Output | -|------------|---------------------------------------------------------------------------------------------------------------------------------| -| no-header | Generates the file without pack name and version | -| detailed | Shows exact version of each mod | -| format | The output format to use (`txt`, `html`, or `md` (default)) | -| **output** | Defines the output path for generated files. If --pattern is set, describes a directory for output files, else a concrete file. | -| pattern | Defines the output file name pattern. %n is replaced with pack name, %v with pack version. | - -## Examples -### Detailed - -To use this argument, use the following command: - -`$ java -jar ModListCreator--fatjar.jar --detailed` - -| Without argument | With argument | -|---------------------------------|------------------------------------------| -| AIOT Botania (by MelanX) | aiotbotania-1.16.2-1.3.2.jar (by MelanX) | -| Automatic Tool Swap (by MelanX) | ToolSwap-1.16.2-1.2.0.jar (by MelanX) | -| Botania (by Vazkii) | Botania-1.16.3-409.jar (by Vazkii) | - -### No Header - -To use this argument, use the following command: - -`$ java -jar ModListCreator--fatjar.jar --no-header` - -| Without argument | With argument | -|---------------------------------------------|---------------| -| Garden of Glass (Questbook Edition) - 4.2.0 | _nothing_ | - -### Pattern - -To use this argument, use the following command: - -`$ java -jar ModListCreator--fatjar.jar --pattern "This is %n in version %v` - -> This is CaveStone in version 0.4.0 - -### Input - -To use this argument, use the following command: - -`$ java -jar ModListCreator--fatjar.jar --pattern "Name" --output output modpacks/*` - -This will use the folder `modpacks` as input and tries to generate a modlist for each file in this folder. - -### Output - -To use this argument, use the following command: - -`$ java -jar ModListCreator--fatjar.jar --output output.md` - -This will generate a file called `output.md`. If you set `--pattern` argument, it will generate a folder -called `output.md`. - -## Why use this instead of exported modlist? - -- This tool sorts the project names alphabetically -- This tool links to the project and the author -- The official `modlist.html` contains broken links to the projects +This tool works for both, Modrinth and CurseForge modpacks. +- [Changelog](docs/changelogger.md) +- [Modlist](docs/modlist.md) diff --git a/docs/changelogger.md b/docs/changelogger.md new file mode 100644 index 0000000..7e64931 --- /dev/null +++ b/docs/changelogger.md @@ -0,0 +1,17 @@ +# Changelog +## How to use + +1. Put the ModListCreator file into a folder +2. Open terminal/cmd +3. Add `changelog` after `java -jar ModListCreator--fatjar.jar` +4. Set arguments listed below +5. Run it and wait for output file + +## Arguments you could use + +| Argument | Description | +|:----------:|--------------------------------------------------------------------------| +| **old** | Defines the old modpack zip or json file | +| **new** | Defines the new modpack zip or json file | +| **output** | Defines the output file name | +| format | The output format to use (`plain_text`, `html`, or `markdown` (default)) | diff --git a/docs/modlist.md b/docs/modlist.md new file mode 100644 index 0000000..3c40bb0 --- /dev/null +++ b/docs/modlist.md @@ -0,0 +1,73 @@ +# Modlist +## How to use + +1. Put the ModListCreator file into a folder +2. Open terminal/cmd +3. Add `modlist` after `java -jar ModListCreator--fatjar.jar` +4. Set arguments listed below +5. After all arguments, set the input files (`folder/*` for whole folder) +6. Run it and wait for output file(s) + +## Arguments you could use + +| Argument | Description | +|:------------:|---------------------------------------------------------------------------------------------------------------------------------| +| no-header | Generates the file without pack name and version | +| detailed | Shows exact version of each mod | +| format | The output format to use (`plain_text`, `html`, or `markdown` (default)) | +| **output** | Defines the output path for generated files. If --pattern is set, describes a directory for output files, else a concrete file. | +| pattern | Defines the output file name pattern. %n is replaced with pack name, %v with pack version. | + +## Examples +### Detailed + +To use this argument, use the following command: + +`$ java -jar ModListCreator--fatjar.jar --detailed` + +| Without argument | With argument | +|---------------------------------|------------------------------------------| +| AIOT Botania (by MelanX) | aiotbotania-1.16.2-1.3.2.jar (by MelanX) | +| Automatic Tool Swap (by MelanX) | ToolSwap-1.16.2-1.2.0.jar (by MelanX) | +| Botania (by Vazkii) | Botania-1.16.3-409.jar (by Vazkii) | + +### No Header + +To use this argument, use the following command: + +`$ java -jar ModListCreator--fatjar.jar --no-header` + +| Without argument | With argument | +|---------------------------------------------|---------------| +| Garden of Glass (Questbook Edition) - 4.2.0 | _nothing_ | + +### Pattern + +To use this argument, use the following command: + +`$ java -jar ModListCreator--fatjar.jar --pattern "This is %n in version %v` + +> This is CaveStone in version 0.4.0 + +### Input + +To use this argument, use the following command: + +`$ java -jar ModListCreator--fatjar.jar --pattern "Name" --output output modpacks/*` + +This will use the folder `modpacks` as input and tries to generate a modlist for each file in this folder. + +### Output + +To use this argument, use the following command: + +`$ java -jar ModListCreator--fatjar.jar --output output.md` + +This will generate a file called `output.md`. If you set `--pattern` argument, it will generate a folder +called `output.md`. + +## Why use this instead of exported modlist? + +- This tool sorts the project names alphabetically +- This tool links to the project and the author +- The official `modlist.html` from CurseForge exports contains broken links to the projects \ No newline at end of file diff --git a/src/main/java/org/moddingx/modlistcreator/Main.java b/src/main/java/org/moddingx/modlistcreator/Main.java index f119f9f..fd97566 100644 --- a/src/main/java/org/moddingx/modlistcreator/Main.java +++ b/src/main/java/org/moddingx/modlistcreator/Main.java @@ -1,11 +1,22 @@ package org.moddingx.modlistcreator; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.moddingx.modlistcreator.changelogger.Changelogger; import org.moddingx.modlistcreator.modlist.ModListCreator; import java.io.IOException; import java.util.Locale; public class Main { + + public static final Gson GSON; + + static { + GsonBuilder builder = new GsonBuilder(); + builder.disableHtmlEscaping(); + GSON = builder.create(); + } public static void main(String[] args) throws IOException { String cmd = args.length == 0 ? "" : args[0]; @@ -15,9 +26,11 @@ public static void main(String[] args) throws IOException { } switch (cmd.toLowerCase(Locale.ROOT)) { case "modlist" -> ModListCreator.run(newArgs); + case "changelog" -> Changelogger.run(newArgs); default -> { System.err.println("ModListCreator - Choose sub-command\n"); System.err.println(" modlist: Create a modlist file from a CurseForge or Modrinth modpack."); + System.err.println(" changelog: Create a changelog file from a CurseForge or Modrinth modpack."); } } } diff --git a/src/main/java/org/moddingx/modlistcreator/changelogger/ChangelogFormatter.java b/src/main/java/org/moddingx/modlistcreator/changelogger/ChangelogFormatter.java new file mode 100644 index 0000000..03b83b9 --- /dev/null +++ b/src/main/java/org/moddingx/modlistcreator/changelogger/ChangelogFormatter.java @@ -0,0 +1,76 @@ +package org.moddingx.modlistcreator.changelogger; + +import org.moddingx.modlistcreator.output.OutputTarget; +import org.moddingx.modlistcreator.platform.Modpack; + +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +public class ChangelogFormatter { + + public static String format(Modpack from, Modpack to, OutputTarget.Type outputType) { + Map oldInfoBySlug = from.files().stream().collect(Collectors.toMap(Modpack.File::projectSlug, info -> info)); + Map newInfoBySlug = to.files().stream().collect(Collectors.toMap(Modpack.File::projectSlug, info -> info)); + + boolean changedLoader = !from.minecraft().loaderVersion().equals(to.minecraft().loaderVersion()); + List added = to.files().stream() + .filter(file -> !oldInfoBySlug.containsKey(file.projectSlug())) + .sorted(Comparator.comparing(o -> o.projectName().toLowerCase(Locale.ROOT))) + .toList(); + List removed = from.files().stream() + .filter(file -> !newInfoBySlug.containsKey(file.projectSlug())) + .sorted(Comparator.comparing(o -> o.projectName().toLowerCase(Locale.ROOT))) + .toList(); + record ChangedFile(Modpack.File oldFile, Modpack.File newFile) {} + List changed = to.files().stream() + .filter(info -> oldInfoBySlug.containsKey(info.projectSlug())) + .filter(info -> !oldInfoBySlug.get(info.projectSlug()).equals(info)) + .sorted(Comparator.comparing(o -> o.projectName().toLowerCase(Locale.ROOT))) + .map(file -> new ChangedFile(oldInfoBySlug.get(file.projectSlug()), file)) + .toList(); + + OutputTarget target = outputType.create(); + target.addHeader(from.title() + " - " + from.version() + " -> " + to.version()); + if (changedLoader) { + target.addSubHeader(from.minecraft().loader() + " - " + from.minecraft().loaderVersion() + " -> " + to.minecraft().loaderVersion()); + } + + if (added.isEmpty() && removed.isEmpty() && changed.isEmpty()) { + return target.result(); + } + + if (!added.isEmpty()) { + target.addSubHeader("Added"); + target.beginList(false); + for (Modpack.File file : added) { + target.addListElement(target.formatLink(file.projectName(), file.projectWebsite()) + " (by " + target.formatLink(file.author(), file.authorWebsite()) + ")"); + } + target.endList(); + } + + if (!removed.isEmpty()) { + target.addSubHeader("Removed"); + target.beginList(false); + for (Modpack.File file : removed) { + target.addListElement(target.formatLink(file.projectName(), file.projectWebsite()) + " (by " + target.formatLink(file.author(), file.authorWebsite()) + ")"); + } + target.endList(); + } + + if (!changed.isEmpty()) { + target.addSubHeader("Changed"); + target.beginList(false); + for (ChangedFile changedFile : changed) { + String oldFile = target.formatLink(changedFile.oldFile.fileName(), changedFile.oldFile.fileWebsite()); + String newFile = target.formatLink(changedFile.newFile.fileName(), changedFile.newFile.fileWebsite()); + target.addListElement(oldFile + " -> " + newFile); + } + target.endList(); + } + + return target.result(); + } +} diff --git a/src/main/java/org/moddingx/modlistcreator/changelogger/Changelogger.java b/src/main/java/org/moddingx/modlistcreator/changelogger/Changelogger.java new file mode 100644 index 0000000..6814f49 --- /dev/null +++ b/src/main/java/org/moddingx/modlistcreator/changelogger/Changelogger.java @@ -0,0 +1,49 @@ +package org.moddingx.modlistcreator.changelogger; + +import joptsimple.OptionException; +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import joptsimple.OptionSpec; +import joptsimple.util.PathConverter; +import joptsimple.util.PathProperties; +import org.moddingx.modlistcreator.output.OutputTarget; +import org.moddingx.modlistcreator.platform.Modpack; +import org.moddingx.modlistcreator.util.EnumConverters; +import org.moddingx.modlistcreator.util.OptionUtil; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.List; + +public class Changelogger { + + public static void run(String[] args) throws IOException { + OptionParser options = new OptionParser(); + OptionSpec specOld = options.acceptsAll(List.of("o", "old"), "Defines the old modpack zip or json file").withOptionalArg().withValuesConvertedBy(new PathConverter(PathProperties.FILE_EXISTING)); + OptionSpec specNew = options.acceptsAll(List.of("n", "new"), "Defines the new modpack zip or json file").withOptionalArg().withValuesConvertedBy(new PathConverter(PathProperties.FILE_EXISTING)); + OptionSpec specOutput = options.accepts("output", "Defines the output file name").withOptionalArg().ofType(String.class); + OptionSpec specFormat = options.accepts("format", "The output format to use").withRequiredArg().withValuesConvertedBy(EnumConverters.enumArg(OutputTarget.Type.class)).defaultsTo(OutputTarget.Type.MARKDOWN); + + OptionSet set; + try { + set = options.parse(args); + if (!set.has(specOld)) OptionUtil.missing(options, specOld); + if (!set.has(specNew)) OptionUtil.missing(options, specNew); + if (!set.has(specOutput)) OptionUtil.missing(options, specOutput); + } catch (OptionException e) { + System.err.println(e.getMessage() + "\n"); + options.printHelpOn(System.err); + System.exit(1); + throw new Error(); + } + + Modpack from = Modpack.fromPath(set.valueOf(specOld)); + Modpack to = Modpack.fromPath(set.valueOf(specNew)); + Path output = Paths.get(set.valueOf(specOutput)); + Files.writeString(output, ChangelogFormatter.format(from, to, set.valueOf(specFormat)), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + System.exit(0); + } +} diff --git a/src/main/java/org/moddingx/modlistcreator/modlist/ModListCreator.java b/src/main/java/org/moddingx/modlistcreator/modlist/ModListCreator.java index d520c09..ef646d5 100644 --- a/src/main/java/org/moddingx/modlistcreator/modlist/ModListCreator.java +++ b/src/main/java/org/moddingx/modlistcreator/modlist/ModListCreator.java @@ -1,7 +1,5 @@ package org.moddingx.modlistcreator.modlist; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import joptsimple.OptionException; import joptsimple.OptionParser; import joptsimple.OptionSet; @@ -11,12 +9,11 @@ import org.moddingx.modlistcreator.output.OutputTarget; import org.moddingx.modlistcreator.platform.Modpack; import org.moddingx.modlistcreator.util.EnumConverters; +import org.moddingx.modlistcreator.util.OptionUtil; -import javax.annotation.Nullable; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.ProviderNotFoundException; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.List; @@ -28,14 +25,6 @@ public class ModListCreator { - public static Gson GSON; - - static { - GsonBuilder builder = new GsonBuilder(); - builder.disableHtmlEscaping(); - GSON = builder.create(); - } - public static void run(String[] args) throws IOException { OptionParser options = new OptionParser(); OptionSpec specNoHeader = options.accepts("no-header", "Generates the file without pack name and version"); @@ -48,10 +37,10 @@ public static void run(String[] args) throws IOException { OptionSet set; try { set = options.parse(args); - if (!set.has(specOutput)) missing(options, specOutput); - if (!set.has(specPattern) && set.valuesOf(specFormat).size() != 1) missing(options, specPattern, "Name pattern needed for multiple output formats"); - if (!set.has(specPattern) && set.valuesOf(specInput).size() != 1) missing(options, specPattern, "Name pattern needed for multiple input files"); - if (set.valuesOf(specInput).isEmpty()) missing(options, specInput, "No inputs"); + if (!set.has(specOutput)) OptionUtil.missing(options, specOutput); + if (!set.has(specPattern) && set.valuesOf(specFormat).size() != 1) OptionUtil.missing(options, specPattern, "Name pattern needed for multiple output formats"); + if (!set.has(specPattern) && set.valuesOf(specInput).size() != 1) OptionUtil.missing(options, specPattern, "Name pattern needed for multiple input files"); + if (set.valuesOf(specInput).isEmpty()) OptionUtil.missing(options, specInput, "No inputs"); } catch (OptionException e) { System.err.println(e.getMessage() + "\n"); options.printHelpOn(System.err); @@ -59,7 +48,7 @@ public static void run(String[] args) throws IOException { throw new Error(); } - BiFunction outputPaths = outputPathFunc(set.valueOf(specOutput), set.has(specPattern) ? set.valueOf(specPattern) : null); + BiFunction outputPaths = OptionUtil.outputPathFunc(set.valueOf(specOutput), set.has(specPattern) ? set.valueOf(specPattern) : null); List outputTypes = set.valuesOf(specFormat).stream().distinct().toList(); boolean includeHeader = !set.has(specNoHeader); boolean detailed = set.has(specDetailed); @@ -70,7 +59,7 @@ public static void run(String[] args) throws IOException { for (Path path : inputs) { joins.add(executor.submit(() -> { try { - Modpack pack = fromPath(path); + Modpack pack = Modpack.fromPath(path); for (OutputTarget.Type type : outputTypes) { Path outputPath = outputPaths.apply(pack, type); if (!Files.exists(outputPath.getParent())) { @@ -94,35 +83,4 @@ public static void run(String[] args) throws IOException { } System.exit(0); } - - @SuppressWarnings("UnusedReturnValue") - private static T missing(OptionParser options, OptionSpec spec) throws IOException { - return missing(options, spec, "Missing required option"); - } - - private static T missing(OptionParser options, OptionSpec spec, String msg) throws IOException { - System.err.println(msg + ": " + spec + "\n"); - options.printHelpOn(System.err); - System.exit(1); - throw new Error(); - } - - private static BiFunction outputPathFunc(Path basePath, @Nullable String pattern) { - Path normPath = basePath.toAbsolutePath().normalize(); - if (pattern == null) return (pack, type) -> normPath; - return (pack, type) -> normPath.resolve(pattern - .replace("%n", pack.title().replace(' ', '_')) - .replace("%v", pack.version().replace(' ', '_')) - .replace("%%", "%") + "." + type.extension - ); - } - - private static Modpack fromPath(Path path) throws IOException { - try { - return Modpack.loadZip(path); - } catch (ProviderNotFoundException e) { - // Not a zip file - return Modpack.load(path); - } - } } diff --git a/src/main/java/org/moddingx/modlistcreator/output/HtmlTarget.java b/src/main/java/org/moddingx/modlistcreator/output/HtmlTarget.java index d70b793..5f556c7 100644 --- a/src/main/java/org/moddingx/modlistcreator/output/HtmlTarget.java +++ b/src/main/java/org/moddingx/modlistcreator/output/HtmlTarget.java @@ -15,6 +15,11 @@ public void addHeader(String content) { this.tag.appendChild(new Element("h2").append(content)); } + @Override + public void addSubHeader(String content) { + this.tag.appendChild(new Element("h3").append(content)); + } + @Override public void addParagraph(String content) { this.tag.appendChild(new Element("p").append(content)); @@ -38,6 +43,7 @@ public void endList() { } else { this.lists.peek().appendChild(elem); } + this.tag.appendChild(new Element("br")); } @Override diff --git a/src/main/java/org/moddingx/modlistcreator/output/MarkdownTarget.java b/src/main/java/org/moddingx/modlistcreator/output/MarkdownTarget.java index 350cc89..5c3293d 100644 --- a/src/main/java/org/moddingx/modlistcreator/output/MarkdownTarget.java +++ b/src/main/java/org/moddingx/modlistcreator/output/MarkdownTarget.java @@ -13,6 +13,11 @@ public void addHeader(String content) { this.sb.append("## ").append(content).append("\n\n"); } + @Override + public void addSubHeader(String content) { + this.sb.append("### ").append(content).append("\n\n"); + } + @Override public void addParagraph(String content) { this.sb.append(content).append("\n\n"); @@ -39,6 +44,7 @@ public void addListElement(String content) { @Override public void endList() { this.lists.pop(); + this.sb.append("\n"); } @Override diff --git a/src/main/java/org/moddingx/modlistcreator/output/OutputTarget.java b/src/main/java/org/moddingx/modlistcreator/output/OutputTarget.java index 168a1ac..f66eb8e 100644 --- a/src/main/java/org/moddingx/modlistcreator/output/OutputTarget.java +++ b/src/main/java/org/moddingx/modlistcreator/output/OutputTarget.java @@ -6,6 +6,7 @@ public interface OutputTarget { void addHeader(String content); + void addSubHeader(String content); void addParagraph(String content); void beginList(boolean numbered); void addListElement(String content); diff --git a/src/main/java/org/moddingx/modlistcreator/output/PlainTextTarget.java b/src/main/java/org/moddingx/modlistcreator/output/PlainTextTarget.java index d3d4051..367d3e3 100644 --- a/src/main/java/org/moddingx/modlistcreator/output/PlainTextTarget.java +++ b/src/main/java/org/moddingx/modlistcreator/output/PlainTextTarget.java @@ -14,6 +14,12 @@ public void addHeader(String content) { this.sb.append(" ").append("=".repeat(content.length() + 2)).append(" \n\n"); } + @Override + public void addSubHeader(String content) { + this.sb.append(" ").append(content).append(" \n"); + this.sb.append(" ").append("-".repeat(content.length() + 4)).append(" \n\n"); + } + @Override public void addParagraph(String content) { int len = 0; @@ -51,6 +57,7 @@ public void addListElement(String content) { @Override public void endList() { this.lists.pop(); + this.sb.append("\n"); } @Override diff --git a/src/main/java/org/moddingx/modlistcreator/platform/Modpack.java b/src/main/java/org/moddingx/modlistcreator/platform/Modpack.java index e9c6eb7..17473dc 100644 --- a/src/main/java/org/moddingx/modlistcreator/platform/Modpack.java +++ b/src/main/java/org/moddingx/modlistcreator/platform/Modpack.java @@ -1,15 +1,16 @@ package org.moddingx.modlistcreator.platform; import com.google.gson.JsonElement; -import org.moddingx.modlistcreator.modlist.ModListCreator; +import org.moddingx.modlistcreator.Main; -import java.io.*; +import java.io.IOException; +import java.io.Reader; import java.net.URI; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; +import java.nio.file.*; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; public interface Modpack { @@ -17,6 +18,15 @@ public interface Modpack { Minecraft minecraft(); String version(); List files(); + + public static Modpack fromPath(Path path) throws IOException { + try { + return Modpack.loadZip(path); + } catch (ProviderNotFoundException e) { + // Not a zip file + return Modpack.load(path); + } + } static Modpack loadZip(Path path) throws IOException { try (FileSystem fs = FileSystems.newFileSystem(URI.create("jar:" + path.toAbsolutePath().normalize().toUri()), Map.of())) { @@ -33,7 +43,7 @@ static Modpack loadZip(Path path) throws IOException { static Modpack load(Path path) throws IOException { JsonElement json; try (Reader reader = Files.newBufferedReader(path)) { - json = ModListCreator.GSON.fromJson(reader, JsonElement.class); + json = Main.GSON.fromJson(reader, JsonElement.class); } for (Type type : Type.values()) { Optional pack = type.factory.apply(json); @@ -47,7 +57,7 @@ static Modpack load(Path path) throws IOException { static Modpack load(Path path, Type type) throws IOException { JsonElement json; try (Reader reader = Files.newBufferedReader(path)) { - json = ModListCreator.GSON.fromJson(reader, JsonElement.class); + json = Main.GSON.fromJson(reader, JsonElement.class); } Optional pack = type.factory.apply(json); if (pack.isEmpty()) { diff --git a/src/main/java/org/moddingx/modlistcreator/platform/ModrinthModpack.java b/src/main/java/org/moddingx/modlistcreator/platform/ModrinthModpack.java index 763d184..7d36a68 100644 --- a/src/main/java/org/moddingx/modlistcreator/platform/ModrinthModpack.java +++ b/src/main/java/org/moddingx/modlistcreator/platform/ModrinthModpack.java @@ -1,7 +1,7 @@ package org.moddingx.modlistcreator.platform; import com.google.gson.*; -import org.moddingx.modlistcreator.modlist.ModListCreator; +import org.moddingx.modlistcreator.Main; import java.io.IOException; import java.net.URI; @@ -61,7 +61,7 @@ public static Optional load(JsonElement json) throws IOExceptio try { JsonObject filesResponse = makeRequest(HttpRequest.newBuilder() .uri(URI.create("https://api.modrinth.com/v2/version_files")) - .POST(HttpRequest.BodyPublishers.ofString(ModListCreator.GSON.toJson(requestData), StandardCharsets.UTF_8)) + .POST(HttpRequest.BodyPublishers.ofString(Main.GSON.toJson(requestData), StandardCharsets.UTF_8)) .header("Content-Type", "application/json") ).getAsJsonObject(); @@ -97,7 +97,7 @@ record FileData(String projectId, String versionId, String fileName) {} fileData.stream().map(FileData::projectId).distinct().forEach(allProjectIds::add); JsonArray projectsResponse = makeRequest(HttpRequest.newBuilder() .GET() - .uri(URI.create("https://api.modrinth.com/v2/projects?ids=" + URLEncoder.encode(ModListCreator.GSON.toJson(allProjectIds), StandardCharsets.UTF_8))) + .uri(URI.create("https://api.modrinth.com/v2/projects?ids=" + URLEncoder.encode(Main.GSON.toJson(allProjectIds), StandardCharsets.UTF_8))) ).getAsJsonArray(); record ProjectData(String slug, String name, URI website, String teamId) {} @@ -116,7 +116,7 @@ record ProjectData(String slug, String name, URI website, String teamId) {} projectData.values().stream().map(ProjectData::teamId).distinct().forEach(allTeamIds::add); JsonArray teamsResponse = makeRequest(HttpRequest.newBuilder() .GET() - .uri(URI.create("https://api.modrinth.com/v2/teams?ids=" + URLEncoder.encode(ModListCreator.GSON.toJson(allTeamIds), StandardCharsets.UTF_8))) + .uri(URI.create("https://api.modrinth.com/v2/teams?ids=" + URLEncoder.encode(Main.GSON.toJson(allTeamIds), StandardCharsets.UTF_8))) ).getAsJsonArray(); record TeamData(String owner, URI teamURL) {} @@ -168,7 +168,7 @@ private static JsonElement makeRequest(HttpRequest.Builder builder) throws IOExc throw new IOException("HTTP " + response.substring(1)); } else { try { - return ModListCreator.GSON.fromJson(response, JsonElement.class); + return Main.GSON.fromJson(response, JsonElement.class); } catch (JsonParseException e) { throw new IOException("Invalid jso nresponse from modrinth api: " + response, e); } diff --git a/src/main/java/org/moddingx/modlistcreator/util/OptionUtil.java b/src/main/java/org/moddingx/modlistcreator/util/OptionUtil.java new file mode 100644 index 0000000..e97888e --- /dev/null +++ b/src/main/java/org/moddingx/modlistcreator/util/OptionUtil.java @@ -0,0 +1,35 @@ +package org.moddingx.modlistcreator.util; + +import joptsimple.OptionParser; +import joptsimple.OptionSpec; +import org.moddingx.modlistcreator.output.OutputTarget; +import org.moddingx.modlistcreator.platform.Modpack; + +import javax.annotation.Nullable; +import java.io.IOException; +import java.nio.file.Path; +import java.util.function.BiFunction; + +public class OptionUtil { + + public static T missing(OptionParser options, OptionSpec spec) throws IOException { + return missing(options, spec, "Missing required option"); + } + + public static T missing(OptionParser options, OptionSpec spec, String msg) throws IOException { + System.err.println(msg + ": " + spec + "\n"); + options.printHelpOn(System.err); + System.exit(1); + throw new Error(); + } + + public static BiFunction outputPathFunc(Path basePath, @Nullable String pattern) { + Path normPath = basePath.toAbsolutePath().normalize(); + if (pattern == null) return (pack, type) -> normPath; + return (pack, type) -> normPath.resolve(pattern + .replace("%n", pack.title().replace(' ', '_')) + .replace("%v", pack.version().replace(' ', '_')) + .replace("%%", "%") + "." + type.extension + ); + } +}