diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/FileSpec.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/FileSpec.kt index 720b40c6..b8fb1304 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/FileSpec.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/FileSpec.kt @@ -3,70 +3,87 @@ package com.beust.kobalt import com.beust.kobalt.misc.log import java.io.File import java.nio.file.* -import java.nio.file.FileVisitResult.CONTINUE import java.nio.file.attribute.BasicFileAttributes import java.util.* +/** + * Subclasses of IFileSpec can be turned into a list of files. There are two kings: FileSpec (a single file) + * and GlobSpec (a spec defined by a glob, e.g. ** slash *Test.class) + */ sealed class IFileSpec { - abstract fun toFiles(directory: String): List + abstract fun toFiles(filePath: String, excludes: List = emptyList()): List class FileSpec(val spec: String) : IFileSpec() { - override public fun toFiles(directory: String) = listOf(File(spec)) + override public fun toFiles(filePath: String, excludes: List) = listOf(File(spec)) override public fun toString() = spec } - class GlobSpec(val includeSpec: ArrayList, val excludeSpec: ArrayList) : IFileSpec() { + class GlobSpec(val spec: ArrayList) : IFileSpec() { - constructor(spec: String) : this(arrayListOf(spec), arrayListOf()) + constructor(spec: String) : this(arrayListOf(spec)) - override public fun toFiles(directory: String): List { - - val result = arrayListOf() - val includeMatchers = prepareMatchers(includeSpec.toTypedArray()) - val excludeMatchers = prepareMatchers(excludeSpec.toTypedArray()) - - Files.walkFileTree(Paths.get(directory), object : SimpleFileVisitor() { - override public fun visitFile(path: Path, attrs: BasicFileAttributes): FileVisitResult { - - val rel = Paths.get(directory).relativize(path) - excludeMatchers.forEach { - if (it.matches(rel)) { - log(3, "Excluding ${rel.toFile()}") - return CONTINUE - } - } - includeMatchers.forEach { - if (it.matches(rel)) { - log(3, "Including ${rel.toFile()}") - result.add(rel.toFile()) - return CONTINUE - } - } - - return CONTINUE + private fun isIncluded(includeMatchers: Glob, excludes: List, rel: Path) : Boolean { + excludes.forEach { + if (it.matches(rel)) { + log(2, "Excluding ${rel.toFile()}") + return false } - }) + } + if (includeMatchers.matches(rel)) { + log(2, "Including ${rel.toFile()}") + return true + } + log(2, "Excluding ${rel.toFile()} (not matching any include pattern") + return false + } + + override public fun toFiles(filePath: String, excludes: List): List { + val result = arrayListOf() + val includes = Glob(*spec.toTypedArray()) + + if (File(filePath).isDirectory) { + Files.walkFileTree(Paths.get(filePath), object : SimpleFileVisitor() { + override public fun visitFile(path: Path, attrs: BasicFileAttributes): FileVisitResult { + val rel = Paths.get(filePath).relativize(path) + if (isIncluded(includes, excludes, rel)) { + result.add(rel.toFile()) + } + return FileVisitResult.CONTINUE + } + }) + } else { + if (isIncluded(includes, excludes, Paths.get(filePath))) { + result.add(File(filePath)) + } + } + return result } override public fun toString(): String { var result = "" - includeSpec.apply { + spec.apply { if (!isEmpty()) { result += "Included files: " + joinToString { ", " } } } - excludeSpec.apply { - if (!isEmpty()) { - result += "Excluded files: " + joinToString { ", " } - } - } return result } - - private fun prepareMatchers(specs: Array): List = - specs.map { it -> FileSystems.getDefault().getPathMatcher("glob:$it") } } -} \ No newline at end of file +} + +/** + * A Glob is a simple file name matcher. + */ +class Glob(vararg specs: String) { + val matchers = prepareMatchers(specs.toList()) + + private fun prepareMatchers(specs: List): List = + specs.map { it -> FileSystems.getDefault().getPathMatcher("glob:$it") } + + fun matches(s: String) = matches(Paths.get(s)) + + fun matches(path: Path) = matchers.any { it.matches(path) } +} diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/GenericRunner.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/GenericRunner.kt index 21a0a89b..a8d84692 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/GenericRunner.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/GenericRunner.kt @@ -1,9 +1,6 @@ package com.beust.kobalt.internal -import com.beust.kobalt.IFileSpec -import com.beust.kobalt.JavaInfo -import com.beust.kobalt.SystemProperties -import com.beust.kobalt.TaskResult +import com.beust.kobalt.* import com.beust.kobalt.api.* import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.log @@ -29,8 +26,10 @@ abstract class GenericTestRunner : ITestRunnerContributor { protected fun findTestClasses(project: Project): List { val path = KFiles.joinDir(project.directory, project.buildDirectory, KFiles.TEST_CLASSES_DIR) - val result = IFileSpec.GlobSpec(toClassPaths(project.testIncludes), toClassPaths(project.testExcludes)) - .toFiles(path).map { + val result = IFileSpec.GlobSpec(toClassPaths(project.testIncludes)) + .toFiles(path, project.testExcludes.map { + Glob(it) + }).map { it.toString().replace("/", ".").replace("\\", ".").replace(".class", "") } @@ -39,7 +38,7 @@ abstract class GenericTestRunner : ITestRunnerContributor { } private fun toClassPaths(paths: List): ArrayList = - paths.map { if (it.endsWith(".class")) it else it + ".class" }.toArrayList() + paths.map { if (it.endsWith("class")) it else it + "class" }.toArrayList() /** * @return true if all the tests passed diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/JarUtils.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/JarUtils.kt index 96bdda6a..637c9cba 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/JarUtils.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/JarUtils.kt @@ -1,5 +1,6 @@ package com.beust.kobalt.misc +import com.beust.kobalt.Glob import com.beust.kobalt.IFileSpec import com.google.common.io.CharStreams import java.io.* @@ -29,8 +30,7 @@ public class JarUtils { } private val DEFAULT_JAR_EXCLUDES = - IFileSpec.GlobSpec(arrayListOf(), - arrayListOf("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA")) + Glob("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA") public fun addSingleFile(directory: String, file: IncludedFile, outputStream: ZipOutputStream, expandJarFiles: Boolean, onError: (Exception) -> Unit = DEFAULT_HANDLER) { diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt index 597e6c09..2a1908eb 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt @@ -277,10 +277,13 @@ class KFiles { fun makeOutputTestDir(project: Project) : File = makeDir(project, KFiles.TEST_CLASSES_DIR) - fun isExcluded(file: File, excludes: IFileSpec.GlobSpec) = isExcluded(file.path, excludes) + fun isExcluded(file: String, excludes: Glob) = isExcluded(file, listOf(excludes)) - fun isExcluded(file: String, excludes: IFileSpec.GlobSpec): Boolean = - excludes.toFiles(file).isEmpty() + fun isExcluded(file: File, excludes: Glob) = isExcluded(file.path, listOf(excludes)) + + fun isExcluded(file: File, excludes: List) = isExcluded(file.path, excludes) + + fun isExcluded(file: String, excludes: List): Boolean = excludes.any { it.matches(file) } } fun findRecursively(directory: File, function: Function1): List { diff --git a/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt index 07b000c4..6bd233a6 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt @@ -42,8 +42,7 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana const val TASK_ASSEMBLE: String = "assemble" const val TASK_INSTALL: String = "install" - - fun findIncludedFiles(directory: String, files: List, excludes: IFileSpec.GlobSpec) + fun findIncludedFiles(directory: String, files: List, excludes: List) : List { val result = arrayListOf() files.forEach { includedFile -> @@ -312,7 +311,7 @@ class PackageConfig(val project: Project) : AttributeHolder { open class Zip(open var name: String? = null) { // internal val includes = arrayListOf() - internal val excludes = GlobSpec(arrayListOf(), arrayListOf()) + internal val excludes = arrayListOf() @Directive public fun from(s: String) = From(s) @@ -322,12 +321,12 @@ open class Zip(open var name: String? = null) { @Directive public fun exclude(vararg files: String) { - files.forEach { excludes.excludeSpec.add(it) } + files.forEach { excludes.add(Glob(it)) } } @Directive - public fun exclude(vararg specs: GlobSpec) { - specs.forEach { excludes.excludeSpec.addAll(it.excludeSpec) } + public fun exclude(vararg specs: Glob) { + specs.forEach { excludes.add(it) } } @Directive