1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 16:28:12 -07:00

Add includes/excludes to the test{} directives.

Original code from @bmsantos.
This commit is contained in:
Cedric Beust 2016-01-01 09:55:04 -08:00
parent 0a87a7684f
commit eb2937098d
9 changed files with 96 additions and 84 deletions

View file

@ -3,7 +3,9 @@ package com.beust.kobalt
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import java.io.File import java.io.File
import java.nio.file.* import java.nio.file.*
import java.nio.file.FileVisitResult.CONTINUE
import java.nio.file.attribute.BasicFileAttributes import java.nio.file.attribute.BasicFileAttributes
import java.util.*
sealed class IFileSpec { sealed class IFileSpec {
abstract fun toFiles(directory: String): List<File> abstract fun toFiles(directory: String): List<File>
@ -14,25 +16,57 @@ sealed class IFileSpec {
override public fun toString() = spec override public fun toString() = spec
} }
class GlobSpec(val spec: String) : IFileSpec() { class GlobSpec(val includeSpec: ArrayList<String>, val excludeSpec: ArrayList<String>) : IFileSpec() {
override public fun toFiles(directory: String): List<File> {
val result = arrayListOf<File>() constructor(spec: String) : this(arrayListOf(spec), arrayListOf())
override public fun toFiles(directory: String): List<File> {
val result = arrayListOf<File>()
val includeMatchers = prepareMatchers(includeSpec.toTypedArray())
val excludeMatchers = prepareMatchers(excludeSpec.toTypedArray())
val matcher = FileSystems.getDefault().getPathMatcher("glob:$spec")
Files.walkFileTree(Paths.get(directory), object : SimpleFileVisitor<Path>() { Files.walkFileTree(Paths.get(directory), object : SimpleFileVisitor<Path>() {
override public fun visitFile(path: Path, attrs: BasicFileAttributes): FileVisitResult { override public fun visitFile(path: Path, attrs: BasicFileAttributes): FileVisitResult {
val rel = Paths.get(directory).relativize(path) val rel = Paths.get(directory).relativize(path)
if (matcher.matches(rel)) { excludeMatchers.forEach {
log(3, "Adding ${rel.toFile()}") if (it.matches(rel)) {
result.add(rel.toFile()) log(3, "Removing ${rel.toFile()}")
return CONTINUE
}
} }
return FileVisitResult.CONTINUE includeMatchers.forEach {
if (it.matches(rel)) {
log(3, "Adding ${rel.toFile()}")
result.add(rel.toFile())
return CONTINUE
}
}
return CONTINUE
} }
}) })
return result return result
} }
override public fun toString() = spec override public fun toString(): String {
var result = ""
includeSpec.apply {
if (!isEmpty()) {
result += "Included files: " + joinToString { ", " }
}
}
excludeSpec.apply {
if (!isEmpty()) {
result += "Excluded files: " + joinToString { ", " }
}
}
return result
}
private fun prepareMatchers(specs: Array<String>): List<PathMatcher> =
specs.map { it -> FileSystems.getDefault().getPathMatcher("glob:$it") }
} }
} }

View file

@ -11,9 +11,21 @@ class TestConfig(val project: Project) {
fun jvmArgs(vararg arg: String) { fun jvmArgs(vararg arg: String) {
project.testJvmArgs.addAll(arg) project.testJvmArgs.addAll(arg)
} }
fun includes(vararg arg: String) {
project.testIncludes.apply {
clear()
addAll(arg)
}
}
fun excludes(vararg arg: String) {
project.testExcludes.apply {
clear()
addAll(arg)
}
}
} }
@Directive @Directive
fun Project.test(init: TestConfig.() -> Unit) = TestConfig(this).apply { init() } fun Project.test(init: TestConfig.() -> Unit) = TestConfig(this).apply { init() }

View file

