Skip to content

Commit

Permalink
fixup! WIP. Use domain object container to avoid afterEvaluate.
Browse files Browse the repository at this point in the history
  • Loading branch information
autonomousapps committed Apr 25, 2022
1 parent 0dc6296 commit 3d4a19f
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.dropbox.gradle.plugins.dependencyguard

import org.gradle.api.Named
import org.gradle.api.tasks.Input
import javax.inject.Inject

/**
Expand All @@ -12,23 +13,33 @@ public open class DependencyGuardConfiguration @Inject constructor(
*
* See all possibilities by running Gradle's built in ./gradlew project:dependencies
*/
@get:Input
public val configurationName: String,
) : Named {
@Input
public override fun getName(): String = configurationName

/** Whether to include artifacts in the dependency list report */
@get:Input
public var artifacts: Boolean = true

/** Whether to include modules in the dependency list report */
@get:Input
public var modules: Boolean = true

/**
* Whether to create the dependency tree report
*
* false by default because while valuable for debugging, get very noisy
*/
@get:Input
public var tree: Boolean = false

/** Whether or not to allow a dependency */
/**
* Whether to allow a dependency.
*
* TODO: not sure how to model this as a task input. May not matter since the task that uses it
* can never be up-to-date.
*/
public var isAllowed: (dependencyName: String) -> Boolean = { true }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.dropbox.gradle.plugins.dependencyguard

import com.dropbox.gradle.plugins.dependencyguard.internal.ConfigurationValidators.requirePluginConfig
import com.dropbox.gradle.plugins.dependencyguard.internal.DependencyTreeDiffTaskNames
import com.dropbox.gradle.plugins.dependencyguard.internal.list.DependencyGuardListTask
import com.dropbox.gradle.plugins.dependencyguard.internal.tree.BuildEnvironmentDependencyTreeDiffTask
Expand Down Expand Up @@ -50,6 +49,7 @@ public class DependencyGuardPlugin : Plugin<Project> {
) {
val task = this
task.setParams(
project = target,
extension = extension,
shouldBaseline = true
)
Expand All @@ -65,8 +65,9 @@ public class DependencyGuardPlugin : Plugin<Project> {
DependencyGuardListTask::class.java
) {
val task = this
requirePluginConfig(target, extension)
//requirePluginConfig(target, extension.configurations)
task.setParams(
project = target,
extension = extension,
shouldBaseline = false
)
Expand All @@ -79,7 +80,7 @@ public class DependencyGuardPlugin : Plugin<Project> {
baselineTask: TaskProvider<DependencyGuardListTask>,
guardTask: TaskProvider<DependencyGuardListTask>
) {
extension.container.all {
extension.configurations.all {
val dependencyGuardConfiguration = this
if (dependencyGuardConfiguration.tree) {
val taskClass = if (target.isRootProject()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,10 @@ import javax.inject.Inject
public open class DependencyGuardPluginExtension @Inject constructor(
private val objects: ObjectFactory
) {
internal val configurations = mutableListOf<DependencyGuardConfiguration>()
internal val container = objects.domainObjectContainer(DependencyGuardConfiguration::class.java)
internal val configurations = objects.domainObjectContainer(DependencyGuardConfiguration::class.java)

public fun configuration(name: String) {
// TODO old
val configuration = DependencyGuardConfiguration(name)
configurations.add(configuration)

// TODO new
container.create(name)
configurations.add(newConfiguration(name))
}

/**
Expand All @@ -33,15 +27,15 @@ public open class DependencyGuardPluginExtension @Inject constructor(
* }
*/
public fun configuration(name: String, config: Action<DependencyGuardConfiguration>) {
// TODO old
val configuration = DependencyGuardConfiguration(name)
config.execute(configuration)
configurations.add(configuration)
configurations.add(newConfiguration(name, config))
}

// TODO new
val c = objects.newInstance(DependencyGuardConfiguration::class.java, name).apply {
config.execute(this)
private fun newConfiguration(
name: String,
config: Action<DependencyGuardConfiguration>? = null
): DependencyGuardConfiguration {
return objects.newInstance(DependencyGuardConfiguration::class.java, name).apply {
config?.execute(this)
}
container.add(c)
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
package com.dropbox.gradle.plugins.dependencyguard.internal

import com.dropbox.gradle.plugins.dependencyguard.DependencyGuardPluginExtension
import com.dropbox.gradle.plugins.dependencyguard.DependencyGuardConfiguration
import com.dropbox.gradle.plugins.dependencyguard.DependencyGuardPlugin
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.initialization.dsl.ScriptHandler
import org.gradle.api.logging.Logging

internal object ConfigurationValidators {

fun requirePluginConfig(project: Project, extension: DependencyGuardPluginExtension) {
if (project.isRootProject()) {
println("Configured for Root Project")
if (extension.configurations.isNotEmpty() && extension.configurations.first().configurationName != ScriptHandler.CLASSPATH_CONFIGURATION) {
println("If you wish to use dependency guard on your root project, use the following config:")
private val logger = Logging.getLogger(DependencyGuardPlugin::class.java)

fun requirePluginConfig(
isForRootProject: Boolean,
availableConfigurations: List<String>,
monitoredConfigurations: List<DependencyGuardConfiguration>
) {
if (isForRootProject) {
logger.info("Configured for Root Project")
if (monitoredConfigurations.isNotEmpty() && monitoredConfigurations.first().configurationName != ScriptHandler.CLASSPATH_CONFIGURATION) {
logger.error("If you wish to use dependency guard on your root project, use the following config:")
val message = StringBuilder().apply {
appendLine("dependencyGuard {")
appendLine(""" configuration("${ScriptHandler.CLASSPATH_CONFIGURATION}")""")
Expand All @@ -21,16 +29,14 @@ internal object ConfigurationValidators {
}
return
}
val configurationNames = extension.configurations.map { it.configurationName }
val configurationNames = monitoredConfigurations.map { it.configurationName }
require(configurationNames.isNotEmpty() && configurationNames[0].isNotBlank()) {
StringBuilder().apply {
appendLine("Error: No configurations provided to Dependency Guard Plugin.")
appendLine("Here are some valid configurations you could use.")
appendLine("")
val availableConfigNames = project.configurations
.filter {
isClasspathConfig(it.name)
}.map { it.name }
val availableConfigNames = availableConfigurations
.filter { isClasspathConfig(it) }

appendLine("dependencyGuard {")
availableConfigNames.forEach {
Expand All @@ -41,7 +47,7 @@ internal object ConfigurationValidators {
}
}

fun isClasspathConfig(configName: String): Boolean {
private fun isClasspathConfig(configName: String): Boolean {
return configName.endsWith(
suffix = "CompileClasspath",
ignoreCase = true
Expand All @@ -55,6 +61,8 @@ internal object ConfigurationValidators {
target: Project,
configurationNames: List<String>
) {
val logger = target.logger

if (target.isRootProject()) {
if (configurationNames != listOf(ScriptHandler.CLASSPATH_CONFIGURATION)) {
val message = StringBuilder().apply {
Expand All @@ -73,13 +81,13 @@ internal object ConfigurationValidators {
target.configurations
.firstOrNull { it.name == configurationName }
?: run {
println("Available Configurations:")
logger.quiet("Available Configurations:")
target.configurations
.filter {
isClasspathConfig(it.name)
}
.forEach {
println("* " + it.name)
logger.quiet("* " + it.name)
}
throw GradleException(
"Configuration with name $configurationName was not found for ${target.name}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.dropbox.gradle.plugins.dependencyguard.internal
import com.dropbox.gradle.plugins.dependencyguard.DependencyGuardPlugin
import org.gradle.api.Project

internal fun Project.isRootProject(): Boolean = (path == rootProject.path)
internal fun Project.isRootProject(): Boolean = this == rootProject

internal fun getQualifiedBaselineTaskForProjectPath(path: String): String {
val separator = if (path == ":") "" else ":"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@ import com.dropbox.gradle.plugins.dependencyguard.DependencyGuardConfiguration
import com.dropbox.gradle.plugins.dependencyguard.DependencyGuardPlugin
import com.dropbox.gradle.plugins.dependencyguard.DependencyGuardPluginExtension
import com.dropbox.gradle.plugins.dependencyguard.internal.ConfigurationValidators
import com.dropbox.gradle.plugins.dependencyguard.internal.ConfigurationValidators.requirePluginConfig
import com.dropbox.gradle.plugins.dependencyguard.internal.DependencyGuardListReportWriter
import com.dropbox.gradle.plugins.dependencyguard.internal.DependencyGuardReportData
import com.dropbox.gradle.plugins.dependencyguard.internal.DependencyGuardReportType
import com.dropbox.gradle.plugins.dependencyguard.internal.DependencyVisitor
import com.dropbox.gradle.plugins.dependencyguard.internal.isRootProject
import com.dropbox.gradle.plugins.dependencyguard.internal.qualifiedBaselineTaskName
import com.dropbox.gradle.plugins.dependencyguard.internal.utils.ColorTerminal
import com.dropbox.gradle.plugins.dependencyguard.internal.utils.OutputFileUtils
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.initialization.dsl.ScriptHandler
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.TaskAction
import org.gradle.util.GradleVersion

internal open class DependencyGuardListTask : DefaultTask() {
public abstract class DependencyGuardListTask : DefaultTask() {

init {
group = DependencyGuardPlugin.DEPENDENCY_GUARD_TASK_GROUP
}

private lateinit var extension: DependencyGuardPluginExtension

private var shouldBaseline: Boolean = false

private val dependencyGuardConfigurations: MutableList<DependencyGuardConfiguration> get() = extension.configurations

private fun generateReport(
dependencyGuardConfiguration: DependencyGuardConfiguration
): DependencyGuardReportData {
Expand All @@ -37,7 +37,7 @@ internal open class DependencyGuardListTask : DefaultTask() {
var config = project.configurations.firstOrNull { it.name == configurationName }

if (config == null) {
if (project.isRootProject()) {
if (forRootProject.get()) {
// Assuming this is the root project
config = project.buildscript.configurations.findByName(ScriptHandler.CLASSPATH_CONFIGURATION)
}
Expand All @@ -56,9 +56,28 @@ internal open class DependencyGuardListTask : DefaultTask() {
)
}

@get:Input
public abstract val shouldBaseline: Property<Boolean>

@get:Input
public abstract val forRootProject: Property<Boolean>

@get:Input
public abstract val availableConfigurations: ListProperty<String>

@get:Nested
public abstract val monitoredConfigurations: ListProperty<DependencyGuardConfiguration>

@Suppress("NestedBlockDepth")
@TaskAction
internal fun execute() {
requirePluginConfig(
isForRootProject = forRootProject.get(),
availableConfigurations = availableConfigurations.get(),
monitoredConfigurations = monitoredConfigurations.get()
)

val dependencyGuardConfigurations = monitoredConfigurations.get()
ConfigurationValidators.validateConfigurationsAreAvailable(
target = project,
configurationNames = dependencyGuardConfigurations.map { it.configurationName }
Expand Down Expand Up @@ -114,7 +133,7 @@ internal open class DependencyGuardListTask : DefaultTask() {
reportType = reportType,
),
report = report,
shouldBaseline = shouldBaseline,
shouldBaseline = shouldBaseline.get(),
errorHandler = { }
)
}
Expand Down Expand Up @@ -154,8 +173,20 @@ internal open class DependencyGuardListTask : DefaultTask() {
throw GradleException(errorMessage)
}

internal fun setParams(extension: DependencyGuardPluginExtension, shouldBaseline: Boolean) {
this.extension = extension
this.shouldBaseline = shouldBaseline
internal fun setParams(
project: Project,
extension: DependencyGuardPluginExtension,
shouldBaseline: Boolean
) {
this.forRootProject.set(project.isRootProject())
this.availableConfigurations.set(project.configurations.map { it.name })
this.monitoredConfigurations.set(extension.configurations)
this.shouldBaseline.set(shouldBaseline)

if (GradleVersion.current() >= GradleVersion.version("7.3")) {
doNotTrackState("This task only outputs to console")
} else {
outputs.upToDateWhen { false }
}
}
}

0 comments on commit 3d4a19f

Please sign in to comment.