diff --git a/minimal-plugin/src/main/java/io/micronaut/gradle/MicronautExtension.java b/minimal-plugin/src/main/java/io/micronaut/gradle/MicronautExtension.java index 7e4a3c30..fd0bc552 100644 --- a/minimal-plugin/src/main/java/io/micronaut/gradle/MicronautExtension.java +++ b/minimal-plugin/src/main/java/io/micronaut/gradle/MicronautExtension.java @@ -4,6 +4,7 @@ import org.gradle.api.model.ObjectFactory; import org.gradle.api.plugins.ExtensionAware; import org.gradle.api.provider.Property; +import org.gradle.api.provider.SetProperty; import javax.inject.Inject; import java.util.LinkedHashMap; @@ -34,6 +35,16 @@ public abstract class MicronautExtension implements ExtensionAware { */ public abstract Property getImportMicronautPlatform(); + /** + * The Micronaut plugins can automatically add dependencies to your project. + * If, for some reason, a dependency shouldn't be automatically added, you can + * add its coordinates to this set. The format is "group:name". It must not include + * the version. + * + * @return the set of ignored automatic dependencies, as group:name strings. + */ + public abstract SetProperty getIgnoredAutomaticDependencies(); + @Inject public MicronautExtension(ObjectFactory objectFactory, SourceSetConfigurer sourceSetConfigurer) { this.processing = objectFactory.newInstance(AnnotationProcessing.class, sourceSetConfigurer); diff --git a/minimal-plugin/src/main/java/io/micronaut/gradle/internal/AutomaticDependency.java b/minimal-plugin/src/main/java/io/micronaut/gradle/internal/AutomaticDependency.java index 1675677b..adce2588 100644 --- a/minimal-plugin/src/main/java/io/micronaut/gradle/internal/AutomaticDependency.java +++ b/minimal-plugin/src/main/java/io/micronaut/gradle/internal/AutomaticDependency.java @@ -21,11 +21,12 @@ import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.VersionCatalog; import org.gradle.api.artifacts.VersionCatalogsExtension; -import org.gradle.api.artifacts.dsl.DependencyHandler; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; +import java.util.List; import java.util.Optional; +import java.util.Set; /** * Represents a dependency which is automatically @@ -43,36 +44,42 @@ public record AutomaticDependency( ) { public void applyTo(Project p) { p.getPlugins().withType(MicronautComponentPlugin.class, unused -> { - DependencyHandler dependencyHandler = p.getDependencies(); - MicronautExtension micronautExtension = p.getExtensions().getByType(MicronautExtension.class); - dependencyHandler.addProvider(configuration, p.getProviders().provider(() -> { - if (versionProperty.isPresent()) { - Property provider = (Property) micronautExtension.getExtensions().findByName(versionProperty.get().dslName()); - if (provider != null && provider.isPresent()) { - return dependencyHandler.create(coordinates + ":" + provider.get()); + var dependencyHandler = p.getDependencies(); + var micronautExtension = p.getExtensions().getByType(MicronautExtension.class); + var ignoredDependencies = micronautExtension.getIgnoredAutomaticDependencies(); + p.getConfigurations().getByName(configuration).getDependencies().addAllLater( + p.getProviders().provider(() -> { + var ignored = ignoredDependencies.getOrElse(Set.of()); + if (ignored.contains(coordinates)) { + return List.of(); } - } - // If the Micronaut version catalog is applied via the settings plugin, we won't use an "empty" version - // but fetch it from the catalog if possible - VersionCatalogsExtension versionCatalogs = p.getExtensions().findByType(VersionCatalogsExtension.class); - if (versionCatalogs != null) { - Optional mn = versionCatalogs.find("mn"); - if (mn.isPresent()) { - VersionCatalog micronautCatalog = mn.get(); - Optional> dependencyProvider = micronautCatalog.getLibraryAliases() + if (versionProperty.isPresent()) { + Property provider = (Property) micronautExtension.getExtensions().findByName(versionProperty.get().dslName()); + if (provider != null && provider.isPresent()) { + return List.of(dependencyHandler.create(coordinates + ":" + provider.get())); + } + } + // If the Micronaut version catalog is applied via the settings plugin, we won't use an "empty" version + // but fetch it from the catalog if possible + VersionCatalogsExtension versionCatalogs = p.getExtensions().findByType(VersionCatalogsExtension.class); + if (versionCatalogs != null) { + Optional mn = versionCatalogs.find("mn"); + if (mn.isPresent()) { + VersionCatalog micronautCatalog = mn.get(); + Optional> dependencyProvider = micronautCatalog.getLibraryAliases() .stream() .map(micronautCatalog::findLibrary) .map(Optional::get) .filter(d -> coordinates.equals(d.get().getModule().toString())) .findFirst(); - if (dependencyProvider.isPresent()) { - return dependencyProvider.get().get(); + if (dependencyProvider.isPresent()) { + return List.of(dependencyProvider.get().get()); + } } } - } - return dependencyHandler.create(coordinates); - })); - + return List.of(dependencyHandler.create(coordinates)); + }) + ); }); } diff --git a/minimal-plugin/src/test/groovy/io/micronaut/gradle/MicronautMinimalApplicationPluginSpec.groovy b/minimal-plugin/src/test/groovy/io/micronaut/gradle/MicronautMinimalApplicationPluginSpec.groovy index bc75b702..27435867 100644 --- a/minimal-plugin/src/test/groovy/io/micronaut/gradle/MicronautMinimalApplicationPluginSpec.groovy +++ b/minimal-plugin/src/test/groovy/io/micronaut/gradle/MicronautMinimalApplicationPluginSpec.groovy @@ -331,4 +331,36 @@ public class ExampleTest { result.output.contains('Could not find io.micronaut:micronaut-http-server-netty:2048') } + + def "can ignore an automatic dependency"() { + given: + settingsFile << "rootProject.name = 'hello-world'" + buildFile << """ + plugins { + id "io.micronaut.minimal.application" + } + + micronaut { + version "$micronautVersion" + runtime "netty" + testRuntime "junit5" + ignoredAutomaticDependencies.add("io.micronaut:micronaut-inject-java") + } + + $repositoriesBlock + mainClassName="example.Application" + """ + testProjectDir.newFolder("src", "test", "java", "example") + def javaFile = writeExampleClass() + when: + def result = build('test') + + def task = result.task(":test") + println result.output + + then: + !result.output.contains('Creating bean classes for 1 type elements') + task.outcome == TaskOutcome.FAILED + + } }