diff --git a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardExtension.kt b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardExtension.kt index a2ba652..7580420 100644 --- a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardExtension.kt +++ b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardExtension.kt @@ -33,6 +33,7 @@ import org.gradle.api.artifacts.MinimalExternalModuleDependency import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Provider import org.gradle.kotlin.dsl.listProperty +import org.gradle.kotlin.dsl.property import javax.inject.Inject abstract class ProjectGuardExtension @Inject constructor( @@ -42,10 +43,8 @@ abstract class ProjectGuardExtension @Inject constructor( private val guardSpecs = objects.listProperty() private val moduleRestrictionSpecs = objects.listProperty() private val dependencyRestrictionSpecs = objects.listProperty() - private var reportSpec = ReportSpec(showLibrariesInGraph = false) - private var options = PluginOptions( - lifecycleTask = null - ) + private val reportSpec = objects.property().convention(ReportSpec(showLibrariesInGraph = false)) + private val options = objects.property().convention(PluginOptions(lifecycleTask = null)) override fun restrictModule(modulePath: String, action: Action) { val scope = ModuleRestrictionScopeImpl() @@ -127,17 +126,13 @@ abstract class ProjectGuardExtension @Inject constructor( override fun report(action: Action) { val scope = ReportScopeImpl() action.execute(scope) - reportSpec = reportSpec.copy( - showLibrariesInGraph = scope.showLibrariesInGraph - ) + reportSpec.set(ReportSpec(showLibrariesInGraph = scope.showLibrariesInGraph)) } override fun options(action: Action) { val scope = OptionScopeImpl() action.execute(scope) - options = options.copy( - lifecycleTask = scope.lifecycleTask, - ) + options.set(PluginOptions(lifecycleTask = scope.lifecycleTask)) } internal fun getSpec(): ProjectGuardSpec { @@ -145,8 +140,8 @@ abstract class ProjectGuardExtension @Inject constructor( guardSpecs = guardSpecs.get(), moduleRestrictionSpecs = moduleRestrictionSpecs.get(), dependencyRestrictionSpecs = dependencyRestrictionSpecs.get(), - reportSpec = reportSpec, - options = options + reportSpec = reportSpec.get(), + options = options.get() ) } diff --git a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardPlugin.kt b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardPlugin.kt index fe210a9..2b2f413 100644 --- a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardPlugin.kt +++ b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardPlugin.kt @@ -292,7 +292,7 @@ class ProjectGuardPlugin : Plugin { ) { group = "verification" description = "Verifies if there are any dependency restrictions" - reportSpec.set(extension.getSpec().reportSpec) + pluginSpec.set(project.provider { extension.getSpec() }) outputs.upToDateWhen { false } } } @@ -307,7 +307,7 @@ class ProjectGuardPlugin : Plugin { ) { group = "verification" description = "Verifies if there are any dependency restrictions" - reportSpec.set(extension.getSpec().reportSpec) + pluginSpec.set(project.provider { extension.getSpec() }) outputs.upToDateWhen { false } } } @@ -323,7 +323,7 @@ class ProjectGuardPlugin : Plugin { group = "other" description = "Generates a JSON report of all dependency restrictions for this module." projectPath.set(project.path) - specProperty.set(extension.getSpec()) + specProperty.set(project.provider { extension.getSpec() }) outputFile.set( project.layout.buildDirectory.file(jsonReportFilePath) ) @@ -340,7 +340,7 @@ class ProjectGuardPlugin : Plugin { group = "other" description = "Generates a JSON containing the dependencies of this module." projectPath.set(project.path) - dependencyGraph.set(graphBuilder.buildFromProject(project)) + dependencyGraph.set(project.provider { graphBuilder.buildFromProject(project) }) outputFile.set( project.layout.buildDirectory.file(dependenciesFilePath) ) diff --git a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskAggregateDependencyDump.kt b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskAggregateDependencyDump.kt index 5f5fa47..494d8d1 100644 --- a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskAggregateDependencyDump.kt +++ b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskAggregateDependencyDump.kt @@ -23,7 +23,6 @@ import kotlinx.serialization.json.Json import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.RegularFileProperty -import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.PathSensitive @@ -31,7 +30,6 @@ import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import java.io.File -@CacheableTask internal abstract class TaskAggregateDependencyDump : DefaultTask() { @get:InputFiles diff --git a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskAggregateRestrictionDump.kt b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskAggregateRestrictionDump.kt index 45088e9..678ab1c 100644 --- a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskAggregateRestrictionDump.kt +++ b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskAggregateRestrictionDump.kt @@ -23,7 +23,6 @@ import kotlinx.serialization.json.Json import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.RegularFileProperty -import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.PathSensitive @@ -31,7 +30,6 @@ import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import java.io.File -@CacheableTask internal abstract class TaskAggregateRestrictionDump : DefaultTask() { @get:InputFiles diff --git a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskCheck.kt b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskCheck.kt index 0262a7a..795503f 100644 --- a/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskCheck.kt +++ b/projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/task/TaskCheck.kt @@ -18,6 +18,7 @@ package com.rubensousa.projectguard.plugin.internal.task import com.rubensousa.projectguard.plugin.internal.BaselineConfiguration import com.rubensousa.projectguard.plugin.internal.DependencyGraphBuilder +import com.rubensousa.projectguard.plugin.internal.ProjectGuardSpec import com.rubensousa.projectguard.plugin.internal.ReportSpec import com.rubensousa.projectguard.plugin.internal.SuppressionMap import com.rubensousa.projectguard.plugin.internal.YamlProcessor @@ -54,7 +55,7 @@ internal abstract class TaskCheck : DefaultTask() { internal abstract val reportFilePath: Property @get:Input - internal abstract val reportSpec: Property + internal abstract val pluginSpec: Property @get:OutputDirectory abstract val outputDir: DirectoryProperty @@ -67,7 +68,7 @@ internal abstract class TaskCheck : DefaultTask() { dependenciesFile = dependenciesFile.get().asFile, reportDir = outputDir.get().asFile, reportFilePath = reportFilePath.get(), - reportSpec = reportSpec.get() + reportSpec = pluginSpec.get().reportSpec ) executor.execute().getOrThrow() } diff --git a/projectguard/src/test/kotlin/com/rubensousa/projectguard/plugin/PluginCacheTest.kt b/projectguard/src/test/kotlin/com/rubensousa/projectguard/plugin/PluginCacheTest.kt index 3fc2ed4..af14397 100644 --- a/projectguard/src/test/kotlin/com/rubensousa/projectguard/plugin/PluginCacheTest.kt +++ b/projectguard/src/test/kotlin/com/rubensousa/projectguard/plugin/PluginCacheTest.kt @@ -19,6 +19,7 @@ package com.rubensousa.projectguard.plugin import com.google.common.truth.Truth.assertThat import org.gradle.testkit.runner.TaskOutcome import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder @@ -50,18 +51,36 @@ class PluginCacheTest { } @Test - fun `outputs from projectGuardDependencyDump are re-used`() { + fun `outputs from projectGuardDependencyDump are up-to-date on next execution`() { // given pluginRunner.createModule("a") pluginRunner.createModule("b") pluginRunner.addDependency(from = "a", to = "b") val libraryDependencyTask = ":b:projectGuardDependencyDump" + pluginRunner.runTask(libraryDependencyTask) // when + val nextResult = pluginRunner.runTask(libraryDependencyTask) + + // then + assertThat(nextResult).isEqualTo(TaskOutcome.UP_TO_DATE) + } + + @Test + fun `outputs from projectGuardDependencyDump are re-used from cache`() { + // given + pluginRunner.createModule("a") + pluginRunner.createModule("b") + pluginRunner.addDependency(from = "a", to = "b") + val libraryDependencyTask = ":b:projectGuardDependencyDump" pluginRunner.runTask(libraryDependencyTask) + // when + pluginRunner.deleteBuildDirs() + val result = pluginRunner.runTask(libraryDependencyTask) + // then - assertThat(pluginRunner.runTask(libraryDependencyTask)).isEqualTo(TaskOutcome.UP_TO_DATE) + assertThat(result).isEqualTo(TaskOutcome.FROM_CACHE) } @Test @@ -76,24 +95,45 @@ class PluginCacheTest { // when pluginRunner.addDependency(from = "b", to = "c") + pluginRunner.deleteBuildDirs() + val result = pluginRunner.runTask(libraryDependencyTask) // then - assertThat(pluginRunner.runTask(libraryDependencyTask)).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result).isEqualTo(TaskOutcome.SUCCESS) } @Test - fun `outputs from projectGuardAggregateDependencyDump are re-used`() { + fun `outputs from projectGuardAggregateDependencyDump are up-to-date on next execution`() { // given pluginRunner.createModule("a") pluginRunner.createModule("b") pluginRunner.addDependency(from = "a", to = "b") val task = ":projectGuardAggregateDependencyDump" + pluginRunner.runTask(task) // when + val result = pluginRunner.runTask(task) + + // then + assertThat(result).isEqualTo(TaskOutcome.UP_TO_DATE) + } + + @Ignore("Not working for now") + @Test + fun `outputs from projectGuardAggregateDependencyDump are re-used from cache`() { + // given + pluginRunner.createModule("a") + pluginRunner.createModule("b") + pluginRunner.addDependency(from = "a", to = "b") + val task = ":projectGuardAggregateDependencyDump" pluginRunner.runTask(task) + // when + pluginRunner.deleteBuildDirs() + val result = pluginRunner.runTask(task) + // then - assertThat(pluginRunner.runTask(task)).isEqualTo(TaskOutcome.UP_TO_DATE) + assertThat(result).isEqualTo(TaskOutcome.FROM_CACHE) } @Test @@ -114,18 +154,36 @@ class PluginCacheTest { } @Test - fun `outputs from projectGuardRestrictionDump are re-used if nothing changed`() { + fun `outputs from projectGuardRestrictionDump are up-to-date if nothing changed`() { // given pluginRunner.createModule("a") pluginRunner.createModule("b") pluginRunner.addDependency(from = "a", to = "b") val task = ":a:projectGuardRestrictionDump" + pluginRunner.runTask(task) // when + val result = pluginRunner.runTask(task) + + // then + assertThat(result).isEqualTo(TaskOutcome.UP_TO_DATE) + } + + @Test + fun `outputs from projectGuardRestrictionDump are cached`() { + // given + pluginRunner.createModule("a") + pluginRunner.createModule("b") + pluginRunner.addDependency(from = "a", to = "b") + val task = ":a:projectGuardRestrictionDump" pluginRunner.runTask(task) + // when + pluginRunner.deleteBuildDirs() + val result = pluginRunner.runTask(task) + // then - assertThat(pluginRunner.runTask(task)).isEqualTo(TaskOutcome.UP_TO_DATE) + assertThat(result).isEqualTo(TaskOutcome.FROM_CACHE) } @Test @@ -140,6 +198,7 @@ class PluginCacheTest { // when pluginRunner.addDependency(from = "b", to = "c") + pluginRunner.deleteBuildDirs() // then assertThat(pluginRunner.runTask(task)).isEqualTo(TaskOutcome.SUCCESS) @@ -162,6 +221,7 @@ class PluginCacheTest { } """.trimIndent() ) + pluginRunner.deleteBuildDirs() // then assertThat(pluginRunner.runTask(task)).isEqualTo(TaskOutcome.SUCCESS) diff --git a/projectguard/src/test/kotlin/com/rubensousa/projectguard/plugin/PluginRunner.kt b/projectguard/src/test/kotlin/com/rubensousa/projectguard/plugin/PluginRunner.kt index c219dee..2e2bfdf 100644 --- a/projectguard/src/test/kotlin/com/rubensousa/projectguard/plugin/PluginRunner.kt +++ b/projectguard/src/test/kotlin/com/rubensousa/projectguard/plugin/PluginRunner.kt @@ -34,11 +34,24 @@ class PluginRunner( .withGradleVersion("8.13") } private var lastResult: BuildResult? = null + private val modules = mutableListOf() fun createModule(name: String) { temporaryFolder.newFolder(name) temporaryFolder.newFile("$name/build.gradle.kts") settingsFile.appendText("\ninclude(\":$name\")") + modules.add(name) + } + + fun deleteBuildDirs() { + modules.forEach { module -> + temporaryFolder.getRoot() + .resolve("$module/build/") + .deleteRecursively() + } + temporaryFolder.getRoot() + .resolve("build") + .deleteRecursively() } fun assertProjectGuardCheckFails(module: String) { @@ -72,7 +85,7 @@ class PluginRunner( } fun runTask(task: String): TaskOutcome { - val result = gradleRunner.withArguments(task).build() + val result = gradleRunner.withArguments("--build-cache", task).build() lastResult = result return result.task(task)!!.outcome }