diff --git a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java index c0da3e8d..ca131136 100644 --- a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java @@ -29,7 +29,6 @@ import org.gradle.api.Project; import org.gradle.api.artifacts.ArtifactRepositoryContainer; import org.gradle.api.artifacts.dsl.RepositoryHandler; import org.gradle.api.artifacts.repositories.ArtifactRepository; -import org.gradle.api.artifacts.repositories.IvyArtifactRepository; import org.gradle.api.artifacts.repositories.MavenArtifactRepository; import org.gradle.api.initialization.Settings; import org.gradle.api.invocation.Gradle; @@ -62,10 +61,8 @@ public class LoomRepositoryPlugin implements Plugin { } private void declareRepositories(RepositoryHandler repositories, LoomFiles files, ExtensionAware target) { - repositories.maven(repo -> { - repo.setName("UserLocalRemappedMods"); - repo.setUrl(files.getRemappedModCache()); - }); + declareLocalRepositories(repositories, files); + repositories.maven(repo -> { repo.setName("Fabric"); repo.setUrl(MirrorUtil.getFabricRepository(target)); @@ -93,17 +90,22 @@ public class LoomRepositoryPlugin implements Plugin { } repositories.mavenCentral(); + } - repositories.ivy(repo -> { - repo.setUrl(files.getUserCache()); - repo.patternLayout(layout -> layout.artifact("[revision]/[artifact](-[classifier])(.[ext])")); - repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); + private void declareLocalRepositories(RepositoryHandler repositories, LoomFiles files) { + repositories.maven(repo -> { + repo.setName("LoomLocalRemappedMods"); + repo.setUrl(files.getRemappedModCache()); }); - repositories.ivy(repo -> { - repo.setUrl(files.getRootProjectPersistentCache()); - repo.patternLayout(layout -> layout.artifact("[revision]/[artifact](-[classifier])(.[ext])")); - repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); + repositories.maven(repo -> { + repo.setName("LoomGlobalMinecraft"); + repo.setUrl(files.getGlobalMinecraftRepo()); + }); + + repositories.maven(repo -> { + repo.setName("LoomLocalMinecraft"); + repo.setUrl(files.getLocalMinecraftRepo()); }); } diff --git a/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java index 71029e8f..f1cb169f 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2021 FabricMC + * Copyright (c) 2021-2022 FabricMC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,20 +24,32 @@ package net.fabricmc.loom.configuration.ide.idea; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.gradle.StartParameter; import org.gradle.TaskExecutionRequest; import org.gradle.api.Project; +import org.gradle.api.Task; import org.gradle.api.tasks.TaskProvider; import org.gradle.internal.DefaultTaskExecutionRequest; +import org.jetbrains.annotations.Nullable; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.configuration.ide.RunConfigSettings; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; import net.fabricmc.loom.task.LoomTasks; public class IdeaConfiguration { + private static final String INIT_SCRIPT_NAME = "ijmiscinit"; + private static final Pattern NOTATION_PATTERN = Pattern.compile("'net\\.minecraft:(?.*):(.*):sources'"); + public static void setup(Project project) { TaskProvider ideaSyncTask = project.getTasks().register("ideaSyncTask", IdeaSyncTask.class, task -> { if (LoomGradleExtension.get(project).getRunConfigs().stream().anyMatch(RunConfigSettings::isIdeConfigGenerated)) { @@ -47,6 +59,12 @@ public class IdeaConfiguration { } }); + project.getTasks().configureEach(task -> { + if (task.getName().equals("DownloadSources")) { + hookDownloadSources(project, task); + } + }); + if (!IdeaUtils.isIdeaSync()) { return; } @@ -57,4 +75,63 @@ public class IdeaConfiguration { taskRequests.add(new DefaultTaskExecutionRequest(List.of("ideaSyncTask"))); startParameter.setTaskRequests(taskRequests); } + + /* + "Parse" the init script enough to figure out what jar we are talking about. + + Intelij code: https://github.com/JetBrains/intellij-community/blob/a09b1b84ab64a699794c860bc96774766dd38958/plugins/gradle/java/src/util/GradleAttachSourcesProvider.java + */ + private static void hookDownloadSources(Project project, Task task) { + List initScripts = project.getGradle().getStartParameter().getInitScripts(); + + for (File initScript : initScripts) { + if (!initScript.getName().contains(INIT_SCRIPT_NAME)) { + continue; + } + + try { + final String script = Files.readString(initScript.toPath(), StandardCharsets.UTF_8); + final String notation = parseInitScript(project, script); + + if (notation != null) { + task.dependsOn(getGenSourcesTaskName(LoomGradleExtension.get(project), notation)); + } + } catch (IOException e) { + // Ignore + } + } + } + + @Nullable + private static String parseInitScript(Project project, String script) { + if (!script.contains("Attempt to download sources from") + || !script.contains("downloadSources_") + || !script.contains("'%s'".formatted(project.getPath()))) { + // Failed some basic sanity checks. + return null; + } + + // A little gross but should do the job nicely. + final Matcher matcher = NOTATION_PATTERN.matcher(script); + + if (matcher.find()) { + return matcher.group("name"); + } + + return null; + } + + private static String getGenSourcesTaskName(LoomGradleExtension extension, String notation) { + final MinecraftJarConfiguration configuration = extension.getMinecraftJarConfiguration().get(); + + if (configuration == MinecraftJarConfiguration.SPLIT) { + if (notation.contains("minecraft-clientOnly")) { + return "genClientOnlySources"; + } + + return "genCommonSources"; + } + + return "genSources"; + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/dependency/LocalMavenHelper.java b/src/main/java/net/fabricmc/loom/configuration/mods/dependency/LocalMavenHelper.java index 4d7e31e7..33af9b96 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/dependency/LocalMavenHelper.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/dependency/LocalMavenHelper.java @@ -32,25 +32,22 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import org.gradle.api.Project; import org.jetbrains.annotations.Nullable; -import net.fabricmc.loom.LoomGradleExtension; - public final class LocalMavenHelper { private final String group; private final String name; private final String version; @Nullable private final String baseClassifier; - private final Project project; + private final Path root; - LocalMavenHelper(String group, String name, String version, @Nullable String classifier, Project project) { + public LocalMavenHelper(String group, String name, String version, @Nullable String classifier, Path root) { this.group = group; this.name = name; this.version = version; this.baseClassifier = classifier; - this.project = project; + this.root = root; } public Path copyToMaven(Path artifact, @Nullable String classifier) throws IOException { @@ -75,7 +72,7 @@ public final class LocalMavenHelper { return String.format("%s:%s:%s", group, name, version); } - private void savePom() { + public void savePom() { try { String pomTemplate; @@ -94,13 +91,8 @@ public final class LocalMavenHelper { } } - private Path getRoot() { - final LoomGradleExtension extension = LoomGradleExtension.get(project); - return extension.getFiles().getRemappedModCache().toPath(); - } - private Path getDirectory() { - return getRoot().resolve("%s/%s/%s".formatted(group.replace(".", "/"), name, version)); + return root.resolve("%s/%s/%s".formatted(group.replace(".", "/"), name, version)); } private Path getPomPath() { diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/dependency/ModDependency.java b/src/main/java/net/fabricmc/loom/configuration/mods/dependency/ModDependency.java index 2cde009c..bfcd0b02 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/dependency/ModDependency.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/dependency/ModDependency.java @@ -69,7 +69,9 @@ public abstract sealed class ModDependency permits SplitModDependency, SimpleMod public abstract void applyToProject(Project project); protected LocalMavenHelper createMaven(String name) { - return new LocalMavenHelper(getRemappedGroup(), name, this.version, this.classifier, this.project); + final LoomGradleExtension extension = LoomGradleExtension.get(project); + final Path root = extension.getFiles().getRemappedModCache().toPath(); + return new LocalMavenHelper(getRemappedGroup(), name, this.version, this.classifier, root); } public ArtifactRef getInputArtifact() { diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java index 609045fe..291cfa46 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java @@ -152,6 +152,10 @@ public final class MinecraftJarProcessorManager { } private boolean processMappings(MemoryMappingTree mappings, MappingProcessorContext context) { + if (mappingsProcessor() == null) { + return false; + } + return mappingsProcessor().transform(mappings, spec, context); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java index 4e18410f..6686a131 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java @@ -24,24 +24,31 @@ package net.fabricmc.loom.configuration.providers.minecraft; +import java.io.File; import java.nio.file.Path; import java.util.Objects; public abstract sealed class MinecraftJar permits MinecraftJar.Merged, MinecraftJar.Common, MinecraftJar.ServerOnly, MinecraftJar.ClientOnly { private final Path path; private final boolean merged, client, server; + private final String name; - protected MinecraftJar(Path path, boolean merged, boolean client, boolean server) { + protected MinecraftJar(Path path, boolean merged, boolean client, boolean server, String name) { this.path = Objects.requireNonNull(path); this.merged = merged; this.client = client; this.server = server; + this.name = name; } public Path getPath() { return path; } + public File toFile() { + return getPath().toFile(); + } + public boolean isMerged() { return merged; } @@ -54,27 +61,53 @@ public abstract sealed class MinecraftJar permits MinecraftJar.Merged, Minecraft return server; } + public String getName() { + return name; + } + + public abstract MinecraftJar forPath(Path path); + public static final class Merged extends MinecraftJar { public Merged(Path path) { - super(path, true, true, true); + super(path, true, true, true, "merged"); + } + + @Override + public MinecraftJar forPath(Path path) { + return new Merged(path); } } public static final class Common extends MinecraftJar { public Common(Path path) { - super(path, false, false, true); + super(path, false, false, true, "common"); + } + + @Override + public MinecraftJar forPath(Path path) { + return new Common(path); } } public static final class ServerOnly extends MinecraftJar { public ServerOnly(Path path) { - super(path, false, false, true); + super(path, false, false, true, "serverOnly"); + } + + @Override + public MinecraftJar forPath(Path path) { + return new ServerOnly(path); } } public static final class ClientOnly extends MinecraftJar { public ClientOnly(Path path) { - super(path, false, true, false); + super(path, false, true, false, "clientOnly"); + } + + @Override + public MinecraftJar forPath(Path path) { + return new ClientOnly(path); } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java index 63550225..d88d3dd9 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java @@ -24,22 +24,28 @@ package net.fabricmc.loom.configuration.providers.minecraft.mapped; +import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.function.Function; import org.gradle.api.Project; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.configuration.ConfigContext; +import net.fabricmc.loom.configuration.mods.dependency.LocalMavenHelper; import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJar; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets; import net.fabricmc.loom.configuration.providers.minecraft.SignatureFixerApplyVisitor; +import net.fabricmc.loom.extension.LoomFiles; import net.fabricmc.loom.util.TinyRemapperHelper; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; @@ -91,24 +97,53 @@ public abstract class AbstractMappedMinecraftProvider fileFunction; + + MavenScope(Function fileFunction) { + this.fileFunction = fileFunction; + } + + public Path getRoot(LoomGradleExtension extension) { + return fileFunction.apply(extension.getFiles()).toPath(); + } + } + + public abstract MavenScope getMavenScope(); + + public LocalMavenHelper getMavenHelper(String name) { + return new LocalMavenHelper("net.minecraft", getName(name), getVersion(), null, getMavenScope().getRoot(extension)); } protected String getName(String name) { - return "minecraft-%s-%s".formatted(name, getTargetNamespace().toString()); + if (getTargetNamespace() != MappingsNamespace.NAMED) { + name = getTargetNamespace().name().toLowerCase(Locale.ROOT) + "-" + name; + } + + return "minecraft-" + name; + } + + protected String getVersion() { + return "%s-%s".formatted(extension.getMinecraftProvider().minecraftVersion(), extension.getMappingConfiguration().mappingsIdentifier()); } protected String getDependencyNotation(String name) { - return "net.minecraft:%s:%s/%s".formatted(getName(name), extension.getMinecraftProvider().minecraftVersion(), extension.getMappingConfiguration().mappingsIdentifier()); + return "net.minecraft:%s:%s".formatted(getName(name), getVersion()); } private boolean areOutputsValid(List remappedJars) { for (RemappedJars remappedJar : remappedJars) { - if (!Files.exists(remappedJar.outputJar())) { + if (!getMavenHelper(remappedJar.name()).exists(null)) { return false; } } @@ -129,7 +164,7 @@ public abstract class AbstractMappedMinecraftProvider remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingConfiguration, getProject(), configContext.serviceManager(), toM); TinyRemapper remapper = TinyRemapperHelper.getTinyRemapper(getProject(), configContext.serviceManager(), fromM, toM, true, (builder) -> { @@ -137,7 +172,7 @@ public abstract class AbstractMappedMinecraftProvider remappedJars) throws IOException { for (RemappedJars remappedJar : remappedJars) { - Files.deleteIfExists(remappedJar.outputJar()); + Files.deleteIfExists(remappedJar.outputJarPath()); } } @@ -175,6 +212,13 @@ public abstract class AbstractMappedMinecraftProvider implements Merged { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java index 73b0caa9..4ea32349 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java @@ -44,13 +44,13 @@ public interface MappedMinecraftProvider { interface Merged extends ProviderImpl { String MERGED = "merged"; - default Path getMergedJar() { - return getJar(MERGED); + default MinecraftJar getMergedJar() { + return new MinecraftJar.Merged(getJar(MERGED)); } @Override default List getMinecraftJars() { - return List.of(new MinecraftJar.Merged(getMergedJar())); + return List.of(getMergedJar()); } } @@ -58,17 +58,17 @@ public interface MappedMinecraftProvider { String COMMON = "common"; String CLIENT_ONLY = "clientOnly"; - default Path getCommonJar() { - return getJar(COMMON); + default MinecraftJar getCommonJar() { + return new MinecraftJar.Common(getJar(COMMON)); } - default Path getClientOnlyJar() { - return getJar(CLIENT_ONLY); + default MinecraftJar getClientOnlyJar() { + return new MinecraftJar.ClientOnly(getJar(CLIENT_ONLY)); } @Override default List getMinecraftJars() { - return List.of(new MinecraftJar.Common(getCommonJar()), new MinecraftJar.ClientOnly(getClientOnlyJar())); + return List.of(getCommonJar(), getClientOnlyJar()); } } @@ -79,13 +79,13 @@ public interface MappedMinecraftProvider { return "%sOnly".formatted(env()); } - default Path getEnvOnlyJar() { - return getJar(envName()); + default MinecraftJar getEnvOnlyJar() { + return env().getJar().apply(getJar(envName())); } @Override default List getMinecraftJars() { - return List.of(env().getJar().apply(getEnvOnlyJar())); + return List.of(getEnvOnlyJar()); } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java index 97de6d96..bf66d5be 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java @@ -24,7 +24,6 @@ package net.fabricmc.loom.configuration.providers.minecraft.mapped; -import java.nio.file.Path; import java.util.List; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; @@ -43,13 +42,13 @@ public abstract class NamedMinecraftProvider extend } @Override - protected Path getDirectory() { - return extension.getMappingConfiguration().mappingsWorkingDir(); + public final MappingsNamespace getTargetNamespace() { + return MappingsNamespace.NAMED; } @Override - public final MappingsNamespace getTargetNamespace() { - return MappingsNamespace.NAMED; + public MavenScope getMavenScope() { + return MavenScope.GLOBAL; } public static final class MergedImpl extends NamedMinecraftProvider implements Merged { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java index 18413335..d3297130 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java @@ -25,14 +25,14 @@ package net.fabricmc.loom.configuration.providers.minecraft.mapped; import java.io.IOException; -import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.util.List; import java.util.Objects; -import net.fabricmc.loom.LoomGradleExtension; +import org.gradle.api.Project; + +import net.fabricmc.loom.configuration.mods.dependency.LocalMavenHelper; import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.configuration.processors.ProcessorContextImpl; import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; @@ -46,20 +46,11 @@ import net.fabricmc.loom.configuration.providers.minecraft.SplitMinecraftProvide public abstract class ProcessedNamedMinecraftProvider> extends NamedMinecraftProvider { private final P parentMinecraftProvider; private final MinecraftJarProcessorManager jarProcessorManager; - private final String projectMappedName; - private final Path projectMappedDir; public ProcessedNamedMinecraftProvider(P parentMinecraftProvide, MinecraftJarProcessorManager jarProcessorManager) { super(parentMinecraftProvide.getConfigContext(), parentMinecraftProvide.getMinecraftProvider()); this.parentMinecraftProvider = parentMinecraftProvide; this.jarProcessorManager = Objects.requireNonNull(jarProcessorManager); - - this.projectMappedName = "minecraft-project-%s-".formatted(getProject().getPath().replace(':', '@')); - - final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); - this.projectMappedDir = extension.getFiles().getRootProjectPersistentCache().toPath() - .resolve(getMinecraftProvider().minecraftVersion()) - .resolve(extension.getMappingConfiguration().mappingsIdentifier()); } @Override @@ -78,21 +69,20 @@ public abstract class ProcessedNamedMinecraftProvider path.getFileName().startsWith(jar.getFileName().toString().replace(".jar", ""))).toList()) { Files.deleteIfExists(path); } @@ -120,7 +115,14 @@ public abstract class ProcessedNamedMinecraftProvider getMinecraftJarPaths() { - return getParentMinecraftProvider().getMinecraftJarPaths().stream() + public List getMinecraftJars() { + return getParentMinecraftProvider().getMinecraftJars().stream() .map(this::getProcessedPath) .toList(); } @@ -145,8 +147,9 @@ public abstract class ProcessedNamedMinecraftProvider implements Merged { @@ -155,7 +158,7 @@ public abstract class ProcessedNamedMinecraftProvider split.getClientOnlyJar().toAbsolutePath().toString(); - case "common" -> split.getCommonJar().toAbsolutePath().toString(); + case "client" -> split.getClientOnlyJar().getPath().toAbsolutePath().toString(); + case "common" -> split.getCommonJar().getPath().toAbsolutePath().toString(); default -> throw new UnsupportedOperationException(); }; }