Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Loader support for quilt.mod.json5 #329

Merged
merged 1 commit into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading