Skip to content

Commit

Permalink
[Filtering] Add support for filtering classes like Maven plugin (#54)
Browse files Browse the repository at this point in the history
This adds package filters similar to how the Maven plugin filters in its `<classes>` block. This supports ant-like patterns similar to how patterns filter.

Follows #53 which added similar support for `packages` filtering

Closes #16.
  • Loading branch information
Nava2 authored Apr 26, 2023
1 parent b8acd28 commit a1f9eb5
Show file tree
Hide file tree
Showing 6 changed files with 537 additions and 2 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,30 @@ sourceSets {
See [`PackageFilter` tests](src/test/groovy/org/assertj/generator/gradle/parameter/PackageFilter.groovy) for more
examples.

#### classes - `JavaClassPatternFilterable`

Default: All classes

Class filters can be used to include, or exclude individual patterns of fully-qualified class names to be generated.
These filters use a
similar pattern to `include`/`exclude` with `SourceSet`.

```groovy
sourceSets {
main {
assertJ {
classes {
include "org.example.**" // include *all* classes under `org.example` including sub-packages
exclude "org.example.Foo" // exclude class `org.example.Foo` specifically
}
}
}
}
```

See [`ClassesFilter` tests](src/test/groovy/org/assertj/generator/gradle/parameter/ClassesFilter.groovy) for more
examples.

#### entryPoints - `EntryPointsGeneratorOptions`

Default: Only generate "standard" assertion entrypoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.assertj.assertions.generator.description.converter.ClassToClassDescri
import org.assertj.assertions.generator.util.ClassUtil
import org.assertj.generator.gradle.tasks.config.AssertJGeneratorExtension
import org.assertj.generator.gradle.tasks.config.SerializedTemplate
import org.assertj.generator.gradle.tasks.config.patterns.JavaClassPatternFilterable
import org.assertj.generator.gradle.tasks.config.patterns.JavaPackageNamePatternFilterable
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
Expand Down Expand Up @@ -83,6 +84,9 @@ open class AssertJGenerationTask @Inject internal constructor(
@get:Input
internal val hierarchical: Property<Boolean> = objects.property()

@get:Input
internal val classesFilterable: Property<JavaClassPatternFilterable> = objects.property()

@get:Input
internal val packagesFilterable: Property<JavaPackageNamePatternFilterable> = objects.property()

Expand Down Expand Up @@ -114,6 +118,7 @@ open class AssertJGenerationTask @Inject internal constructor(

skip.set(project.provider { assertJOptions.skip })
hierarchical.set(project.provider { assertJOptions.hierarchical })
classesFilterable.set(project.provider { assertJOptions.classes })
packagesFilterable.set(project.provider { assertJOptions.packages })
entryPoints.set(project.provider { assertJOptions.entryPoints.entryPoints })
entryPointsClassPackage.set(project.provider { assertJOptions.entryPoints.classPackage })
Expand All @@ -130,6 +135,7 @@ open class AssertJGenerationTask @Inject internal constructor(

val classLoader = URLClassLoader((generationClasspath + classDirectories).map { it.toURI().toURL() }.toTypedArray())

val classesPredicate = classesFilterable.get().asPredicate()
val packagesPredicate = packagesFilterable.get().asPredicate()
val allClassNames = getClassNames(classDirectories)
.filter { packagesPredicate.test(it.substringBeforeLast('.')) }
Expand All @@ -138,7 +144,9 @@ open class AssertJGenerationTask @Inject internal constructor(
val allClasses = ClassUtil.collectClasses(
classLoader,
*allClassNames.toTypedArray(),
)
).asSequence()
.filter { classesPredicate.test(it) }
.toSet()

val changedFiles = if (inputs.isIncremental) {
inputs.getFileChanges(classDirectories).asSequence().map { it.file }.filter { it.isFile }.toSet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.assertj.generator.gradle.tasks.config

import org.assertj.assertions.generator.AssertionsEntryPointType
import org.assertj.generator.gradle.tasks.config.patterns.JavaClassPatternFilterable
import org.assertj.generator.gradle.tasks.config.patterns.JavaPackageNamePatternFilterable
import org.gradle.api.Action
import org.gradle.api.Project
Expand All @@ -35,6 +36,12 @@ open class AssertJGeneratorExtension @Inject internal constructor(
val classDirectories: SourceDirectorySet =
objects.sourceDirectorySet("assertJClasses", "Classes to generate AssertJ assertions from")

val classes: JavaClassPatternFilterable = objects.newInstance()

fun classes(action: Action<in JavaClassPatternFilterable>): AssertJGeneratorExtension = apply {
action.execute(classes)
}

val packages: JavaPackageNamePatternFilterable = objects.newInstance()

fun packages(action: Action<in JavaPackageNamePatternFilterable>): AssertJGeneratorExtension = apply {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2023. assertj-generator-gradle-plugin contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.assertj.generator.gradle.tasks.config.patterns

import com.google.common.reflect.TypeToken
import org.assertj.generator.gradle.tasks.config.patterns.JavaNamePatternCompiler.compilePattern
import java.io.IOException
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable

/**
* Implements a similar construction to [org.gradle.api.tasks.util.PatternFilterable] that will match
* [TypeToken] instances.
*/
open class JavaClassPatternFilterable internal constructor() :
JavaIdentifierNamePatternFilterableBase<TypeToken<*>, JavaClassPatternFilterable>(), Serializable {

override fun compilePatterns(patterns: Iterable<String>): Sequence<PatternPredicate<TypeToken<*>>> {
return patterns.asSequence().map { TypeNamePredicate.compile(it) }
}

@Throws(IOException::class)
protected fun writeObject(o: ObjectOutputStream) {
super.writeObjectImpl(o)
}

@Throws(IOException::class, ClassNotFoundException::class)
protected fun readObject(i: ObjectInputStream) {
super.readObjectImpl(i)
}

internal data class TypeNamePredicate(
override val pattern: String,
private val namePattern: Regex,
) : PatternPredicate<TypeToken<*>> {
override fun test(t: TypeToken<*>): Boolean {
return namePattern.matches(t.type.typeName)
}

companion object {
fun compile(pattern: String): TypeNamePredicate = TypeNamePredicate(pattern, compilePattern(pattern))
}
}

companion object {
private const val serialVersionUID = 9418631994L
}
}
Loading

0 comments on commit a1f9eb5

Please sign in to comment.