@ -29,6 +29,8 @@ open class Project(
val testJvmArgs = arrayListOf<String>() val testJvmArgs = arrayListOf<String>()
val projectProperties = ProjectProperties() val projectProperties = ProjectProperties()
val testIncludes = arrayListOf("**/*Test.class")
val testExcludes = arrayListOf<String>()
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
return name == (other as Project).name return name == (other as Project).name

View file

@ -1,5 +1,6 @@
package com.beust.kobalt.internal package com.beust.kobalt.internal
import com.beust.kobalt.IFileSpec
import com.beust.kobalt.JavaInfo import com.beust.kobalt.JavaInfo
import com.beust.kobalt.SystemProperties import com.beust.kobalt.SystemProperties
import com.beust.kobalt.TaskResult import com.beust.kobalt.TaskResult
@ -7,7 +8,7 @@ import com.beust.kobalt.api.*
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import java.io.File import java.io.File
import java.net.URLClassLoader import java.util.*
/** /**
* Base class for testing frameworks that are invoked from a main class with arguments. Test runners can * Base class for testing frameworks that are invoked from a main class with arguments. Test runners can
@ -25,33 +26,21 @@ abstract class GenericTestRunner : ITestRunnerContributor {
if (project.testDependencies.any { it.id.contains(dependencyName)}) IAffinity.DEFAULT_POSITIVE_AFFINITY if (project.testDependencies.any { it.id.contains(dependencyName)}) IAffinity.DEFAULT_POSITIVE_AFFINITY
else 0 else 0
protected fun findTestClasses(project: Project, classpath: List<IClasspathDependency>, protected fun findTestClasses(project: Project): List<String> {
classFilter : (Class<*>) -> Boolean = {true}): List<String> {
val path = KFiles.joinDir(project.directory, project.buildDirectory, KFiles.TEST_CLASSES_DIR) val path = KFiles.joinDir(project.directory, project.buildDirectory, KFiles.TEST_CLASSES_DIR)
val result = KFiles.findRecursively(File(path), arrayListOf(File(".")), {
file -> file.endsWith(".class")
}).map {
it.replace("/", ".").replace("\\", ".").replace(".class", "").substring(2)
}.filter {
try {
// Only keep classes with a parameterless constructor
val urls = arrayOf(File(path).toURI().toURL()) +
classpath.map { it.jarFile.get().toURI().toURL() }
val cl = URLClassLoader(urls).loadClass(it)
val constructor = cl.getConstructor()
// If we get past this, we have a default constructor
classFilter(cl) val result = IFileSpec.GlobSpec(toClassPaths(project.testIncludes), toClassPaths(project.testExcludes))
} catch(ex: Exception) { .toFiles(path).map {
log(2, "Skipping non test class $it: ${ex.message}") it.toString().replace("/", ".").replace("\\", ".").replace(".class", "")
false }
}
}
log(2, "Found ${result.size} test classes") log(2, "Found ${result.size} test classes")
return result return result
} }
private fun toClassPaths(paths: List<String>): ArrayList<String> =
paths.map { if (it.endsWith(".class")) it else it + ".class" }.toArrayList()
/** /**
* @return true if all the tests passed * @return true if all the tests passed
*/ */

View file

@ -9,15 +9,6 @@ open public class JUnitRunner() : GenericTestRunner() {
override val dependencyName = "junit" override val dependencyName = "junit"
override fun args(project: Project, classpath: List<IClasspathDependency>) override fun args(project: Project, classpath: List<IClasspathDependency>) = findTestClasses(project)
= findTestClasses(project, classpath) {
// Only return a class if it contains at least one @Test method, otherwise
// JUnit 4 throws an exception :-(
it.declaredMethods.flatMap {
it.annotations.toList()
}.filter {
ann: Annotation -> ann.javaClass.name.contains("Test")
}.size > 0
}
} }

View file

