mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 16:28:12 -07:00
Make "assemble" incremental.
This commit is contained in:
parent
181a043047
commit
1ae9baa97d
6 changed files with 112 additions and 104 deletions
|
@ -1,5 +1,6 @@
|
|||
package com.beust.kobalt
|
||||
|
||||
import com.beust.kobalt.api.KobaltContext
|
||||
import com.beust.kobalt.api.Project
|
||||
|
||||
/**
|
||||
|
@ -7,10 +8,10 @@ import com.beust.kobalt.api.Project
|
|||
* calculated by Kobalt. If they differ, the task gets run. If they are equal, outputChecksums are then compared.
|
||||
* @param outputChecksum The checksum for the output of this task. If null, the output is absent
|
||||
* and the task will be run. If non null, it gets compared against the checksum of the previous run and
|
||||
* if they differ, the task gets run. Note that this parameter is a closure and not a direct value
|
||||
* because Kobalt needs to call it twice: once before the task and once after a successful execution (to store it).
|
||||
* if they differ, the task gets run.
|
||||
* @param task The task to run.
|
||||
*/
|
||||
class IncrementalTaskInfo(val inputChecksum: String?,
|
||||
class IncrementalTaskInfo(val inputChecksum: () -> String?,
|
||||
val outputChecksum: () -> String?,
|
||||
val task: (Project) -> TaskResult)
|
||||
val task: (Project) -> TaskResult,
|
||||
val context: KobaltContext)
|
||||
|
|
|
@ -8,7 +8,7 @@ import com.beust.kobalt.internal.PluginInfo
|
|||
import com.beust.kobalt.maven.DependencyManager
|
||||
import com.beust.kobalt.misc.KobaltExecutors
|
||||
|
||||
public class KobaltContext(val args: Args) {
|
||||
class KobaltContext(val args: Args) {
|
||||
var variant: Variant = Variant()
|
||||
val profiles = arrayListOf<String>()
|
||||
|
||||
|
@ -20,6 +20,14 @@ public class KobaltContext(val args: Args) {
|
|||
|
||||
fun findPlugin(name: String) = Plugins.findPlugin(name)
|
||||
|
||||
/**
|
||||
* When an incremental task decides it's up to date, it sets this boolean to true so that subsequent
|
||||
* tasks in that project can be skipped as well. This is an internal field that should only be set by Kobalt.
|
||||
*/
|
||||
private val incrementalSuccesses = hashSetOf<String>()
|
||||
fun previousTaskWasIncrementalSuccess(projectName: String) = incrementalSuccesses.contains(projectName) ?: false
|
||||
fun setIncrementalSuccess(projectName: String) = incrementalSuccesses.add(projectName)
|
||||
|
||||
//
|
||||
// Injected
|
||||
//
|
||||
|
|
|
@ -84,12 +84,20 @@ class IncrementalManager(val fileName: String = IncrementalManager.BUILD_INFO_FI
|
|||
val taskName = project.name + ":" + shortTaskName
|
||||
var upToDate = false
|
||||
var taskOutputChecksum : String? = null
|
||||
|
||||
if (iti.context.previousTaskWasIncrementalSuccess(project.name)) {
|
||||
//
|
||||
// If the previous task was an incremental success, no need to run
|
||||
//
|
||||
logIncremental(LEVEL, "Previous incremental task was a success, not running $shortTaskName")
|
||||
TaskResult()
|
||||
} else {
|
||||
//
|
||||
// First, compare the input checksums
|
||||
//
|
||||
inputChecksumFor(taskName)?.let { inputChecksum ->
|
||||
val dependsOnDirtyProjects = project.projectExtra.dependsOnDirtyProjects(project)
|
||||
if (inputChecksum == iti.inputChecksum && ! dependsOnDirtyProjects) {
|
||||
if (inputChecksum == iti.inputChecksum() && !dependsOnDirtyProjects) {
|
||||
//
|
||||
// Input checksums are equal, compare the output checksums
|
||||
//
|
||||
|
@ -106,7 +114,7 @@ class IncrementalManager(val fileName: String = IncrementalManager.BUILD_INFO_FI
|
|||
logIncremental(LEVEL, "Project ${project.name} depends on dirty project, running $taskName")
|
||||
} else {
|
||||
logIncremental(LEVEL, "Incremental task $taskName input is out of date, running it"
|
||||
+ " old: $inputChecksum new: ${iti.inputChecksum}")
|
||||
+ " old: $inputChecksum new: ${iti.inputChecksum()}")
|
||||
}
|
||||
project.projectExtra.isDirty = true
|
||||
}
|
||||
|
@ -119,7 +127,7 @@ class IncrementalManager(val fileName: String = IncrementalManager.BUILD_INFO_FI
|
|||
val result = iti.task(project)
|
||||
if (result.success) {
|
||||
logIncremental(LEVEL, "Incremental task $taskName done running, saving checksums")
|
||||
iti.inputChecksum?.let {
|
||||
iti.inputChecksum()?.let {
|
||||
saveInputChecksum(taskName, it)
|
||||
logIncremental(LEVEL, " input checksum \"$it\" saved")
|
||||
}
|
||||
|
@ -135,11 +143,13 @@ class IncrementalManager(val fileName: String = IncrementalManager.BUILD_INFO_FI
|
|||
// Identical input and output checksums, don't run the task
|
||||
//
|
||||
logIncremental(LEVEL, "Incremental task \"$taskName\" is up to date, not running it")
|
||||
iti.context.setIncrementalSuccess(project.name)
|
||||
TaskResult()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val LEVEL = 3
|
||||
val LEVEL = 2
|
||||
private fun logIncremental(level: Int, s: String) = log(level, " INC - $s")
|
||||
}
|
||||
|
|
|
@ -143,22 +143,22 @@ open class JvmCompilerPlugin @Inject constructor(
|
|||
runAfter = arrayOf(JvmCompilerPlugin.TASK_COMPILE))
|
||||
fun taskCompileTest(project: Project): IncrementalTaskInfo {
|
||||
sourceTestDirectories.addAll(context.variant.sourceDirectories(project, context, SourceSet.of(isTest = true)))
|
||||
val inputChecksum = Md5.toMd5Directories(context.testSourceDirectories(project).map {
|
||||
File(project.directory, it.path)
|
||||
})
|
||||
return IncrementalTaskInfo(
|
||||
inputChecksum = inputChecksum,
|
||||
inputChecksum = {
|
||||
Md5.toMd5Directories(context.testSourceDirectories(project).map { File(project.directory, it.path)})
|
||||
},
|
||||
outputChecksum = {
|
||||
Md5.toMd5Directories(listOf(KFiles.makeOutputTestDir(project)))
|
||||
},
|
||||
task = { project -> doTaskCompileTest(project) }
|
||||
task = { project -> doTaskCompileTest(project)},
|
||||
context = context
|
||||
)
|
||||
}
|
||||
|
||||
@IncrementalTask(name = JvmCompilerPlugin.TASK_COMPILE, description = "Compile the project")
|
||||
fun taskCompile(project: Project): IncrementalTaskInfo {
|
||||
// Generate the BuildConfig before invoking sourceDirectories() since that call
|
||||
// might add the buildConfig source directori
|
||||
// might add the buildConfig source directories
|
||||
val sourceDirectory = context.variant.maybeGenerateBuildConfig(project, context)
|
||||
if (sourceDirectory != null) {
|
||||
sourceDirectories.add(sourceDirectory)
|
||||
|
@ -167,15 +167,15 @@ open class JvmCompilerPlugin @Inject constructor(
|
|||
// Set up the source files now that we have the variant
|
||||
sourceDirectories.addAll(context.variant.sourceDirectories(project, context, SourceSet.of(isTest = false)))
|
||||
|
||||
val inputChecksum = Md5.toMd5Directories(context.sourceDirectories(project).map {
|
||||
File(project.directory, it.path)
|
||||
})
|
||||
return IncrementalTaskInfo(
|
||||
inputChecksum = inputChecksum,
|
||||
inputChecksum = {
|
||||
Md5.toMd5Directories(context.sourceDirectories(project).map { File(project.directory, it.path) })
|
||||
},
|
||||
outputChecksum = {
|
||||
Md5.toMd5Directories(listOf(File(project.directory, project.classesDir(context))))
|
||||
},
|
||||
task = { project -> doTaskCompile(project) }
|
||||
task = { project -> doTaskCompile(project) },
|
||||
context = context
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
package com.beust.kobalt.plugin.packaging
|
||||
|
||||
import com.beust.kobalt.JarGenerator
|
||||
import com.beust.kobalt.KobaltException
|
||||
import com.beust.kobalt.TaskResult
|
||||
import com.beust.kobalt.*
|
||||
import com.beust.kobalt.api.*
|
||||
import com.beust.kobalt.api.annotation.Directive
|
||||
import com.beust.kobalt.api.annotation.ExportedProjectProperty
|
||||
import com.beust.kobalt.api.annotation.Task
|
||||
import com.beust.kobalt.archive.*
|
||||
import com.beust.kobalt.glob
|
||||
import com.beust.kobalt.internal.IncrementalManager
|
||||
import com.beust.kobalt.internal.JvmCompilerPlugin
|
||||
import com.beust.kobalt.maven.DependencyManager
|
||||
|
@ -26,7 +23,8 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
|
|||
val executors: KobaltExecutors, val jarGenerator: JarGenerator, val warGenerator: WarGenerator,
|
||||
val zipGenerator: ZipGenerator, val taskContributor: TaskContributor,
|
||||
val pomFactory: PomGenerator.IFactory, val configActor: ConfigActor<InstallConfig>)
|
||||
: BasePlugin(), ITaskContributor, IAssemblyContributor, IConfigActor<InstallConfig> by configActor {
|
||||
: BasePlugin(), ITaskContributor, IIncrementalAssemblyContributor,
|
||||
IConfigActor<InstallConfig> by configActor {
|
||||
|
||||
companion object {
|
||||
const val PLUGIN_NAME = "Packaging"
|
||||
|
@ -53,8 +51,16 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
|
|||
runTask = { doTaskAssemble(project) })
|
||||
}
|
||||
|
||||
// IAssemblyContributor
|
||||
override fun assemble(project: Project, context: KobaltContext) : TaskResult {
|
||||
/**
|
||||
* "assemble" is an incremental task but with a twist. Because it can be costly to determine if any
|
||||
* of the class files generated in the previous phase is new or not, we just don't do that and always
|
||||
* return "null" for both input and output checksums, which would cause that task to always be rerun.
|
||||
* However, we are depending on Kobalt's cascading incremental management to skip up whenever appropriate:
|
||||
* whenever a previous incremental task was a success, all following incremental tasks are automatically
|
||||
* skipped.
|
||||
*/
|
||||
override fun assemble(project: Project, context: KobaltContext) : IncrementalTaskInfo {
|
||||
return IncrementalTaskInfo({ null }, { null }, { project ->
|
||||
try {
|
||||
project.projectProperties.put(PACKAGES, packages)
|
||||
packages.filter { it.project.name == project.name }.forEach { pkg ->
|
||||
|
@ -65,27 +71,10 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
|
|||
pomFactory.create(project).generate()
|
||||
}
|
||||
}
|
||||
return TaskResult()
|
||||
TaskResult()
|
||||
} catch(ex: Exception) {
|
||||
throw KobaltException(ex)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doAssemble(project: Project, context: KobaltContext) : TaskResult {
|
||||
try {
|
||||
project.projectProperties.put(PACKAGES, packages)
|
||||
packages.filter { it.project.name == project.name }.forEach { pkg ->
|
||||
pkg.jars.forEach { jarGenerator.generateJar(pkg.project, context, it) }
|
||||
pkg.wars.forEach { warGenerator.generateWar(pkg.project, context, it) }
|
||||
pkg.zips.forEach { zipGenerator.generateZip(pkg.project, context, it) }
|
||||
if (pkg.generatePom) {
|
||||
pomFactory.create(project).generate()
|
||||
}
|
||||
}
|
||||
return TaskResult()
|
||||
} catch(ex: Exception) {
|
||||
throw KobaltException(ex)
|
||||
}
|
||||
}}, context)
|
||||
}
|
||||
|
||||
@Task(name = TASK_ASSEMBLE, description = "Package the artifacts",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue