Skip to content

Commit

Permalink
Allow duplicate libraries in the installer profile to make sure they …
Browse files Browse the repository at this point in the history
…always match specified tool versions
  • Loading branch information
Technici4n committed Nov 14, 2024
1 parent afe4d61 commit 026d7fe
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ static NeoDevConfigurations createAndSetup(Project project) {
// Resolvable configurations.
//

/**
* Resolved {@link #neoFormDataOnly}.
* This is used to add NeoForm to the installer libraries.
* Only the zip is used (for the mappings), not the NeoForm tools, so it's not transitive.
*/
final Configuration neoFormDataOnly;
/**
* Resolvable {@link #neoFormDependencies}.
*/
Expand Down Expand Up @@ -84,12 +90,6 @@ static NeoDevConfigurations createAndSetup(Project project) {
* This is also used to produce the legacy classpath file for server installs.
*/
final Configuration launcherProfileClasspath;
/**
* Libraries that need to be downloaded and installed by the installer.
* This includes all dependencies added by NeoForge, the NeoForm archive,
* and all dependencies needed by the various tools that the installer runs.
*/
final Configuration installerProfileLibraries;

//
// The configurations for resolution only are declared in the build.gradle file.
Expand Down Expand Up @@ -117,22 +117,27 @@ private NeoDevConfigurations(ConfigurationContainer configurations) {
userdevCompileOnly = dependencyScope(configurations, "userdevCompileOnly");
userdevTestFixtures = dependencyScope(configurations, "userdevTestFixtures");

neoFormDataOnly = resolvable(configurations, "neoFormDataOnly");
neoFormClasspath = resolvable(configurations, "neoFormClasspath");
modulePath = resolvable(configurations, "modulePath");
userdevClasspath = resolvable(configurations, "userdevClasspath");
userdevCompileOnlyClasspath = resolvable(configurations, "userdevCompileOnlyClasspath");
userdevTestClasspath = resolvable(configurations, "userdevTestClasspath");
launcherProfileClasspath = resolvable(configurations, "launcherProfileClasspath");
installerProfileLibraries = resolvable(configurations, "installerProfileLibraries");

// Libraries & module libraries & MC dependencies need to be available when compiling in NeoDev,
// and on the runtime classpath too for IDE debugging support.
configurations.getByName("implementation").extendsFrom(libraries, moduleLibraries, neoFormDependencies);

// runtimeClasspath is our reference for all dependency versions.
// Make sure that any configuration we resolve are consistent with it.
// runtimeClasspath is our reference for all MC dependency versions.
// Make sure that any classpath we resolve is consistent with it.
var runtimeClasspath = configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);

neoFormDataOnly.setTransitive(false);
neoFormDataOnly.extendsFrom(neoFormData);

neoFormClasspath.extendsFrom(neoFormDependencies);

modulePath.extendsFrom(moduleLibraries);
modulePath.shouldResolveConsistentlyWith(runtimeClasspath);

Expand All @@ -147,9 +152,5 @@ private NeoDevConfigurations(ConfigurationContainer configurations) {

launcherProfileClasspath.extendsFrom(libraries, moduleLibraries);
launcherProfileClasspath.shouldResolveConsistentlyWith(runtimeClasspath);

installerProfileLibraries.extendsFrom(libraries, moduleLibraries, neoFormData);
installerProfileLibraries.shouldResolveConsistentlyWith(runtimeClasspath);
// Installer tools are also added to `installerProfileLibraries`, from NeoDevPlugin.
}
}
13 changes: 9 additions & 4 deletions buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,11 @@ public void apply(Project project) {
task.getNeoForgeVersion().set(neoForgeVersion);
task.getMcAndNeoFormVersion().set(mcAndNeoFormVersion);
task.getIcon().set(project.getRootProject().file("docs/assets/neoforged.ico"));
task.setLibraries(configurations.installerProfileLibraries);
// Anything that is on the launcher classpath should be downloaded by the installer.
// (At least on the server side).
task.addLibraries(configurations.launcherProfileClasspath);
// We need the NeoForm zip for the SRG mappings.
task.addLibraries(configurations.neoFormDataOnly);
task.getRepositoryURLs().set(project.provider(() -> {
List<URI> repos = new ArrayList<>();
for (var repo : project.getRepositories().withType(MavenArtifactRepository.class)) {
Expand All @@ -267,10 +271,11 @@ public void apply(Project project) {
files.setCanBeResolved(true);
files.getDependencies().add(installerProcessor.tool.asDependency(project));
});
configurations.installerProfileLibraries.extendsFrom(configuration);
// Each tool should resolve consistently with the full set of installed libraries.
configuration.shouldResolveConsistentlyWith(configurations.installerProfileLibraries);
createInstallerProfile.configure(task -> {
// Add installer processor.
// Different processors might use different versions of the same library,
// but that is fine because each processor gets its own classpath.
task.addLibraries(configuration);
task.getProcessorClasspaths().put(installerProcessor, DependencyUtils.configurationToGavList(configuration));
task.getProcessorGavs().put(installerProcessor, installerProcessor.tool.asGav(project));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.gson.GsonBuilder;
import net.neoforged.neodev.utils.FileUtils;
import net.neoforged.neodev.utils.MavenIdentifier;
import org.gradle.api.DefaultTask;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.RegularFileProperty;
Expand Down Expand Up @@ -46,8 +47,8 @@ public CreateInstallerProfile() {}
@Nested
protected abstract ListProperty<IdentifiedFile> getLibraryFiles();

public void setLibraries(Configuration libraries) {
getLibraryFiles().set(IdentifiedFile.listFromConfiguration(getProject(), libraries));
public void addLibraries(Configuration libraries) {
getLibraryFiles().addAll(IdentifiedFile.listFromConfiguration(getProject(), libraries));
}

@Input
Expand Down Expand Up @@ -134,8 +135,23 @@ public void createInstallerProfile() throws IOException {
);

getLogger().info("Collecting libraries for Installer Profile");
// Remove potential duplicates.
var libraryFilesToResolve = new LinkedHashMap<MavenIdentifier, IdentifiedFile>(getLibraryFiles().get().size());
for (var libraryFile : getLibraryFiles().get()) {
var existingFile = libraryFilesToResolve.putIfAbsent(libraryFile.getIdentifier().get(), libraryFile);
if (existingFile != null) {
var existing = existingFile.getFile().getAsFile().get();
var duplicate = libraryFile.getFile().getAsFile().get();
if (!existing.equals(duplicate)) {
throw new IllegalArgumentException("Cannot resolve installer profile! Library %s has different files: %s and %s.".formatted(
libraryFile.getIdentifier().get(),
existing,
duplicate));
}
}
}
var libraries = new ArrayList<>(
LibraryCollector.resolveLibraries(getRepositoryURLs().get(), getLibraryFiles().get()));
LibraryCollector.resolveLibraries(getRepositoryURLs().get(), libraryFilesToResolve.values()));

var universalJar = getUniversalJar().getAsFile().get().toPath();
libraries.add(new Library(
Expand Down

0 comments on commit 026d7fe

Please sign in to comment.