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

Rework mod discovery, resolution and loading #461

Merged
merged 5 commits into from
Jul 3, 2021
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
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ dependencies {
implementation 'net.fabricmc:tiny-remapper:0.4.2'
implementation 'net.fabricmc:access-widener:1.0.0'

implementation 'com.google.jimfs:jimfs:1.2-fabric'
implementation 'net.fabricmc:fabric-loader-sat4j:2.3.5.4'
implementation 'org.ow2.sat4j:org.ow2.sat4j.core:2.3.6'
implementation 'org.ow2.sat4j:org.ow2.sat4j.pb:2.3.6'

// launchwrapper + dependencies
implementation ('net.minecraft:launchwrapper:1.12') {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ group = net.fabricmc
description = The mod loading component of Fabric
url = https://github.com/FabricMC/fabric-loader

version = 0.11.6
version = 0.12.0
asm_version = 9.1
20 changes: 8 additions & 12 deletions src/main/java/net/fabricmc/loader/api/SemanticVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import java.util.Optional;

import net.fabricmc.loader.impl.util.version.VersionDeserializer;
import net.fabricmc.loader.impl.util.version.VersionParser;

/**
* Represents a <a href="https://semver.org/">Sematic Version</a>.
Expand All @@ -28,7 +28,7 @@
*
* @see Version
*/
public interface SemanticVersion extends Version, Comparable<SemanticVersion> {
public interface SemanticVersion extends Version {
/**
* The value of {@linkplain #getVersionComponent(int) version component} that indicates
* a {@linkplain #hasWildcard() wildcard}.
Expand Down Expand Up @@ -87,16 +87,12 @@ public interface SemanticVersion extends Version, Comparable<SemanticVersion> {
boolean hasWildcard();

/**
* {@inheritDoc}
*
* <p>Comparison of semantic versions is by the version components, from high to low;
* then it falls back to comparing the prerelease notations.</p>
*
* @param o the other version
* @return the result of comparison
* @deprecated Use {@link #compareTo(Version)} instead
*/
@Override
int compareTo(SemanticVersion o);
@Deprecated
default int compareTo(SemanticVersion o) {
return compareTo((Version) o);
}

/**
* Parses a semantic version from a string notation.
Expand All @@ -106,6 +102,6 @@ public interface SemanticVersion extends Version, Comparable<SemanticVersion> {
* @throws VersionParsingException if a problem arises during version parsing
*/
static SemanticVersion parse(String s) throws VersionParsingException {
return VersionDeserializer.deserializeSemantic(s);
return VersionParser.parseSemantic(s);
}
}
6 changes: 3 additions & 3 deletions src/main/java/net/fabricmc/loader/api/Version.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
package net.fabricmc.loader.api;

import net.fabricmc.loader.api.metadata.ModMetadata;
import net.fabricmc.loader.impl.util.version.VersionDeserializer;
import net.fabricmc.loader.impl.util.version.VersionParser;

/**
* Represents a version of a mod.
*
* @see ModMetadata#getVersion()
*/
public interface Version {
public interface Version extends Comparable<Version> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any concern here from potential existing implementations which wouldn't implement Comparable? I can't think of any but it is technically a backward compatibility problem

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, are users even supposed to implement this interface?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They shouldn't need to, but that hasn't stopped people doing odd things with internals in the past

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really supported and somewhat pointless (can't put that Version anywhere in loader). The JVM doesn't verify whether a class implements everything, so would only throw AbstractMethodError on access.

/**
* Returns the user-friendly representation of this version.
*/
Expand All @@ -38,6 +38,6 @@ public interface Version {
* @throws VersionParsingException if a problem arises during version parsing
*/
static Version parse(String string) throws VersionParsingException {
return VersionDeserializer.deserialize(string);
return VersionParser.parse(string, false);
}
}
145 changes: 0 additions & 145 deletions src/main/java/net/fabricmc/loader/api/VersionPredicate.java

This file was deleted.

71 changes: 68 additions & 3 deletions src/main/java/net/fabricmc/loader/api/metadata/ModDependency.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,22 @@

package net.fabricmc.loader.api.metadata;

import java.util.Set;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import net.fabricmc.loader.api.Version;
import net.fabricmc.loader.api.VersionPredicate;
import net.fabricmc.loader.api.metadata.version.VersionPredicate;

/**
* Represents a dependency.
*/
public interface ModDependency {
/**
* Get the kind of dependency.
*/
Kind getKind();

/**
* Returns the ID of the mod to check.
*/
Expand All @@ -42,5 +49,63 @@ public interface ModDependency {
*
* @return representation of the dependency's version requirements
*/
Set<VersionPredicate> getVersionRequirements();
Collection<VersionPredicate> getVersionRequirements();

enum Kind {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a find of 'kind'. Would 'type', 'relation', or 'relationship' be better here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"type" is too overloaded with other meanings in this concept, relation* is wrong since ModDependency itself is the relation. Not sure what's wrong with calling depends, recommends , ... kinds of dependencies.

DEPENDS("depends", true, false),
RECOMMENDS("recommends", true, true),
SUGGESTS("suggests", true, true),
CONFLICTS("conflicts", false, true),
BREAKS("breaks", false, false);

private static final Map<String, Kind> map = createMap();
private final String key;
private final boolean positive;
private final boolean soft;

Kind(String key, boolean positive, boolean soft) {
this.key = key;
this.positive = positive;
this.soft = soft;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd document this better and give it a more meaningful name to clarify that dependency kinds that are soft only produce warnings rather than failing mod resolution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's to indicate it being a soft dependency (opposite of a hard dependency), whether it produces a warning is unspecified (suggests doesn't, recommends/conflicts do)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a hard dependency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hard = must be met, soft = should be met

}

/**
* Get the key for the dependency as used by fabric.mod.json (v1+) and dependency overrides.
*/
public String getKey() {
return key;
}

/**
* Get whether the dependency is positive, encouraging the inclusion of a mod instead of negative/discouraging.
*/
public boolean isPositive() {
return positive;
}

/**
* Get whether it is a soft dependency, allowing the mod to still load if the dependency is unmet.
*/
public boolean isSoft() {
return soft;
}

/**
* Parse a dependency kind from its key as provided by {@link #getKey}.
*/
public static Kind parse(String key) {
return map.get(key);
}

private static Map<String, Kind> createMap() {
Kind[] values = values();
Map<String, Kind> ret = new HashMap<>(values.length);

for (Kind kind : values) {
ret.put(kind.key, kind);
}

return ret;
}
}
}
Loading