diff --git a/kobalt/src/Build.kt b/kobalt/src/Build.kt index 2d0b46db..6f15035a 100644 --- a/kobalt/src/Build.kt +++ b/kobalt/src/Build.kt @@ -120,8 +120,10 @@ val kobaltPluginApi = project { "org.junit.platform:junit-platform-engine:${Versions.junitPlatform}", "org.junit.platform:junit-platform-console:${Versions.junitPlatform}", "org.junit.jupiter:junit-jupiter-engine:${Versions.junitJupiter}", - "org.junit.vintage:junit-vintage-engine:${Versions.junitVintageVersion}" + "org.junit.vintage:junit-vintage-engine:${Versions.junitVintageVersion}", + "org.apache.commons:commons-compress:1.13", + "commons-io:commons-io:2.5" ) exclude(*aether("impl", "spi", "util", "api")) } diff --git a/kobalt/wrapper/kobalt-wrapper.properties b/kobalt/wrapper/kobalt-wrapper.properties index 113a1799..19b565d8 100644 --- a/kobalt/wrapper/kobalt-wrapper.properties +++ b/kobalt/wrapper/kobalt-wrapper.properties @@ -1 +1 @@ -kobalt.version=1.0.58 +kobalt.version=1.0.60 diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/JarGenerator.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/JarGenerator.kt index ddddaebd..61acb1e1 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/JarGenerator.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/JarGenerator.kt @@ -6,13 +6,12 @@ import com.beust.kobalt.archive.Archives import com.beust.kobalt.archive.Zip import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.aether.Scope -import com.beust.kobalt.misc.* +import com.beust.kobalt.misc.KFiles +import com.beust.kobalt.misc.kobaltLog import com.google.inject.Inject import java.io.File import java.io.FileInputStream -import java.io.OutputStream import java.nio.file.Paths -import java.util.jar.JarOutputStream import java.util.jar.Manifest class JarGenerator @Inject constructor(val dependencyManager: DependencyManager) : ArchiveGenerator { @@ -155,10 +154,8 @@ class JarGenerator @Inject constructor(val dependencyManager: DependencyManager) } } - val jarFactory = { os: OutputStream -> JarOutputStream(os, manifest) } - return Archives.generateArchive(project, context, zip.name, ".jar", includedFiles, - true /* expandJarFiles */, jarFactory) + true /* expandJarFiles */, manifest) } } \ No newline at end of file diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/TaskResult.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/TaskResult.kt index 4d6a45f3..241bc045 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/TaskResult.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/TaskResult.kt @@ -1,3 +1,8 @@ package com.beust.kobalt -open public class TaskResult(val success: Boolean = true, val errorMessage: String? = null) +class TestResult(val success: Boolean, val shortMessage: String? = null, val longMessage: String? = null) + +open class TaskResult(val success: Boolean = true, + val testResult: TestResult? = null, + val errorMessage: String? = null +) diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/DependencyHolder.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/DependencyHolder.kt index a561cd9f..e1195ca3 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/DependencyHolder.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/DependencyHolder.kt @@ -13,6 +13,7 @@ interface IDependencyHolder { val compileDependencies : ArrayList val optionalDependencies : ArrayList val compileProvidedDependencies : ArrayList + val compileOnlyDependencies : ArrayList val compileRuntimeDependencies : ArrayList val excludedDependencies : ArrayList val nativeDependencies : ArrayList @@ -29,6 +30,7 @@ open class DependencyHolder : IDependencyHolder { override val compileDependencies : ArrayList = arrayListOf() override val optionalDependencies : ArrayList = arrayListOf() override val compileProvidedDependencies : ArrayList = arrayListOf() + override val compileOnlyDependencies : ArrayList = arrayListOf() override val compileRuntimeDependencies : ArrayList = arrayListOf() override val excludedDependencies : ArrayList = arrayListOf() override val nativeDependencies : ArrayList = arrayListOf() @@ -37,7 +39,7 @@ open class DependencyHolder : IDependencyHolder { override fun dependencies(init: Dependencies.() -> Unit) : Dependencies { dependencies = Dependencies(project, compileDependencies, optionalDependencies, compileProvidedDependencies, - compileRuntimeDependencies, excludedDependencies, nativeDependencies) + compileOnlyDependencies, compileRuntimeDependencies, excludedDependencies, nativeDependencies) dependencies!!.init() return dependencies!! } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/IBuildListener.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/IBuildListener.kt index 1e53cc49..2b0fdadb 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/IBuildListener.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/IBuildListener.kt @@ -4,8 +4,12 @@ package com.beust.kobalt.api * Plug-ins that listen to build events. */ interface IBuildListener : IListener { + + class TaskEndInfo(val success: Boolean, val shortMessage: String? = null, + val longMessage: String? = null) + fun taskStart(project: Project, context: KobaltContext, taskName: String) {} - fun taskEnd(project: Project, context: KobaltContext, taskName: String, success: Boolean) {} + fun taskEnd(project: Project, context: KobaltContext, taskName: String, info: TaskEndInfo) {} fun projectStart(project: Project, context: KobaltContext) {} fun projectEnd(project: Project, context: KobaltContext, status: ProjectBuildStatus) {} diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/ITaskContributor.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/ITaskContributor.kt index 83621451..714bd61b 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/ITaskContributor.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/ITaskContributor.kt @@ -23,7 +23,7 @@ class DynamicTask(override val plugin: IPlugin, override val name: String, overr override fun call(): TaskResult2 { val taskResult = closure.invoke(project) - return TaskResult2(taskResult.success, taskResult.errorMessage, this) + return TaskResult2(taskResult.success, errorMessage = taskResult.errorMessage, value = this) } override fun toString() = "[DynamicTask $name dependsOn=$dependsOn reverseDependsOn=$reverseDependsOn]" diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/Project.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/Project.kt index 2196cbc9..e54e30ec 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/Project.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/Project.kt @@ -91,7 +91,8 @@ open class Project( @Directive fun dependenciesTest(init: Dependencies.() -> Unit) : Dependencies { dependencies = Dependencies(this, testDependencies, arrayListOf(), - testProvidedDependencies, compileRuntimeDependencies, excludedDependencies, nativeDependencies) + testProvidedDependencies, compileOnlyDependencies, compileRuntimeDependencies, + excludedDependencies, nativeDependencies) dependencies!!.init() return dependencies!! } @@ -154,6 +155,7 @@ class Dependencies(val project: Project, val dependencies: ArrayList, val optionalDependencies: ArrayList, val providedDependencies: ArrayList, + val compileOnlyDependencies: ArrayList, val runtimeDependencies: ArrayList, val excludedDependencies: ArrayList, val nativeDependencies: ArrayList) { @@ -244,6 +246,9 @@ class Dependencies(val project: Project, addToDependencies(project, dependencies, arrayOf(dep), excludeConfig = excludeConfig) } + @Directive + fun compileOnly(vararg dep: String) = addToDependencies(project, compileOnlyDependencies, dep) + @Directive fun compileOptional(vararg dep: String) { addToDependencies(project, optionalDependencies, dep, optional = true) diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/archive/Archives.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/archive/Archives.kt index 19054e33..f8bd656c 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/archive/Archives.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/archive/Archives.kt @@ -8,10 +8,7 @@ import com.beust.kobalt.misc.JarUtils import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.kobaltLog import java.io.File -import java.io.FileOutputStream -import java.io.OutputStream import java.util.* -import java.util.zip.ZipOutputStream class Archives { companion object { @@ -20,8 +17,6 @@ class Archives { @ExportedProjectProperty(doc = "The name of the a jar file with a main() method", type = "String") const val JAR_NAME_WITH_MAIN_CLASS = "jarNameWithMainClass" - private val DEFAULT_STREAM_FACTORY = { os : OutputStream -> ZipOutputStream(os) } - fun defaultArchiveName(project: Project) = project.name + "-" + project.version fun generateArchive(project: Project, @@ -30,15 +25,15 @@ class Archives { suffix: String, includedFiles: List, expandJarFiles : Boolean = false, - outputStreamFactory: (OutputStream) -> ZipOutputStream = DEFAULT_STREAM_FACTORY) : File { + manifest: java.util.jar.Manifest? = null) : File { val fullArchiveName = context.variant.archiveName(project, archiveName, suffix) val archiveDir = File(KFiles.libsDir(project)) val result = File(archiveDir.path, fullArchiveName) context.logger.log(project.name, 3, "Creating $result") if (! Features.USE_TIMESTAMPS || isOutdated(project.directory, includedFiles, result)) { try { - outputStreamFactory(FileOutputStream(result)).use { - JarUtils.addFiles(project.directory, includedFiles, it, expandJarFiles) + MetaArchive(result, manifest).use { metaArchive -> + JarUtils.addFiles(project.directory, includedFiles, metaArchive, expandJarFiles) context.logger.log(project.name, 2, "Added ${includedFiles.size} files to $result") context.logger.log(project.name, 1, " Created $result") } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/archive/MetaArchive.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/archive/MetaArchive.kt new file mode 100644 index 00000000..1e531359 --- /dev/null +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/archive/MetaArchive.kt @@ -0,0 +1,79 @@ +package com.beust.kobalt.archive + +import com.beust.kobalt.Glob +import com.beust.kobalt.misc.KFiles +import org.apache.commons.compress.archivers.ArchiveEntry +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream +import java.io.Closeable +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.nio.file.Files +import org.apache.commons.compress.archivers.zip.ZipFile as ApacheZipFile + +/** + * Abstraction of a zip/jar/war archive that automatically manages the addition of expanded jar files. + * Uses ZipArchiveOutputStream for fast inclusion of expanded jar files. + */ +class MetaArchive(outputFile: File, val manifest: java.util.jar.Manifest?) : Closeable { + private val zos = ZipArchiveOutputStream(outputFile).apply { + encoding = "UTF-8" + } + + fun addFile(file: File, path: String) { + FileInputStream(file).use { inputStream -> + val entry = zos.createArchiveEntry(file, path) + maybeAddEntry(entry) { + addEntry(entry, inputStream) + } + } + } + + fun addArchive(jarFile: File) { + ApacheZipFile(jarFile).use { jar -> + val jarEntries = jar.entries + for (entry in jarEntries) { + maybeAddEntry(entry) { + zos.addRawArchiveEntry(entry, jar.getRawInputStream(entry)) + } + } + } + } + + private val DEFAULT_JAR_EXCLUDES = + Glob("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA") + + private val seen = hashSetOf() + + private fun okToAdd(name: String): Boolean = ! seen.contains(name) + && ! KFiles.isExcluded(name, DEFAULT_JAR_EXCLUDES) + + override fun close() { + if (manifest != null) { + Files.createTempFile("aaa", "bbb").toFile().let { manifestFile -> + FileOutputStream(manifestFile).use { fos -> + manifest.write(fos) + } + + val entry = zos.createArchiveEntry(manifestFile, "META-INF/MANIFEST.MF") + addEntry(entry, FileInputStream(manifestFile)) + } + } + zos.close() + } + + private fun addEntry(entry: ArchiveEntry, inputStream: FileInputStream) { + zos.putArchiveEntry(entry) + inputStream.use { ins -> + ins.copyTo(zos, 50 * 1024) + } + zos.closeArchiveEntry() + } + + private fun maybeAddEntry(entry: ArchiveEntry, action:() -> Unit) { + if (okToAdd(entry.name)) { + action() + } + seen.add(entry.name) + } +} diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/BaseProjectRunner.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/BaseProjectRunner.kt index 2dc77ca0..963255bd 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/BaseProjectRunner.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/BaseProjectRunner.kt @@ -1,5 +1,7 @@ package com.beust.kobalt.internal +import com.beust.kobalt.TestResult +import com.beust.kobalt.api.IBuildListener import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.Project import com.beust.kobalt.api.ProjectBuildStatus @@ -25,9 +27,14 @@ abstract class BaseProjectRunner { } fun runBuildListenersForTask(project: Project, context: KobaltContext, taskName: String, start: Boolean, - success: Boolean = false) { + success: Boolean = false, testResult: TestResult? = null) { context.pluginInfo.buildListeners.forEach { - if (start) it.taskStart(project, context, taskName) else it.taskEnd(project, context, taskName, success) + if (start) { + it.taskStart(project, context, taskName) + } else { + val info = IBuildListener.TaskEndInfo(success, testResult?.shortMessage, testResult?.longMessage) + it.taskEnd(project, context, taskName, info) + } } } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/BuildListeners.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/BuildListeners.kt index 1a8781a5..58d8eed8 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/BuildListeners.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/BuildListeners.kt @@ -11,7 +11,8 @@ import java.util.concurrent.ConcurrentHashMap */ class BuildListeners : IBuildListener, IBuildReportContributor { class ProfilerInfo(val taskName: String, val durationMillis: Long) - class ProjectInfo(val projectName: String, var durationMillis: Long = 0) + class ProjectInfo(val projectName: String, var durationMillis: Long = 0, + var shortMessage: String? = null, var longMessage: String? = null) private val startTimes = ConcurrentHashMap() private val timings = arrayListOf() @@ -29,18 +30,21 @@ class BuildListeners : IBuildListener, IBuildReportContributor { } // IBuildListener - override fun taskEnd(project: Project, context: KobaltContext, taskName: String, success: Boolean) { + override fun taskEnd(project: Project, context: KobaltContext, taskName: String, info: IBuildListener.TaskEndInfo) { + val success = info.success if (! success) hasFailures = true startTimes[taskName]?.let { val taskTime = System.currentTimeMillis() - it timings.add(ProfilerInfo(taskName, taskTime)) projectInfos[project.name]?.let { - it.durationMillis += taskTime.toLong() + it.durationMillis += taskTime + if (info.shortMessage != null && it.shortMessage == null) it.shortMessage = info.shortMessage + if (info.longMessage != null && it.longMessage == null) it.longMessage = info.longMessage } } } - private val projectStatuses = arrayListOf>() + private val projectStatuses = arrayListOf>() // IBuildListener override fun projectStart(project: Project, context: KobaltContext) { @@ -49,7 +53,9 @@ class BuildListeners : IBuildListener, IBuildReportContributor { // IBuildListener override fun projectEnd(project: Project, context: KobaltContext, status: ProjectBuildStatus) { - projectStatuses.add(Pair(project, status)) + val shortMessage = projectInfos[project.name]?.shortMessage + val statusText = status.toString() + (if (shortMessage != null) " ($shortMessage)" else "") + projectStatuses.add(Pair(project, statusText)) } // IBuildReportContributor @@ -70,10 +76,15 @@ class BuildListeners : IBuildListener, IBuildReportContributor { } + // Calculate the longest short message so we can create a column long enough to contain it + val width = 12 + (projectInfos.values.map { it.shortMessage?.length ?: 0 }.maxBy { it } ?: 0) + fun col1(s: String) = String.format(" %1\$-30s", s) - fun col2(s: String) = String.format(" %1\$-13s", s) + fun col2(s: String) = String.format(" %1\$-${width}s", s) fun col3(s: String) = String.format(" %1\$-8s", s) + + // Only print the build report if there is more than one project and at least one of them failed if (timings.any()) { // if (timings.size > 1 && hasFailures) { @@ -83,7 +94,7 @@ class BuildListeners : IBuildListener, IBuildReportContributor { table.append(AsciiArt.logBox(listOf(line), AsciiArt.bottomLeft2, AsciiArt.bottomRight2, indent = 10) + "\n") projectStatuses.forEach { pair -> val projectName = pair.first.name - val cl = listOf(col1(projectName), col2(pair.second.toString()), + val cl = listOf(col1(projectName), col2(pair.second), col3(formatMillisLeft(projectInfos[projectName]!!.durationMillis, 8))) .joinToString(AsciiArt.verticalBar) table.append(" " + AsciiArt.verticalBar + " " + cl + " " + AsciiArt.verticalBar + "\n") diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/CompilerUtils.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/CompilerUtils.kt index e84b3de8..758a10e9 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/CompilerUtils.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/CompilerUtils.kt @@ -70,7 +70,12 @@ class CompilerUtils @Inject constructor(val files: KFiles, val dependencyManager copyResources(project, context, SourceSet.of(isTest)) val fullClasspath = dependencyManager.calculateDependencies(project, context, - scopes = if (isTest) listOf(Scope.COMPILE, Scope.TEST) else listOf(Scope.COMPILE)) + scopes = if (isTest) { + listOf(Scope.COMPILE, Scope.COMPILEONLY, Scope.TEST) + } else { + listOf(Scope.COMPILE, Scope.COMPILEONLY) + }) + File(project.directory, buildDirectory.path).mkdirs() diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt index 1ea14a1a..a3e26afd 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DynamicGraph.kt @@ -7,7 +7,8 @@ import java.lang.reflect.InvocationTargetException import java.util.* import java.util.concurrent.* -open class TaskResult2(success: Boolean, errorMessage: String?, val value: T) : TaskResult(success, errorMessage) { +open class TaskResult2(success: Boolean, testResult: TestResult? = null, + errorMessage: String? = null, val value: T) : TaskResult(success, testResult, errorMessage) { override fun toString() = com.beust.kobalt.misc.toString("TaskResult", "value", value, "success", success) } @@ -393,7 +394,7 @@ fun main(argv: Array) { object: IWorker { override fun call(): TaskResult2? { kobaltLog(1, " Running worker $it") - return TaskResult2(true, null, it) + return TaskResult2(true, value = it) } override val priority: Int get() = 0 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 b1f3dcd9..01836be1 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 @@ -16,17 +16,23 @@ abstract class GenericTestRunner: ITestRunnerContributor { abstract val mainClass: String abstract val annotationPackage: String abstract val runnerName: String + open var shortMessage: String? = null + open var longMessage: String? = null abstract fun args(project: Project, context: KobaltContext, classpath: List, testConfig: TestConfig) : List + open fun onFinish(project: Project) {} + open val extraClasspath: List = emptyList() open fun filterTestClasses(classes: List) : List = classes override fun run(project: Project, context: KobaltContext, configName: String, - classpath: List) - = TaskResult(runTests(project, context, classpath, configName)) + classpath: List) : TaskResult { + val tr = runTests(project, context, classpath, configName) + return TaskResult(tr.success, testResult = tr) + } override fun affinity(project: Project, context: KobaltContext) : Int { val result = @@ -99,7 +105,7 @@ abstract class GenericTestRunner: ITestRunnerContributor { * @return true if all the tests passed */ open fun runTests(project: Project, context: KobaltContext, classpath: List, - configName: String) : Boolean { + configName: String) : TestResult { var result = false context.logger.log(project.name, 1, "Running tests with " + runnerName) @@ -140,7 +146,9 @@ abstract class GenericTestRunner: ITestRunnerContributor { } else { throw KobaltException("Couldn't find a test configuration named \"$configName\"") } - return result + + onFinish(project) + return TestResult(result, shortMessage, longMessage) } /* diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt index 7732774d..43a9c6dd 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt @@ -91,7 +91,7 @@ open class JvmCompilerPlugin @Inject constructor( dependencyFilter = dependencyManager.createDependencyFilter(project, project.testDependencies), scopes = listOf(Scope.TEST)) val compileDependencies = dependencyManager.calculateDependencies(project, context, - scopes = listOf(Scope.COMPILE)) + scopes = listOf(Scope.COMPILE, Scope.COMPILEONLY)) val allDependencies = (testDependencies + compileDependencies).distinct() return testContributor.run(project, context, configName, allDependencies.toList()) } else { diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/ParallelProjectRunner.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/ParallelProjectRunner.kt index 6a703a20..d98f0d8a 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/ParallelProjectRunner.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/ParallelProjectRunner.kt @@ -54,12 +54,12 @@ class ParallelProjectRunner(val tasksByNames: (Project) -> ListMultimap ListMultimap { val taskResult = task(project) - return TaskResult2(taskResult.success, taskResult.errorMessage, this) + return TaskResult2(taskResult.success, errorMessage = taskResult.errorMessage, value = this, + testResult = taskResult.testResult) } }) dependsOn.forEach { dependsOn(it, name) } @@ -321,7 +322,7 @@ class TaskWorker(val tasks: List, val dryRun: Boolean, val pluginInfo: Pl success = success and tr.success if (tr.errorMessage != null) errorMessages.add(tr.errorMessage) } - return TaskResult2(success, errorMessages.joinToString("\n"), tasks[0]) + return TaskResult2(success, errorMessage = errorMessages.joinToString("\n"), value = tasks[0]) } // override val timeOut : Long = 10000 diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt index 735b26e1..345919c9 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt @@ -2,6 +2,7 @@ package com.beust.kobalt.internal import com.beust.kobalt.AsciiArt import com.beust.kobalt.TestConfig +import com.beust.kobalt.TestResult import com.beust.kobalt.api.IClasspathDependency import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.Project @@ -12,8 +13,12 @@ import org.testng.remote.strprotocol.JsonMessageSender import org.testng.remote.strprotocol.MessageHelper import org.testng.remote.strprotocol.MessageHub import org.testng.remote.strprotocol.TestResultMessage +import org.w3c.dom.Attr +import org.xml.sax.InputSource import java.io.File +import java.io.FileReader import java.io.IOException +import javax.xml.parsers.DocumentBuilderFactory class TestNgRunner : GenericTestRunner() { @@ -60,11 +65,40 @@ class TestNgRunner : GenericTestRunner() { } } + /** + * Extract test results from testng-results.xml and initialize shortMessage. + */ + override fun onFinish(project: Project) { + File(defaultOutput(project), "testng-results.xml").let { file -> + val ins = InputSource(FileReader(file)) + val doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(ins) + + val root = doc.documentElement + var failed = 0 + var skipped = 0 + var passed = 0 + repeat(root.attributes.length) { + val attribute = root.attributes.item(it) + if (attribute is Attr) when (attribute.name) { + "failed" -> failed = Integer.parseInt(attribute.value) + "skipped" -> skipped = Integer.parseInt(attribute.value) + "passed" -> passed = Integer.parseInt(attribute.value) + } + } + + if (failed == 0) { + shortMessage = "$passed tests" + } else if (failed > 0) { + shortMessage = "$failed failed" + (if (skipped > 0) ", $skipped skipped" else "") + " tests" + } + } + } + val VERSION_6_10 = StringVersion("6.10") fun _runTests(project: Project, context: KobaltContext, classpath: List, // override fun runTests(project: Project, context: KobaltContext, classpath: List, - configName: String): Boolean { + configName: String): TestResult { val testConfig = project.testConfigs.firstOrNull { it.name == configName } @@ -85,7 +119,7 @@ class TestNgRunner : GenericTestRunner() { } return result } else { - return true + return TestResult(true) } } @@ -102,7 +136,8 @@ class TestNgRunner : GenericTestRunner() { } private fun displayPrettyColors(project: Project, context: KobaltContext, - classpath: List, testConfig: TestConfig, versions: Pair): Boolean { + classpath: List, testConfig: TestConfig, versions: Pair) + : TestResult { val port = 2345 // launchRemoteServer(project, context, classpath, testConfig, versions, port) @@ -151,7 +186,7 @@ class TestNgRunner : GenericTestRunner() { val top = it.stackTrace.substring(0, it.stackTrace.indexOf("\n")) kobaltLog(1, " " + it.cls + "." + it.method + "\n " + top) } - return failed.isEmpty() && skipped.isEmpty() + return TestResult(failed.isEmpty() && skipped.isEmpty()) } fun launchRemoteServer(project: Project, context: KobaltContext, classpath: List, diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/DependencyManager.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/DependencyManager.kt index 0ad02ffa..ff2d9fd9 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/DependencyManager.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/DependencyManager.kt @@ -108,6 +108,9 @@ class DependencyManager @Inject constructor(val executors: KobaltExecutors, addAll(project.compileDependencies) addAll(project.compileProvidedDependencies) } + if (scopes.contains(Scope.COMPILEONLY)) { + addAll(project.compileOnlyDependencies) + } if (scopes.contains(Scope.RUNTIME)) { addAll(project.compileRuntimeDependencies) } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/Filters.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/Filters.kt index d4409b03..0a661c2c 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/Filters.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/Filters.kt @@ -15,7 +15,7 @@ object Filters { override fun accept(p0: DependencyNode, p1: MutableList): Boolean { val result = p0.dependency != null && ! p0.dependency.optional if (! result) { - kobaltLog(2, "Excluding from optional filter: $p0") + kobaltLog(3, "Excluding from optional filter: $p0") } return result } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt index 48b3e836..376081df 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt @@ -38,13 +38,27 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings, filter: DependencyFilter = Filters.EXCLUDE_OPTIONAL_FILTER) : Artifact = resolve(id, scope, filter).root.artifact - fun resolve(id: String, scope: Scope? = null, + fun resolve(passedId: String, scope: Scope? = null, filter: DependencyFilter = Filters.EXCLUDE_OPTIONAL_FILTER, repos: List = emptyList()): DependencyResult { - val dependencyRequest = DependencyRequest(createCollectRequest(id, scope, repos), filter) + val mavenId = MavenId.toMavenId(passedId) + val id = + if (isRangeVersion(mavenId)) { + val artifact = DefaultArtifact(mavenId) + val request = VersionRangeRequest(artifact, createRepos(repos), null) + val rr = system.resolveVersionRange(session, request) + val newArtifact = DefaultArtifact(artifact.groupId, artifact.artifactId, artifact.classifier, + artifact.extension, rr.highestVersion.toString()) + artifactToId(newArtifact) + } else { + passedId + } + + val collectRequest = createCollectRequest(id, scope, repos) + val dependencyRequest = DependencyRequest(collectRequest, filter) val result = system.resolveDependencies(session, dependencyRequest) -// GraphUtil.displayGraph(listOf(result.root), { it -> it.children }, -// { it: DependencyNode, indent: String -> println(indent + it.toString()) }) + // GraphUtil.displayGraph(listOf(result.root), { it -> it.children }, + // { it: DependencyNode, indent: String -> println(indent + it.toString()) }) return result } @@ -58,7 +72,7 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings, val rr = resolve(id, scope, filter) val children = rr.root.children.filter { - filter == null || filter.accept(DefaultDependencyNode(it.dependency), emptyList()) + filter.accept(DefaultDependencyNode(it.dependency), emptyList()) }.filter { it.dependency.scope != Scope.SYSTEM.scope } @@ -109,6 +123,9 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings, } } + private fun createRepos(repos: List) : List + = kobaltRepositories + repos.map { createRepo(HostConfig(it)) } + private fun createCollectRequest(id: String, scope: Scope? = null, repos: List = emptyList()) = CollectRequest().apply { val allIds = arrayListOf(MavenId.toMavenId(id)) @@ -116,6 +133,6 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings, dependencies = allIds.map { Dependency(DefaultArtifact(it), scope?.scope) } root = Dependency(DefaultArtifact(MavenId.toMavenId(id)), scope?.scope) - repositories = kobaltRepositories + repos.map { createRepo(HostConfig(it)) } + repositories = createRepos(repos) } } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/Scope.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/Scope.kt index 6c18f555..7822159e 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/Scope.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/Scope.kt @@ -12,6 +12,7 @@ sealed class Scope(val scope: String, val dependencyLambda: (Project) -> List emptyList() }) object RUNTIME : Scope(JavaScopes.RUNTIME, Project::compileRuntimeDependencies) object TEST : Scope(JavaScopes.TEST, Project::testDependencies) diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/Git.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/Git.kt index f4c4161f..f8892390 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/Git.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/Git.kt @@ -11,7 +11,7 @@ class Git @Inject constructor() { if (uploadResult.success && enabled) { val tagSuccess = tagRelease(project, annotated, tag, message) if (! tagSuccess) { - TaskResult(false, "Couldn't tag the project") + TaskResult(false, errorMessage = "Couldn't tag the project") } else { TaskResult() } 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 81f55b8e..81420a43 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,14 +1,16 @@ package com.beust.kobalt.misc -import com.beust.kobalt.* +import com.beust.kobalt.From +import com.beust.kobalt.IFileSpec +import com.beust.kobalt.IncludedFile +import com.beust.kobalt.To +import com.beust.kobalt.archive.MetaArchive import com.google.common.io.CharStreams -import java.io.* -import java.util.jar.JarEntry +import java.io.File +import java.io.FileOutputStream +import java.io.InputStreamReader import java.util.jar.JarFile -import java.util.jar.JarInputStream -import java.util.zip.ZipEntry import java.util.zip.ZipFile -import java.util.zip.ZipOutputStream class JarUtils { companion object { @@ -19,18 +21,15 @@ class JarUtils { } } - fun addFiles(directory: String, files: List, target: ZipOutputStream, + fun addFiles(directory: String, files: List, metaArchive: MetaArchive, expandJarFiles: Boolean, onError: (Exception) -> Unit = DEFAULT_HANDLER) { files.forEach { - addSingleFile(directory, it, target, expandJarFiles, onError) + addSingleFile(directory, it, metaArchive, expandJarFiles, onError) } } - private val DEFAULT_JAR_EXCLUDES = - Glob("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA") - - fun addSingleFile(directory: String, file: IncludedFile, outputStream: ZipOutputStream, + fun addSingleFile(directory: String, file: IncludedFile, metaArchive: MetaArchive, expandJarFiles: Boolean, onError: (Exception) -> Unit = DEFAULT_HANDLER) { val foundFiles = file.allFromFiles(directory) foundFiles.forEach { foundFile -> @@ -49,42 +48,22 @@ class JarUtils { // Directory val includedFile = IncludedFile(From(""), To(""), listOf(IFileSpec.GlobSpec("**"))) - addSingleFile(localFile.path, includedFile, outputStream, expandJarFiles) + addSingleFile(localFile.path, includedFile, metaArchive, expandJarFiles) } else { - if (file.expandJarFiles && foundFile.name.endsWith(".jar") && ! file.from.contains("resources")) { - kobaltLog(2, " Writing contents of jar file $foundFile") - JarInputStream(FileInputStream(localFile)).use { stream -> - var entry = stream.nextEntry - while (entry != null) { - if (!entry.isDirectory && !KFiles.isExcluded(entry.name, DEFAULT_JAR_EXCLUDES)) { - addEntry(stream, JarEntry(entry), outputStream, onError) - } - entry = stream.nextEntry - } - } - } else { - val entryFileName = KFiles.fixSlashes(file.to(foundFile.path)) - val entry = JarEntry(entryFileName) - entry.time = localFile.lastModified() - FileInputStream(localFile).use { stream -> - addEntry(stream, entry, outputStream, onError) + try { + if (file.expandJarFiles && foundFile.name.endsWith(".jar") && !file.from.contains("resources")) { + kobaltLog(2, " Writing contents of jar file $foundFile") + metaArchive.addArchive(foundFile) + } else { + metaArchive.addFile(File(directory, fromFile.path), foundFile.path) } + } catch(ex: Exception) { + onError(ex) } } } } - private fun addEntry(inputStream: InputStream, entry: ZipEntry, outputStream: ZipOutputStream, - onError: (Exception) -> Unit = DEFAULT_HANDLER) { - try { - outputStream.putNextEntry(entry) - inputStream.copyTo(outputStream, 50 * 1024) - outputStream.closeEntry() - } catch(ex: Exception) { - onError(ex) - } - } - fun extractTextFile(zip : ZipFile, fileName: String) : String? { val enumEntries = zip.entries() while (enumEntries.hasMoreElements()) { diff --git a/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java b/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java index f91bf3c1..f57db6d2 100644 --- a/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java +++ b/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java @@ -345,6 +345,11 @@ public class Main { try { Files.createDirectories(entryPath.getParent()); Files.copy(zipFile.getInputStream(entry), entryPath, StandardCopyOption.REPLACE_EXISTING); + if (!isWindows() && entry.getName().endsWith(KOBALTW)) { + if (!entryPath.toFile().setExecutable(true)) { + log(1, "Couldn't make distribution " + KOBALTW + " executable"); + } + } } catch (FileSystemException ex) { log(2, "Couldn't copy to " + entryPath); } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt index 01b7c90d..97d7644b 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt @@ -94,11 +94,11 @@ class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltL } return if (result) { - TaskResult(true, "Compilation succeeded") + TaskResult(true, errorMessage = "Compilation succeeded") } else { val message = "Compilation errors, command:\n$command\n" + errorMessage logk(1, message) - TaskResult(false, message) + TaskResult(false, errorMessage = message) } } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt index a1c1176c..5fa6af71 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt @@ -90,7 +90,7 @@ class KotlinCompiler @Inject constructor( return invokeCompilerInSeparateProcess(classpath, info, actualVersion, project) } else { - return invokeCompilerDirectly(projectName ?: "kobalt-" + Random().nextInt(), outputDir, + return invokeCompilerDirectly(project, projectName ?: "kobalt-" + Random().nextInt(), outputDir, info, classpath, filesToCompile) } } @@ -126,14 +126,23 @@ class KotlinCompiler @Inject constructor( // The Kotlin compiler issues warnings on stderr :-( containsErrors = { errors: List -> errors.any { it.contains("rror")} } }).invoke() - return TaskResult(result == 0, "Error while compiling") + return TaskResult(result == 0, errorMessage = "Error while compiling") } - private fun invokeCompilerDirectly(projectName: String, outputDir: String?, info: CompilerActionInfo, - classpathString: String, filesToCompile: Int): TaskResult { + private fun invokeCompilerDirectly(project: Project?, projectName: String, outputDir: String?, + info: CompilerActionInfo, classpathString: String, filesToCompile: Int): TaskResult { val sourceFiles = info.sourceFiles val friends = info.friendPaths.toTypedArray() - val args = K2JVMCompilerArguments().apply { + + // Collect the compiler args from kotlinCompiler{} and from settings.xml and parse them + val args2 = (kotlinConfig(project)?.args ?: arrayListOf()) + + (settings.kobaltCompilerFlags?.split(" ") ?: listOf()) + val args = K2JVMCompilerArguments() + val compiler = K2JVMCompiler() + compiler.parseArguments(args2.toTypedArray(), args) + + // Override important arguments with our values + args.apply { moduleName = projectName destination = outputDir classpath = classpathString @@ -224,7 +233,7 @@ class KotlinCompiler @Inject constructor( if (cliArgs.noIncrementalKotlin || Kobalt.context?.internalContext?.noIncrementalKotlin ?: false) { log(2, " Kotlin incremental compilation is disabled") val duration = benchmarkMillis { - K2JVMCompiler().exec(collector, Services.Builder().build(), args) + compiler.exec(collector, Services.Builder().build(), args) } log(1, " Regular compilation time: ${duration.first} ms") TaskResult(duration.second == ExitCode.OK) diff --git a/src/main/kotlin/com/beust/kobalt/plugin/packaging/WarGenerator.kt b/src/main/kotlin/com/beust/kobalt/plugin/packaging/WarGenerator.kt index 6556e033..4f42f6c4 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/packaging/WarGenerator.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/packaging/WarGenerator.kt @@ -88,7 +88,7 @@ class WarGenerator @Inject constructor(val dependencyManager: DependencyManager, val jarFactory = { os: OutputStream -> JarOutputStream(os, manifest) } return Archives.generateArchive(project, context, war.name, ".war", files, - false /* don't expand jar files */, jarFactory) + false /* don't expand jar files */, manifest) } } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/publish/BintrayApi.kt b/src/main/kotlin/com/beust/kobalt/plugin/publish/BintrayApi.kt index 7793a77d..878d0e1c 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/publish/BintrayApi.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/publish/BintrayApi.kt @@ -204,7 +204,7 @@ class BintrayApi @Inject constructor(val http: Http, return TaskResult() } else { error(" Errors while uploading:\n" + errorMessages.map { " $it" }.joinToString("\n")) - return TaskResult(false, errorMessages.joinToString("\n")) + return TaskResult(false, errorMessage = errorMessages.joinToString("\n")) } } else { warn("Found no artifacts to upload") diff --git a/src/main/kotlin/com/beust/kobalt/plugin/publish/PublishPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/publish/PublishPlugin.kt index 23519c43..f5b1e4d0 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/publish/PublishPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/publish/PublishPlugin.kt @@ -153,7 +153,7 @@ class PublishPlugin @Inject constructor(val files: KFiles, val factory: PomGener TaskResult() } - val result = TaskResult(tmpResult.success, messages.joinToString("\n ")) + val result = TaskResult(tmpResult.success, errorMessage = messages.joinToString("\n ")) return result } diff --git a/src/main/resources/kobalt.properties b/src/main/resources/kobalt.properties index 113a1799..19b565d8 100644 --- a/src/main/resources/kobalt.properties +++ b/src/main/resources/kobalt.properties @@ -1 +1 @@ -kobalt.version=1.0.58 +kobalt.version=1.0.60 diff --git a/src/main/resources/templates/build.mustache b/src/main/resources/templates/build.mustache index 07a7dc96..808dc24a 100644 --- a/src/main/resources/templates/build.mustache +++ b/src/main/resources/templates/build.mustache @@ -2,36 +2,37 @@ import com.beust.kobalt.* import com.beust.kobalt.plugin.packaging.* import com.beust.kobalt.plugin.application.* {{imports}} - +{{#repositories.length}} val bs = buildScript { repos({{{repositories}}}) } - +{{/repositories.length}} {{#properties}} val {{first}} = "{{second}}" {{/properties}} val p = {{directive}} { - name = "{{name}}" group = "{{group}}" artifactId = name version = "{{version}}" - +{{#sourceDirectories.length}} sourceDirectories { {{#sourceDirectories}} path("{{toString}}") {{/sourceDirectories}} } - +{{/sourceDirectories.length}} +{{#sourceDirectoriesTest.length}} sourceDirectoriesTest { {{#sourceDirectoriesTest}} path("{{toString}}") {{/sourceDirectoriesTest}} } +{{/sourceDirectoriesTest.length}} dependencies { -// compile("com.beust:jcommander:1.48") +// compile("com.beust:jcommander:1.68") {{#mainDependencies}} compile("{{groupId}}:{{artifactId}}:{{version}}") {{/mainDependencies}} @@ -42,7 +43,6 @@ val p = {{directive}} { {{#testDependencies}} compile("{{groupId}}:{{artifactId}}:{{version}}") {{/testDependencies}} - } assemble { @@ -53,6 +53,4 @@ val p = {{directive}} { application { mainClass = "com.example.{{mainClass}}" } - - } diff --git a/src/test/kotlin/com/beust/kobalt/VerifyKobaltZipTest.kt b/src/test/kotlin/com/beust/kobalt/VerifyKobaltZipTest.kt index 06a96888..03278f4e 100644 --- a/src/test/kotlin/com/beust/kobalt/VerifyKobaltZipTest.kt +++ b/src/test/kotlin/com/beust/kobalt/VerifyKobaltZipTest.kt @@ -1,9 +1,10 @@ package com.beust.kobalt -import com.beust.kobalt.misc.KFiles -import com.beust.kobalt.misc.kobaltLog +import com.beust.kobalt.misc.* import org.testng.annotations.Test import java.io.* +import java.nio.file.Files +import java.nio.file.Paths import java.util.* import java.util.jar.* @@ -37,6 +38,11 @@ class VerifyKobaltZipTest : KobaltTest() { throw KobaltException("kobaltw has wrong line endings") } } + if (OperatingSystem.current().isWindows()) { + warn("Can't determine if kobaltw is executable under Windows") + } else if (!Files.isExecutable(Paths.get("dist/kobaltw"))) { + throw KobaltException("kobaltw has invalid permissions") + } foundKobaltw = true } else if (entry.name.endsWith(mainJarFilePath)) { val ins = zipFile.getInputStream(entry) diff --git a/src/test/kotlin/com/beust/kobalt/internal/DynamicGraphTest.kt b/src/test/kotlin/com/beust/kobalt/internal/DynamicGraphTest.kt index 64dbd5bd..ca74505a 100644 --- a/src/test/kotlin/com/beust/kobalt/internal/DynamicGraphTest.kt +++ b/src/test/kotlin/com/beust/kobalt/internal/DynamicGraphTest.kt @@ -31,7 +31,7 @@ class DynamicGraphTest { override fun call() : TaskResult2 { kobaltLog(2, "Running node $n") runNodes.add(n) - return TaskResult2(errorFunction(n), null, n) + return TaskResult2(errorFunction(n), value = n) } }