addon dependency sorting

This commit is contained in:
dfsek
2021-11-18 21:13:32 -07:00
parent 9b30d11791
commit 83126454ea
3 changed files with 72 additions and 46 deletions
@@ -1,6 +1,10 @@
package com.dfsek.terra.addons.manifest.impl; package com.dfsek.terra.addons.manifest.impl;
import java.util.List; import java.util.List;
import java.util.Map;
import ca.solostudios.strata.version.Version;
import ca.solostudios.strata.version.VersionRange;
import com.dfsek.terra.addons.manifest.api.AddonInitializer; import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.addons.manifest.impl.config.AddonManifest; import com.dfsek.terra.addons.manifest.impl.config.AddonManifest;
@@ -43,4 +47,18 @@ public class ManifestAddon implements BaseAddon {
initializer.initialize(); initializer.initialize();
}); });
} }
public AddonManifest getManifest() {
return manifest;
}
@Override
public Map<String, VersionRange> getDependencies() {
return manifest.getDependencies();
}
@Override
public Version getVersion() {
return manifest.getVersion();
}
} }
@@ -1,5 +1,6 @@
package com.dfsek.terra.addons.manifest.impl; package com.dfsek.terra.addons.manifest.impl;
import ca.solostudios.strata.Versions;
import ca.solostudios.strata.version.Version; import ca.solostudios.strata.version.Version;
import ca.solostudios.strata.version.VersionRange; import ca.solostudios.strata.version.VersionRange;
import com.dfsek.tectonic.exception.LoadException; import com.dfsek.tectonic.exception.LoadException;
@@ -33,6 +34,8 @@ public class ManifestAddonLoader implements BootstrapBaseAddon<ManifestAddon> {
@Inject @Inject
private Platform platform; private Platform platform;
private static final Version VERSION = Versions.getVersion(1, 0, 0);
@Override @Override
public Iterable<ManifestAddon> loadAddons(Path addonsFolder, ClassLoader parent) { public Iterable<ManifestAddon> loadAddons(Path addonsFolder, ClassLoader parent) {
platform.logger().info("Loading addons..."); platform.logger().info("Loading addons...");
@@ -44,51 +47,51 @@ public class ManifestAddonLoader implements BootstrapBaseAddon<ManifestAddon> {
try { try {
return Files.walk(addonsFolder, 1) return Files.walk(addonsFolder, 1)
.filter(path -> path.toFile().isFile() && path.toString().endsWith(".jar")) .filter(path -> path.toFile().isFile() && path.toString().endsWith(".jar"))
.map(path -> { .map(path -> {
try { try {
platform.getDebugLogger().info("Loading addon from JAR " + path); platform.getDebugLogger().info("Loading addon from JAR " + path);
JarFile jar = new JarFile(path.toFile()); JarFile jar = new JarFile(path.toFile());
JarEntry manifestEntry = jar.getJarEntry("terra.addon.yml"); JarEntry manifestEntry = jar.getJarEntry("terra.addon.yml");
if(manifestEntry == null) { if(manifestEntry == null) {
throw new ManifestNotPresentException("Addon " + path + " does not contain addon manifest."); throw new ManifestNotPresentException("Addon " + path + " does not contain addon manifest.");
} }
try { try {
AddonManifest manifest = manifestLoader.load(new AddonManifest(), AddonManifest manifest = manifestLoader.load(new AddonManifest(),
new YamlConfiguration(jar.getInputStream(manifestEntry), new YamlConfiguration(jar.getInputStream(manifestEntry),
"terra.addon.yml")); "terra.addon.yml"));
platform.logger().info("Loading addon " + manifest.getID()); platform.logger().info("Loading addon " + manifest.getID());
ManifestAddonClassLoader loader = new ManifestAddonClassLoader(new URL[]{ path.toUri().toURL() }, ManifestAddonClassLoader loader = new ManifestAddonClassLoader(new URL[]{ path.toUri().toURL() },
getClass().getClassLoader()); getClass().getClassLoader());
return new ManifestAddon(manifest, manifest.getEntryPoints().stream().map(entryPoint -> { return new ManifestAddon(manifest, manifest.getEntryPoints().stream().map(entryPoint -> {
try { try {
Object in = loader.loadClass(entryPoint).getConstructor().newInstance(); Object in = loader.loadClass(entryPoint).getConstructor().newInstance();
if(!(in instanceof AddonInitializer)) { if(!(in instanceof AddonInitializer)) {
throw new AddonException(in.getClass() + " does not extend " + AddonInitializer.class); throw new AddonException(in.getClass() + " does not extend " + AddonInitializer.class);
} }
return (AddonInitializer) in; return (AddonInitializer) in;
} catch(InvocationTargetException e) { } catch(InvocationTargetException e) {
throw new AddonException("Exception occurred while instantiating addon: ", e); throw new AddonException("Exception occurred while instantiating addon: ", e);
} catch(NoSuchMethodException | IllegalAccessException | InstantiationException e) { } catch(NoSuchMethodException | IllegalAccessException | InstantiationException e) {
throw new AddonException("No valid default constructor found in entry point " + entryPoint); throw new AddonException("No valid default constructor found in entry point " + entryPoint);
} catch(ClassNotFoundException e) { } catch(ClassNotFoundException e) {
throw new AddonException("Entry point " + entryPoint + " not found in JAR."); throw new AddonException("Entry point " + entryPoint + " not found in JAR.");
} }
}).collect(Collectors.toList())); }).collect(Collectors.toList()));
} catch(LoadException e) { } catch(LoadException e) {
throw new ManifestException("Failed to load addon manifest", e); throw new ManifestException("Failed to load addon manifest", e);
} }
} catch(IOException e) { } catch(IOException e) {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);
} }
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} catch(IOException e) { } catch(IOException e) {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);
} }
@@ -98,4 +101,9 @@ public class ManifestAddonLoader implements BootstrapBaseAddon<ManifestAddon> {
public String getID() { public String getID() {
return "MANIFEST"; return "MANIFEST";
} }
@Override
public Version getVersion() {
return VERSION;
}
} }
@@ -36,7 +36,7 @@ public class AddonManifest implements ConfigTemplate, StringIdentifiable {
@Value("depends") @Value("depends")
@Default @Default
private Map<String, VersionRange> dependencies; private Map<String, VersionRange> dependencies = Collections.emptyMap();
@Value("website") @Value("website")
private WebsiteConfig website; private WebsiteConfig website;