Skip to content

Commit

Permalink
WIP Replace arch-loom with ForgeGradle
Browse files Browse the repository at this point in the history
  • Loading branch information
Yeregorix committed Dec 21, 2024
1 parent efb1b64 commit 6ad9559
Show file tree
Hide file tree
Showing 15 changed files with 426 additions and 176 deletions.
3 changes: 3 additions & 0 deletions bootstrap-dev/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies {
api(libs.bootstrap.api)
}
6 changes: 6 additions & 0 deletions bootstrap-dev/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module org.spongepowered.boostrap.dev {
requires net.minecraftforge.bootstrap.api;
exports org.spongepowered.bootstrap.dev;

provides net.minecraftforge.bootstrap.api.BootstrapClasspathModifier with org.spongepowered.bootstrap.dev.SpongeDevClasspathFixer;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.bootstrap.dev;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

public class Multimap<K, V> extends HashMap<K, List<V>> {

public void add(K key, V value) {
this.computeIfAbsent(key, k -> new LinkedList<>()).add(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.vanilla.devlaunch;
package org.spongepowered.bootstrap.dev;

import java.nio.file.Files;
import java.nio.file.Path;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.vanilla.devlaunch;
package org.spongepowered.bootstrap.dev;

import net.minecraftforge.bootstrap.api.BootstrapClasspathModifier;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

Expand All @@ -51,11 +49,12 @@ public String name() {
*/
@Override
public boolean process(final List<Path[]> classpath) {
final Set<String> bootLibs = Set.of(System.getProperty("sponge.dev.boot").split(";"));
final Set<String> gameShadedLibs = Set.of(System.getProperty("sponge.dev.gameShaded").split(";"));
final Set<String> ignoredLibs = Set.of("bootstrap-dev.jar");
final Set<String> bootLibs = Set.of(System.getProperty("sponge.dev.boot").split(File.pathSeparator));
final Set<String> gameShadedLibs = Set.of(System.getProperty("sponge.dev.gameShaded").split(File.pathSeparator));

final Map<String, List<Path>> bootSourceSets = new HashMap<>();
final Map<String, List<Path>> unknownProjects = new HashMap<>();
final Multimap<String, Path> bootSourceSets = new Multimap<>();
final Multimap<String, Path> unknownProjects = new Multimap<>();

final List<Path> spongeImplUnion = new ArrayList<>();
final List<Path> gameLibs = new ArrayList<>();
Expand All @@ -75,8 +74,11 @@ public boolean process(final List<Path[]> classpath) {
}

switch (sourceSet.project()) {
case "modlauncher-transformers":
bootSourceSets.computeIfAbsent("transformers", k -> new LinkedList<>()).add(path);
case "bootstrap-dev":
// ignore
break;
case "modlauncher-transformers", "library-manager":
bootSourceSets.add(sourceSet.project(), path);
break;
case "SpongeAPI":
switch (sourceSet.name()) {
Expand All @@ -91,28 +93,29 @@ public boolean process(final List<Path[]> classpath) {
break;
}
break;
case "Sponge", "vanilla":
switch (sourceSet.name()) {
case "devlaunch":
// ignore
break;
case "applaunch":
bootSourceSets.computeIfAbsent("applaunch", k -> new LinkedList<>()).add(path);
break;
default:
spongeImplUnion.add(path);
break;
case "Sponge", "vanilla", "forge":
if (sourceSet.name().equals("applaunch")) {
bootSourceSets.add("applaunch", path);
} else {
spongeImplUnion.add(path);
}
break;
default:
unknownProjects.computeIfAbsent(sourceSet.project(), k -> new LinkedList<>()).add(path);
unknownProjects.add(sourceSet.project(), path);
break;
}
return true;
}

final String fileName = path.getFileName().toString();

if (ignoredLibs.contains(fileName)) {
if (DEBUG) {
System.out.println("Ignored: " + path);
}
return true;
}

if (bootLibs.contains(fileName)) {
if (DEBUG) {
System.out.println("Boot: " + path);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.spongepowered.bootstrap.dev.SpongeDevClasspathFixer
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@

import javax.annotation.Nullable;
import javax.inject.Inject;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.StringJoiner;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand All @@ -60,33 +63,100 @@ public SpongeImplementationExtension(final Project project, final Logger logger)
this.logger = logger;
}

public void copyModulesExcludingProvided(final Configuration source, final Configuration provided, final Configuration target) {
final DependencyHandler deps = this.project.getDependencies();
private record Module(ModuleIdentifier id, String classifier) {}

public String buildRuntimeFileNames(final Configuration config) {
final Configuration runtimeConfig = this.project.getConfigurations().getByName("runtimeClasspath");

final Map<Module, String> runtimeFileNames = new HashMap<>();
for (final ResolvedArtifact artifact : runtimeConfig.getResolvedConfiguration().getResolvedArtifacts()) {
final ComponentIdentifier id = artifact.getId().getComponentIdentifier();
if (id instanceof ModuleComponentIdentifier moduleId) {
runtimeFileNames.put(new Module(moduleId.getModuleIdentifier(), artifact.getClassifier()), artifact.getFile().getName());
}
}

final StringJoiner joiner = new StringJoiner(File.pathSeparator);

for (final ResolvedArtifact artifact : config.getResolvedConfiguration().getResolvedArtifacts()) {
final ComponentIdentifier id = artifact.getId().getComponentIdentifier();

String fileName = null;
if (id instanceof ModuleComponentIdentifier moduleId) {
fileName = runtimeFileNames.get(new Module(moduleId.getModuleIdentifier(), artifact.getClassifier()));
}

if (fileName == null) {
fileName = artifact.getFile().getName();
}

joiner.add(fileName);
}

return joiner.toString();
}

private String buildDependencyNotation(final ModuleComponentIdentifier moduleId, final String classifier) {
final ModuleIdentifier module = moduleId.getModuleIdentifier();
String notation = module.getGroup() + ":" + module.getName() + ":" + moduleId.getVersion();
if (classifier != null) {
notation += ":" + classifier;
}
return notation;
}

public void copyModulesExcludingProvided(final Configuration source, final Configuration provided, final Configuration target) {
final Map<ModuleIdentifier, String> providedModuleVersions = new HashMap<>();
for (ResolvedArtifact artifact : provided.getResolvedConfiguration().getResolvedArtifacts()) {
for (final ResolvedArtifact artifact : provided.getResolvedConfiguration().getResolvedArtifacts()) {
final ComponentIdentifier id = artifact.getId().getComponentIdentifier();
if (id instanceof ModuleComponentIdentifier) {
final ModuleComponentIdentifier moduleId = (ModuleComponentIdentifier) id;
if (id instanceof ModuleComponentIdentifier moduleId) {
providedModuleVersions.put(moduleId.getModuleIdentifier(), moduleId.getVersion());
}
}

this.copyModulesExcludingPredicate(source, (moduleId) -> {
final ModuleIdentifier module = moduleId.getModuleIdentifier();
final String version = moduleId.getVersion();

final String providedVersion = providedModuleVersions.get(module);
if (providedVersion == null) {
return false;
}

if (!providedVersion.equals(version)) {
this.logger.warn("Version mismatch for module {}. {} expects {} but {} has {}.", module, source.getName(), version, provided.getName(), providedVersion);
}
return true;
}, target);
}

public void copyModulesExcludingPrefix(final Configuration source, final String group, final String namePrefix, final Configuration target) {
this.copyModulesExcludingPredicate(source, (moduleId) -> {
final ModuleIdentifier module = moduleId.getModuleIdentifier();
return module.getGroup().equals(group) && module.getName().startsWith(namePrefix);
}, target);
}

public void copyModulesExcludingExact(final Configuration source, final String group, final String name, final Configuration target) {
this.copyModulesExcludingPredicate(source, (moduleId) -> {
final ModuleIdentifier module = moduleId.getModuleIdentifier();
return module.getGroup().equals(group) && module.getName().equals(name);
}, target);
}

private void copyModulesExcludingPredicate(final Configuration source, final Predicate<ModuleComponentIdentifier> predicate, final Configuration target) {
final DependencyHandler deps = this.project.getDependencies();

for (ResolvedArtifact artifact : source.getResolvedConfiguration().getResolvedArtifacts()) {
final ComponentIdentifier id = artifact.getId().getComponentIdentifier();
if (id instanceof ModuleComponentIdentifier) {
final ModuleComponentIdentifier moduleId = (ModuleComponentIdentifier) id;
final ModuleIdentifier module = moduleId.getModuleIdentifier();
final String version = moduleId.getVersion();

final String providedVersion = providedModuleVersions.get(module);
if (providedVersion == null) {
ModuleDependency dep = (ModuleDependency) deps.create(module.getGroup() + ":" + module.getName() + ":" + version);
dep.setTransitive(false);
target.getDependencies().add(dep);
} else if (!providedVersion.equals(version)) {
this.logger.warn("Version mismatch for module {}. {} expects {} but {} has {}.", module, source.getName(), version, provided.getName(), providedVersion);
if (id instanceof ModuleComponentIdentifier moduleId) {
if (predicate.test(moduleId)) {
continue;
}

final ModuleDependency dep = (ModuleDependency) deps.create(this.buildDependencyNotation(moduleId, artifact.getClassifier()));
dep.setTransitive(false);
target.getDependencies().add(dep);
}

// projects are not copied because we cannot always recreate properly a project dependency from the resolved artefact
Expand Down
Loading

0 comments on commit 6ad9559

Please sign in to comment.