Skip to content

Commit

Permalink
Add Loader support for quilt.mod.json
Browse files Browse the repository at this point in the history
  • Loading branch information
EnnuiL committed Oct 7, 2024
1 parent 3379b2e commit c0c1bcb
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public static void findCandidatesStatic(ModAdder out) {
if (QuiltLauncherBase.getLauncher().isDevelopment()) {
Map<Path, List<Path>> pathGroups = getPathGroups();
try {
findCandidates("quilt.mod.json5", pathGroups, out);
findCandidates("quilt.mod.json", pathGroups, out);
findCandidates("fabric.mod.json", pathGroups, out);
} catch (IOException e) {
Expand Down Expand Up @@ -84,21 +85,27 @@ private static void findCandidates(String metadataName, Map<Path, List<Path>> pa
Path path = LoaderUtil.normalizeExistingPath(UrlUtil.getCodeSource(url, metadataName));
List<Path> paths = pathGroups.get(path);

if (paths == null) {
if (!url.getProtocol().equals("jar")) {
if (!pathGroups.isEmpty()) {
// path groups are enabled, warn for misconfiguration
Log.error(LogCategory.DISCOVERY,"Mod at path " + url + " lacks a class path group! Make sure the loom 'mods' block " +
"is configured correctly!");
// If this is specifically reading for quilt.mod.json files, we check against QMJ5s as well
// This is so we can ignore QMJs from mods that already have a QMJ5
if (metadataName.equals("quilt.mod.json") && Files.isRegularFile(path.resolve("quilt.mod.json5"))) {
Log.debug(LogCategory.DISCOVERY, "Ignoring quilt.mod.json from mod at path %s that already has a quilt.mod.json5", path);
} else {
if (paths == null) {
if (!url.getProtocol().equals("jar")) {
if (!pathGroups.isEmpty()) {
// path groups are enabled, warn for misconfiguration
Log.error(LogCategory.DISCOVERY,"Mod at path " + url + " lacks a class path group! Make sure the loom 'mods' block " +
"is configured correctly!");
}

Log.error(LogCategory.DISCOVERY, "Mod at path %s is not included in the loom 'mods' block! " +
"This will be an error in a future version of Loader!", path);
}

Log.error(LogCategory.DISCOVERY, "Mod at path %s is not included in the loom 'mods' block! " +
"This will be an error in a future version of Loader!", path);
}

out.addMod(Collections.singletonList(path));
} else {
out.addMod(paths);
out.addMod(Collections.singletonList(path));
} else {
out.addMod(paths);
}
}
} catch (UrlConversionException e) {
Log.debug(LogCategory.DISCOVERY, "Error determining location for %s from %s", metadataName, url, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ public static InternalModMetadata read(InputStream json) throws IOException, Par
public static InternalModMetadata read(InputStream json, Path path, QuiltPluginManager manager, PluginGuiTreeNode warningNode) throws IOException, ParseException {
JsonLoaderValue value;

try (JsonReader reader = JsonReader.json(new InputStreamReader(json, StandardCharsets.UTF_8))) {
try (JsonReader reader = JsonReader.json5(new InputStreamReader(json, StandardCharsets.UTF_8))) {
// Only use the reader as a JSON5 one if we're dealing with a JSON5 file
if (!path.toString().endsWith(".json5")) {
reader.setStrictJson();
}

// Root must be an object
if (reader.peek() != JsonToken.BEGIN_OBJECT) {
throw new ParseException(reader, "A quilt.mod.json must have an object at the root");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,86 @@ private ModLoadOption[] scan0(Path root, QuiltLoaderIcon fileIcon, ModLocation l
PluginGuiTreeNode guiNode) throws IOException {

Path qmj = root.resolve("quilt.mod.json");
if (!FasterFiles.isRegularFile(qmj)) {
Path qmj5 = root.resolve("quilt.mod.json5");
Path usedQmj = qmj;

if (FasterFiles.isRegularFile(qmj5)) {
if (QuiltLoader.isDevelopmentEnvironment()) {
if (Boolean.parseBoolean(System.getProperty(SystemProperties.ENABLE_QUILT_MOD_JSON5_IN_DEV_ENV))) {
if (FasterFiles.exists(qmj)) {
QuiltLoaderText title = QuiltLoaderText.translate("gui.text.qmj_qmj5_coexistence.title");
QuiltDisplayedError error = context().reportError(title);
String describedPath = context().manager().describePath(usedQmj);
error.appendReportText(
"A coexistence of 'quilt.mod.json5' and 'quilt.mod.json' has been detected at " + describedPath,
"These metadata files cannot coexist with each other due to their conflicting purposes!"
);
error.appendDescription(
QuiltLoaderText.translate("gui.text.qmj_qmj5_coexistence.desc.0"),
QuiltLoaderText.translate("gui.text.qmj_qmj5_coexistence.desc.1"),
QuiltLoaderText.translate("gui.text.qmj_qmj5_coexistence.desc.2", describedPath)
);
context().manager().getRealContainingFile(root).ifPresent(real ->
error.addFileViewButton(real)
.icon(QuiltLoaderGui.iconJarFile().withDecoration(QuiltLoaderGui.iconQuilt()))
);

guiNode.addChild(QuiltLoaderText.translate("gui.text.qmj_qmj5_coexistence"));
return null;
} else {
usedQmj = qmj5;
}
} else {
QuiltLoaderText title = QuiltLoaderText.translate("gui.text.qmj5_in_dev_env_not_enabled.title");
QuiltDisplayedError error = context().reportError(title);
String describedPath = context().manager().describePath(usedQmj);
error.appendReportText(
"Attempted to read a 'quilt.mod.json5' file at " + describedPath + " without the support being enabled!",
"If regenerating your run configurations doesn't fix this issue, then your build system doesn't support 'quilt.mod.json5' files!"
);
error.appendDescription(
QuiltLoaderText.translate("gui.text.qmj5_in_dev_env_not_enabled.desc.0"),
QuiltLoaderText.translate("gui.text.qmj5_in_dev_env_not_enabled.desc.1"),
QuiltLoaderText.translate("gui.text.qmj5_in_dev_env_not_enabled.desc.2"),
QuiltLoaderText.translate("gui.text.qmj5_in_dev_env_not_enabled.desc.3", describedPath)
);
context().manager().getRealContainingFile(root).ifPresent(real ->
error.addFileViewButton(real)
.icon(QuiltLoaderGui.iconJarFile().withDecoration(QuiltLoaderGui.iconQuilt()))
);

guiNode.addChild(QuiltLoaderText.translate("gui.text.qmj5_in_dev_env_not_enabled"));
return null;
}
} else {
QuiltLoaderText title = QuiltLoaderText.translate("gui.text.qmj5_on_production.title");
QuiltDisplayedError error = context().reportError(title);
String describedPath = context().manager().describePath(usedQmj);
error.appendReportText(
"An attempt to read a 'quilt.mod.json5' file was detected: " + describedPath,
"'quilt.mod.json5' files can't be used outside of a development environment without converting to a 'quilt.mod.json' file!"
);
error.appendDescription(
QuiltLoaderText.translate("gui.text.qmj5_on_production.desc.0"),
QuiltLoaderText.translate("gui.text.qmj5_on_production.desc.1"),
QuiltLoaderText.translate("gui.text.qmj5_on_production.desc.2", describedPath)
);
context().manager().getRealContainingFile(root).ifPresent(real ->
error.addFileViewButton(real)
.icon(QuiltLoaderGui.iconJarFile().withDecoration(QuiltLoaderGui.iconQuilt()))
);

guiNode.addChild(QuiltLoaderText.translate("gui.text.qmj5_on_production"));
return null;
}
}

if (!FasterFiles.isRegularFile(usedQmj)) {
return null;
}

try {
InternalModMetadata meta = ModMetadataReader.read(qmj, context().manager(), guiNode);
InternalModMetadata meta = ModMetadataReader.read(usedQmj, context().manager(), guiNode);

Path from = root;
if (isZip) {
Expand Down Expand Up @@ -330,7 +404,7 @@ private ModLoadOption[] scan0(Path root, QuiltLoaderIcon fileIcon, ModLocation l
"gui.text.invalid_metadata.title", "quilt.mod.json", parse.getMessage()
);
QuiltDisplayedError error = context().reportError(title);
String describedPath = context().manager().describePath(qmj);
String describedPath = context().manager().describePath(usedQmj);
error.appendReportText("Invalid 'quilt.mod.json' metadata file:" + describedPath);
error.appendDescription(QuiltLoaderText.translate("gui.text.invalid_metadata.desc.0", describedPath));
error.appendThrowable(parse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private SystemProperties() {}
public static final String LOG_CACHE_KEY_CHANGES = "loader.transform_cache.log_changed_keys";
// enable useTempFile in ZipFileSystem, reduces memory usage when writing transform cache at the cost of speed
public static final String USE_ZIPFS_TEMP_FILE = "loader.zipfs.use_temp_file";
public static final String DISABLE_BEACON = "loader.disable_beacon";
public static final String ENABLE_QUILT_MOD_JSON5_IN_DEV_ENV = "loader.enable_quilt_mod_json5_in_dev_env";
public static final String DEBUG_DUMP_FILESYSTEM_CONTENTS = "loader.debug.filesystem.dump_contents";
public static final String ALWAYS_DEFER_FILESYSTEM_OPERATIONS = "loader.workaround.defer_all_filesystem_operations";
public static final String DISABLE_QUILT_CLASS_PATH_CUSTOM_TABLE = "loader.quilt_class_path.disable_custom_table";
Expand Down
16 changes: 16 additions & 0 deletions src/main/resources/lang/quilt_loader.properties
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,22 @@ gui.error.zerobytezip.desc.0=Try deleting the file and downloading it again.
gui.text.invalid_metadata=Invalid Metadata: %s
gui.text.invalid_metadata.title=Unable to read %s: %s
gui.text.invalid_metadata.desc.0=From %s
gui.text.qmj5_on_production=Unconverted 'quilt.mod.json5' found
gui.text.qmj5_on_production.title=Attempted to read an unconverted 'quilt.mod.json5' file
gui.text.qmj5_on_production.desc.0=An attempt to read a 'quilt.mod.json5' file was detected!
gui.text.qmj5_on_production.desc.1='quilt.mod.json5' files can't be used outside a development environment without converting to a 'quilt.mod.json' file!
gui.text.qmj5_on_production.desc.2=From %s
gui.text.qmj_qmj5_coexistence=Coexistence of conflicting Quilt metadata found
gui.text.qmj_qmj5_coexistence.title=Detected the coexistence of conflicting metadata!
gui.text.qmj_qmj5_coexistence.desc.0=A coexistence of 'quilt.mod.json5' and 'quilt.mod.json' has been detected.
gui.text.qmj_qmj5_coexistence.desc.1=These metadata files cannot coexist with each other due to their conflicting purposes!
gui.text.qmj_qmj5_coexistence.desc.2=From %s
gui.text.qmj5_in_dev_env_not_enabled=Found a 'quilt.mod.json5' file without support enabled!
gui.text.qmj5_in_dev_env_not_enabled.title=Found a 'quilt.mod.json5' file without support enabled!
gui.text.qmj5_in_dev_env_not_enabled.desc.0=The Loader support for 'quilt.mod.json5' hasn't been enabled!
gui.text.qmj5_in_dev_env_not_enabled.desc.1=If regenerating your run configurations doesn't fix this issue,
gui.text.qmj5_in_dev_env_not_enabled.desc.2=then your build system doesn't support 'quilt.mod.json5' files!
gui.text.qmj5_in_dev_env_not_enabled.desc.3=From %s
error.unhandled_solver=Complex solver error; see the crash report for more information
error.unhandled_solver.desc=Please try updating quilt-loader to see if an update can describe this.\nOr report this to the quilt-loader project so this can be fixed.
error.unhandled_solver.desc.rule_n= \n \nRule %s (%s):
Expand Down

0 comments on commit c0c1bcb

Please sign in to comment.