@ -15,18 +15,18 @@ public class TestNgRunner() : GenericTestRunner() {
override fun args(project: Project, classpath: List<IClasspathDependency>) = arrayListOf<String>().apply { override fun args(project: Project, classpath: List<IClasspathDependency>) = arrayListOf<String>().apply {
if (project.testArgs.size > 0) { if (project.testArgs.size > 0) {
addAll(project.testArgs) addAll(project.testArgs)
}
val testngXml = File(project.directory, KFiles.joinDir("src", "test", "resources", "testng.xml"))
if (testngXml.exists()) {
add(testngXml.absolutePath)
} else { } else {
val testngXml = File(project.directory, KFiles.joinDir("src", "test", "resources", "testng.xml")) val testClasses = findTestClasses(project)
if (testngXml.exists()) { if (testClasses.size > 0) {
add(testngXml.absolutePath) add("-testclass")
add(testClasses.joinToString(","))
} else { } else {
val testClasses = findTestClasses(project, classpath) warn("Couldn't find any test classes for ${project.name}")
if (testClasses.size > 0) {
add("-testclass")
add(testClasses.joinToString(","))
} else {
warn("Couldn't find any test classes for ${project.name}")
}
} }
} }
} }

View file

@ -28,10 +28,9 @@ public class JarUtils {
} }
} }
private val DEFAULT_JAR_EXCLUDES = arrayListOf( private val DEFAULT_JAR_EXCLUDES =
IFileSpec.GlobSpec("META-INF/*.SF"), IFileSpec.GlobSpec(arrayListOf(),
IFileSpec.GlobSpec("META-INF/*.DSA"), arrayListOf("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA"))
IFileSpec.GlobSpec("META-INF/*.RSA"))
public fun addSingleFile(directory: String, file: IncludedFile, outputStream: ZipOutputStream, public fun addSingleFile(directory: String, file: IncludedFile, outputStream: ZipOutputStream,
expandJarFiles: Boolean, onError: (Exception) -> Unit = DEFAULT_HANDLER) { expandJarFiles: Boolean, onError: (Exception) -> Unit = DEFAULT_HANDLER) {
@ -153,7 +152,7 @@ class IncludedFile(val fromOriginal: From, val toOriginal: To, val specs: List<I
public val from: String get() = fromOriginal.path.replace("\\", "/") public val from: String get() = fromOriginal.path.replace("\\", "/")
public val to: String get() = toOriginal.path.replace("\\", "/") public val to: String get() = toOriginal.path.replace("\\", "/")
override public fun toString() = toString("IncludedFile", override public fun toString() = toString("IncludedFile",
"files", specs.map { it.toString() }.joinToString(", "), "files - ", specs.map { it.toString() },
"from", from, "from", from,
"to", to) "to", to)

View file

@ -7,10 +7,10 @@ import com.beust.kobalt.internal.build.BuildFile
import com.beust.kobalt.maven.Md5 import com.beust.kobalt.maven.Md5
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.nio.file.* import java.nio.file.Files
import kotlin.io.FileAlreadyExistsException import java.nio.file.Path
import kotlin.io.FileSystemException import java.nio.file.Paths
import kotlin.io.NoSuchFileException import java.nio.file.StandardCopyOption
class KFiles { class KFiles {
/** /**
@ -277,25 +277,10 @@ class KFiles {
fun makeOutputTestDir(project: Project) : File = makeDir(project, KFiles.TEST_CLASSES_DIR) fun makeOutputTestDir(project: Project) : File = makeDir(project, KFiles.TEST_CLASSES_DIR)
fun isExcluded(file: File, excludes: List<IFileSpec.GlobSpec>) = isExcluded(file.path, excludes) fun isExcluded(file: File, excludes: IFileSpec.GlobSpec) = isExcluded(file.path, excludes)
fun isExcluded(file: String, excludes: List<IFileSpec.GlobSpec>) : Boolean {
if (excludes.isEmpty()) {
return false
} else {
val ex = excludes.map {
FileSystems.getDefault().getPathMatcher("glob:${it.spec}")
}
ex.forEach {
if (it.matches(Paths.get(file))) {
log(3, "Excluding $file")
return true
}
}
}
return false
}
fun isExcluded(file: String, excludes: IFileSpec.GlobSpec): Boolean =
excludes.toFiles(file).isEmpty()
} }
fun findRecursively(directory: File, function: Function1<String, Boolean>): List<String> { fun findRecursively(directory: File, function: Function1<String, Boolean>): List<String> {

View file

@ -43,7 +43,7 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
const val TASK_INSTALL: String = "install" const val TASK_INSTALL: String = "install"
fun findIncludedFiles(directory: String, files: List<IncludedFile>, excludes: List<IFileSpec.GlobSpec>) fun findIncludedFiles(directory: String, files: List<IncludedFile>, excludes: IFileSpec.GlobSpec)
: List<IncludedFile> { : List<IncludedFile> {
val result = arrayListOf<IncludedFile>() val result = arrayListOf<IncludedFile>()
files.forEach { includedFile -> files.forEach { includedFile ->
@ -313,7 +313,7 @@ class PackageConfig(val project: Project) : AttributeHolder {
open class Zip(open var name: String? = null) { open class Zip(open var name: String? = null) {
// internal val includes = arrayListOf<IFileSpec>() // internal val includes = arrayListOf<IFileSpec>()
internal val excludes = arrayListOf<GlobSpec>() internal val excludes = GlobSpec(arrayListOf(), arrayListOf())
@Directive @Directive
public fun from(s: String) = From(s) public fun from(s: String) = From(s)
@ -323,12 +323,12 @@ open class Zip(open var name: String? = null) {
@Directive @Directive
public fun exclude(vararg files: String) { public fun exclude(vararg files: String) {
files.forEach { excludes.add(GlobSpec(it)) } files.forEach { excludes.excludeSpec.add(it) }
} }
@Directive @Directive
public fun exclude(vararg specs: GlobSpec) { public fun exclude(vararg specs: GlobSpec) {
specs.forEach { excludes.add(it) } specs.forEach { excludes.excludeSpec.addAll(it.excludeSpec) }
} }
@Directive @Directive