Skip to content

Commit

Permalink
properly parse --tests parameters in CompositePlugin
Browse files Browse the repository at this point in the history
  • Loading branch information
RBusarow committed Dec 4, 2023
1 parent dbefe79 commit 91fae50
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ class CompositePlugin : Plugin<Project> {

val newRequests = oldRequests.map { request ->

val originalSplit = request.args
.splitInclusive { !it.startsWith('-') }
val originalSplit = request.args.splitTaskArgs()

val taskPaths = originalSplit.mapTo(mutableSetOf()) { it.first() }

Expand All @@ -57,13 +56,9 @@ class CompositePlugin : Plugin<Project> {
return@flatMap listOf(taskWithArgs)
}

val resolvedInRootBuild = target.tasks.namedOrNull(taskName)

// Don't propagate help tasks
if (taskName == "help") return@flatMap listOf(taskWithArgs)

val inRoot = resolvedInRootBuild != null

val included = includedProjects.mapNotNull { includedProject ->

val includedPath = "${includedProject.identityPath}:$taskName"
Expand All @@ -82,7 +77,12 @@ class CompositePlugin : Plugin<Project> {
}

buildList {
if (inRoot) {

// Looks to see if any project in this build has a task with this name.
val resolvedInRootBuild = target.allprojects
.any { project -> project.tasks.namedOrNull(taskName) != null }

if (resolvedInRootBuild) {
add(taskWithArgs)
}
addAll(included)
Expand All @@ -96,18 +96,27 @@ class CompositePlugin : Plugin<Project> {
}
}

private inline fun <E> List<E>.splitInclusive(predicate: (E) -> Boolean): List<List<E>> {
private fun List<String>.splitTaskArgs(): List<List<String>> {

val toSplit = this@splitInclusive
val toSplit = this@splitTaskArgs

if (toSplit.isEmpty()) return emptyList()

return toSplit.subList(1, toSplit.size)
.fold(mutableListOf(mutableListOf(toSplit[0]))) { acc: MutableList<MutableList<E>>, e ->
if (predicate(e)) {
acc.add(mutableListOf(e))
} else {
acc.last().add(e)
val args = toSplit.subList(1, toSplit.size)

return args
.fold(
mutableListOf(mutableListOf(toSplit[0])),
) { acc: MutableList<MutableList<String>>, arg ->

val lastArg = acc.last().last()

when {
arg.startsWith('-') -> acc.last().add(arg)
// Matches 'foo' in `./gradlew test --tests foo`
// Does not match 'foo' in `./gradlew test --tests=foo`
lastArg.startsWith('-') && !lastArg.contains('=') -> acc.last().add(arg)
else -> acc.add(mutableListOf(arg))
}
acc
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,33 @@ import org.gradle.api.NamedDomainObjectCollectionSchema.NamedDomainObjectSchema
import org.gradle.api.tasks.TaskCollection
import org.jetbrains.kotlin.gradle.plugin.extraProperties

/** @throws IllegalArgumentException if the task name is ambiguous when case is ignored */
/** @throws IllegalArgumentException if there are multiple tasks of that name when ignoring its case */
internal fun TaskCollection<*>.namedOrNull(taskName: String): NamedDomainObjectSchema? {

val namesLowercase = extraProperties.getOrPut("taskNamesLowercase") {
collectionSchema.elements.groupBy { it.name.lowercase() }
}
// This will typically be a 1:1 grouping,
// but Gradle does allow you to re-use task names with different capitalization,
// like 'foo' and 'Foo'.
val namesLowercase: Map<String, List<NamedDomainObjectSchema>> =
extraProperties.getOrPut("taskNamesLowercaseToSchema") {
collectionSchema.elements.groupBy { it.name.lowercase() }
}

val taskNameLowercase = taskName.lowercase()

val matches = namesLowercase[taskNameLowercase] ?: return null
// All tasks that match the lowercase name
val lowercaseMatches = namesLowercase[taskNameLowercase] ?: return null

val exactMatch = matches.singleOrNull { it.name == taskName }
// The task with the same case as the requested name, or null
val exactMatch = lowercaseMatches.singleOrNull { it.name == taskName }

if (exactMatch != null) {
return exactMatch
}

require(matches.size == 1) {
require(lowercaseMatches.size == 1) {
"Task name '$taskName' is ambiguous. " +
"It matches multiple tasks: ${matches.map { it.name }}"
"It matches multiple tasks: ${lowercaseMatches.map { it.name }}"
}

return matches.single()
return lowercaseMatches.single()
}

0 comments on commit 91fae50

Please sign in to comment.