Skip to content

Commit cadfa68

Browse files
committed
and then God said, let there be fish
- game can now be launched with Cichlid and mods can load - reworked natives extraction again - started work on the sushi artifact transform
1 parent cedd061 commit cadfa68

File tree

14 files changed

+231
-70
lines changed

14 files changed

+231
-70
lines changed

build.gradle.kts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@ val mcVer = "1.17.1"
1818

1919
dependencies {
2020
implementation(minecraft.client(mcVer))
21-
// compile against Cichlid API
22-
// compileOnly(cichlid.loaderApi("0.1.0"))
23-
// run with full Cichlid
24-
// runtimeOnly(cichlid.loader("0.1.0"))
21+
compileOnly(cichlid.api("0.3.2"))
22+
cichlidRuntime(cichlid.runtime("0.3.2"))
2523
}
2624

2725
cichlid {

plugin/src/main/java/io/github/cichlidmc/cichlid_gradle/CichlidGradlePlugin.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,22 @@
77
import io.github.cichlidmc.cichlid_gradle.extension.repo.CichlidReposExtension;
88
import io.github.cichlidmc.cichlid_gradle.extension.repo.MinecraftReposExtension;
99
import io.github.cichlidmc.cichlid_gradle.run.RunTaskGeneration;
10+
import io.github.cichlidmc.cichlid_gradle.transform.TransformedAttribute;
11+
import org.gradle.api.NamedDomainObjectProvider;
1012
import org.gradle.api.Plugin;
1113
import org.gradle.api.Project;
14+
import org.gradle.api.artifacts.ConfigurationContainer;
1215
import org.gradle.api.artifacts.Dependency;
16+
import org.gradle.api.artifacts.DependencyScopeConfiguration;
1317

1418
import java.util.Objects;
1519

1620
public abstract class CichlidGradlePlugin implements Plugin<Project> {
1721
public static final String NAME = "CichlidGradle";
1822
public static final String VERSION = "1.0-SNAPSHOT";
1923

24+
public static final String CICHLID_CONFIGURATION = "cichlid";
25+
2026
@Override
2127
public void apply(Project project) {
2228
CichlidExtension.setup(project);
@@ -25,9 +31,13 @@ public void apply(Project project) {
2531
CichlidDepsExtension.setup(project);
2632
MinecraftDepsExtension.setup(project);
2733
RunTaskGeneration.setup(project);
34+
TransformedAttribute.setup(project);
35+
36+
ConfigurationContainer configurations = project.getConfigurations();
37+
setupConfigurations(configurations);
2838

2939
// listen for all minecraft dependencies to ensure they're downloaded
30-
project.getConfigurations().configureEach(
40+
configurations.configureEach(
3141
configuration -> configuration.getDependencies().configureEach(dep -> {
3242
if (isMinecraftDependency(dep)) {
3343
String version = Objects.requireNonNull(dep.getVersion());
@@ -38,6 +48,20 @@ public void apply(Project project) {
3848
);
3949
}
4050

51+
private static void setupConfigurations(ConfigurationContainer configurations) {
52+
// configurations for Cichlid.
53+
// you need one configuration for declaring dependencies and another extending it for resolution
54+
NamedDomainObjectProvider<DependencyScopeConfiguration> cichlidRuntime = configurations.dependencyScope("cichlidRuntime");
55+
// resolvable configuration is non-transitive so it only includes Cichlid itself
56+
configurations.resolvable(CICHLID_CONFIGURATION, resolvable -> resolvable.extendsFrom(cichlidRuntime.get()).setTransitive(false));
57+
58+
// add Cichlid and its dependencies to the runtime classpath
59+
configurations.named("runtimeClasspath", runtime -> runtime.extendsFrom(cichlidRuntime.get()));
60+
61+
// compile classpath must be transformed
62+
configurations.named("compileClasspath", compile -> compile.getAttributes().attribute(TransformedAttribute.INSTANCE, true));
63+
}
64+
4165
private static boolean isMinecraftDependency(Dependency dep) {
4266
return "net.minecraft".equals(dep.getGroup())
4367
&& CichlidCache.MINECRAFT_MODULES.contains(dep.getName())

plugin/src/main/java/io/github/cichlidmc/cichlid_gradle/cache/storage/NativesStorage.java

Lines changed: 0 additions & 15 deletions
This file was deleted.

plugin/src/main/java/io/github/cichlidmc/cichlid_gradle/cache/storage/VersionStorage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class VersionStorage extends LockableStorage {
1616

1717
public final MappingsStorage mappings;
1818
public final JarsStorage jars;
19-
public final NativesStorage natives;
19+
public final Path natives;
2020
public final RunTemplateStorage runs;
2121

2222
public final Path completeMarker;
@@ -26,7 +26,7 @@ public VersionStorage(Path root, String version) {
2626
this.version = version;
2727
this.mappings = new MappingsStorage(root.resolve("mappings"));
2828
this.jars = new JarsStorage(root.resolve("jars"), version);
29-
this.natives = new NativesStorage(root.resolve("natives"));
29+
this.natives = root.resolve("natives");
3030
this.runs = new RunTemplateStorage(root.resolve("runs"));
3131
this.completeMarker = root.resolve(COMPLETE_MARKER);
3232
}

plugin/src/main/java/io/github/cichlidmc/cichlid_gradle/cache/task/impl/AssetsTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public void doRun() throws IOException {
4444
for (Asset asset : fullIndex.objects.values()) {
4545
Path dest = this.storage.object(asset);
4646
if (this.shouldDownload(asset, dest)) {
47-
FileUtils.downloadSilently(asset, dest);
47+
FileUtils.download(asset, dest);
4848
}
4949
}
5050

plugin/src/main/java/io/github/cichlidmc/cichlid_gradle/cache/task/impl/ExtractNativesTask.java

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,82 @@
11
package io.github.cichlidmc.cichlid_gradle.cache.task.impl;
22

3-
import io.github.cichlidmc.cichlid_gradle.cache.storage.NativesStorage;
43
import io.github.cichlidmc.cichlid_gradle.cache.task.CacheTask;
54
import io.github.cichlidmc.cichlid_gradle.cache.task.TaskContext;
65
import io.github.cichlidmc.cichlid_gradle.util.FileUtils;
7-
import io.github.cichlidmc.cichlid_gradle.util.IterableStream;
86
import io.github.cichlidmc.pistonmetaparser.FullVersion;
7+
import io.github.cichlidmc.pistonmetaparser.version.library.Artifact;
98
import io.github.cichlidmc.pistonmetaparser.version.library.Classifier;
109
import io.github.cichlidmc.pistonmetaparser.version.library.Library;
1110
import io.github.cichlidmc.pistonmetaparser.version.library.Natives;
1211

1312
import java.io.IOException;
1413
import java.nio.file.FileSystem;
1514
import java.nio.file.FileSystems;
15+
import java.nio.file.FileVisitResult;
1616
import java.nio.file.Files;
1717
import java.nio.file.Path;
18+
import java.nio.file.SimpleFileVisitor;
19+
import java.nio.file.attribute.BasicFileAttributes;
1820
import java.util.Optional;
1921

2022
public class ExtractNativesTask extends CacheTask {
2123
public static final String TEMP_JAR = "temp-jar-for-extracting.jar";
2224

23-
private final NativesStorage storage;
25+
private final Path path;
2426
private final FullVersion version;
2527

26-
protected ExtractNativesTask(TaskContext context, NativesStorage storage, FullVersion version) {
28+
protected ExtractNativesTask(TaskContext context, Path path, FullVersion version) {
2729
super("ExtractNatives", "Extract native dependencies", context);
28-
this.storage = storage;
30+
this.path = path;
2931
this.version = version;
3032
}
3133

3234
@Override
3335
protected void doRun() throws IOException {
34-
Path folder = this.storage.folder(this.version.id);
35-
3636
for (Library library : this.version.libraries) {
37+
if (library.artifact.isPresent()) {
38+
this.downloadAndExtract(library.artifact.get());
39+
}
40+
3741
Optional<Classifier> maybeClassifier = library.natives.flatMap(Natives::choose);
3842
if (maybeClassifier.isPresent()) {
3943
Classifier classifier = maybeClassifier.get();
40-
this.downloadAndExtract(classifier, folder);
44+
this.downloadAndExtract(classifier.artifact);
4145
}
4246
}
4347
}
4448

45-
private void downloadAndExtract(Classifier classifier, Path folder) throws IOException {
46-
Path tempJar = folder.resolve(TEMP_JAR);
47-
FileUtils.downloadSilently(classifier.artifact, tempJar);
49+
// note: rd-20090515 has the exact same jinput dependency twice for some reason, and is probably not the only weird one.
50+
// this information isn't really relevant after some refactoring, but it's good to keep it around.
51+
private void downloadAndExtract(Artifact artifact) throws IOException {
52+
Path tempJar = this.path.resolve(TEMP_JAR);
53+
FileUtils.downloadSilently(artifact, tempJar);
4854

4955
try (FileSystem fs = FileSystems.newFileSystem(tempJar)) {
5056
// jar should have 1 root
5157
Path root = fs.getRootDirectories().iterator().next();
52-
try (IterableStream<Path> files = new IterableStream<>(Files.list(root))) {
53-
for (Path file : files) {
58+
Files.walkFileTree(root, new SimpleFileVisitor<>() {
59+
@Override
60+
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
5461
// the version manifest specifies files that should be excluded from extraction,
5562
// but it's undocumented and a pain to handle, and it doesn't even matter in the end
5663
// as far as I can tell. The only relevant case is META-INF, which needs to be skipped
5764
// to avoid duplicates. META-INF also seems to be the only thing ever specified
5865
// as an exclusion, so it makes sense.
66+
// class files are also skipped, since we're just extracting the entire jar. Cuts out most files.
5967
String fileName = file.getFileName().toString();
60-
if (!fileName.endsWith("META-INF")) {
61-
Path dest = folder.resolve(fileName);
62-
// rd-20090515 has the exact same jinput dependency twice for some reason.
63-
// it's probably not the only weird one.
68+
if (!fileName.endsWith("META-INF") && !fileName.endsWith(".class")) {
69+
Path relative = root.relativize(file);
70+
Path dest = ExtractNativesTask.this.path.resolve(relative.toString());
6471
if (!Files.exists(dest)) {
72+
Files.createDirectories(dest.getParent());
6573
Files.copy(file, dest);
6674
}
6775
}
76+
77+
return FileVisitResult.CONTINUE;
6878
}
69-
}
79+
});
7080
}
7181

7282
Files.delete(tempJar);

plugin/src/main/java/io/github/cichlidmc/cichlid_gradle/extension/dep/CichlidDepsExtension.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,39 @@
22

33
import org.gradle.api.Project;
44
import org.gradle.api.artifacts.Dependency;
5-
import org.gradle.api.artifacts.dsl.DependencyHandler;
5+
import org.gradle.api.artifacts.ExternalModuleDependency;
6+
import org.gradle.api.artifacts.dsl.DependencyFactory;
67

78
public class CichlidDepsExtension {
89
// can't use managed properties - https://github.com/gradle/gradle/issues/18213
9-
private final DependencyHandler deps;
10+
private final DependencyFactory factory;
1011

11-
private CichlidDepsExtension(DependencyHandler deps) {
12-
this.deps = deps;
12+
private CichlidDepsExtension(DependencyFactory factory) {
13+
this.factory = factory;
1314
}
1415

15-
public Dependency loader(String version) {
16-
return this.deps.create("io.github.cichlidmc:cichlid:" + version);
16+
public ExternalModuleDependency runtime(String version) {
17+
return this.factory.create("io.github.cichlidmc", "cichlid", version);
1718
}
1819

19-
public Dependency loaderApi(String version) {
20-
return this.deps.create("io.github.cichlidmc:cichlid:" + version + ":api");
20+
public ExternalModuleDependency api(String version) {
21+
ExternalModuleDependency dep = this.runtime(version);
22+
dep.capabilities(handler -> handler.requireCapability("io.github.cichlidmc:cichlid-mod-api"));
23+
return dep;
2124
}
2225

23-
public Dependency devPlugin(String version) {
24-
return this.deps.create("io.github.cichlidmc:dev-plugin:" + version);
26+
public ExternalModuleDependency pluginApi(String version) {
27+
ExternalModuleDependency dep = this.runtime(version);
28+
dep.capabilities(handler -> handler.requireCapability("io.github.cichlidmc:cichlid-plugin-api"));
29+
return dep;
30+
}
31+
32+
public Dependency cichlibs(String version) {
33+
return this.factory.create("io.github.cichlidmc:cichlibs:" + version);
2534
}
2635

2736
public static void setup(Project project) {
28-
CichlidDepsExtension mc = new CichlidDepsExtension(project.getDependencies());
37+
CichlidDepsExtension mc = new CichlidDepsExtension(project.getDependencyFactory());
2938
project.getDependencies().getExtensions().add("cichlid", mc);
3039
}
3140
}

plugin/src/main/java/io/github/cichlidmc/cichlid_gradle/extension/repo/MinecraftReposExtension.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package io.github.cichlidmc.cichlid_gradle.extension.repo;
22

33
import io.github.cichlidmc.cichlid_gradle.cache.CichlidCache;
4+
import org.gradle.api.Action;
45
import org.gradle.api.Project;
56
import org.gradle.api.artifacts.dsl.RepositoryHandler;
7+
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
68
import org.gradle.api.plugins.ExtensionAware;
79

810
import java.net.URI;
@@ -14,10 +16,15 @@ private MinecraftReposExtension(Project project) {
1416
this.project = project;
1517
}
1618

17-
public void libraries() {
18-
this.project.getRepositories().maven(repo -> {
19+
public MavenArtifactRepository libraries() {
20+
return this.libraries(repo -> {});
21+
}
22+
23+
public MavenArtifactRepository libraries(Action<? super MavenArtifactRepository> action) {
24+
return this.project.getRepositories().maven(repo -> {
1925
repo.setName("Minecraft Libraries");
2026
repo.setUrl(URI.create("https://libraries.minecraft.net/"));
27+
action.execute(repo);
2128
});
2229
}
2330

plugin/src/main/java/io/github/cichlidmc/cichlid_gradle/run/RunTaskGeneration.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package io.github.cichlidmc.cichlid_gradle.run;
22

3+
import io.github.cichlidmc.cichlid_gradle.CichlidGradlePlugin;
34
import io.github.cichlidmc.cichlid_gradle.cache.CichlidCache;
45
import io.github.cichlidmc.cichlid_gradle.cache.storage.VersionStorage;
56
import io.github.cichlidmc.cichlid_gradle.extension.CichlidExtension;
67
import io.github.cichlidmc.cichlid_gradle.util.ListPatch;
78
import org.gradle.api.Project;
9+
import org.gradle.api.artifacts.Configuration;
810
import org.gradle.api.provider.Property;
911
import org.gradle.api.provider.Provider;
1012
import org.gradle.api.tasks.JavaExec;
@@ -59,10 +61,13 @@ private static void generateTask(RunConfiguration config, CichlidCache cache, Pr
5961
task.setWorkingDir(runDir);
6062
task.doFirst($ -> runDir.mkdirs());
6163

64+
Configuration cichlid = project.getConfigurations().getByName(CichlidGradlePlugin.CICHLID_CONFIGURATION);
65+
for (File agent : cichlid.getFiles()) {
66+
task.jvmArgs("-javaagent:" + agent.getAbsolutePath() + "=dist=" + templateName + ",version=" + version);
67+
}
68+
6269
Placeholders.DynamicContext ctx = new Placeholders.DynamicContext(
63-
runDir.toPath(),
64-
versionCache.natives.root,
65-
cache.assets.root
70+
runDir.toPath(), versionCache.natives, cache.assets.root
6671
);
6772
task.args(getArgs(config.getProgramArgs(), template.programArgs(), ctx));
6873
task.jvmArgs(getArgs(config.getJvmArgs(), template.jvmArgs(), ctx));
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package io.github.cichlidmc.cichlid_gradle.transform;
2+
3+
import org.gradle.api.artifacts.transform.InputArtifact;
4+
import org.gradle.api.artifacts.transform.InputArtifactDependencies;
5+
import org.gradle.api.artifacts.transform.TransformAction;
6+
import org.gradle.api.artifacts.transform.TransformOutputs;
7+
import org.gradle.api.artifacts.transform.TransformParameters;
8+
import org.gradle.api.file.FileCollection;
9+
import org.gradle.api.file.FileSystemLocation;
10+
import org.gradle.api.logging.Logger;
11+
import org.gradle.api.logging.Logging;
12+
import org.gradle.api.provider.Provider;
13+
import org.gradle.api.tasks.PathSensitive;
14+
import org.gradle.api.tasks.PathSensitivity;
15+
16+
import java.io.File;
17+
import java.io.IOException;
18+
import java.nio.file.Files;
19+
20+
// @CacheableTransform
21+
public abstract class SushiTransformAction implements TransformAction<TransformParameters.None> {
22+
private static final Logger logger = Logging.getLogger(SushiTransformAction.class);
23+
24+
@InputArtifact
25+
@PathSensitive(PathSensitivity.NAME_ONLY)
26+
public abstract Provider<FileSystemLocation> getInput();
27+
28+
@InputArtifactDependencies
29+
@PathSensitive(PathSensitivity.NAME_ONLY)
30+
public abstract FileCollection getDependencies();
31+
32+
@Override
33+
public void transform(TransformOutputs outputs) {
34+
File file = this.getInput().get().getAsFile();
35+
String name = file.getName();
36+
37+
if (!name.endsWith(".jar") || true) {
38+
File output = outputs.file(file);
39+
copy(file, output);
40+
return;
41+
}
42+
43+
logger.quiet("transformed " + name);
44+
for (File dep : getDependencies()) {
45+
logger.quiet("\t- " + dep.getName());
46+
}
47+
48+
String newName = name.replace(".jar", "-transformed.jar");
49+
File output = outputs.file(newName);
50+
copy(file, output);
51+
}
52+
53+
private static void copy(File from, File to) {
54+
try {
55+
Files.copy(from.toPath(), to.toPath());
56+
} catch (IOException e) {
57+
throw new RuntimeException(e);
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)