SBT在任务中触发或检测是否已重新编译任何源

时间:2015-03-15 11:16:31

标签: scala sbt osgi sbt-osgi

此代码段错误:

    def bundleTo(dir: String) = Seq(
        mkBundles <<= (bundle, compile in Compile) map { (fl, anal) =>
            val flTarget = baseDirectory / s"app/$dir/${fl.getName}"

            if (!flTarget.exists()) {
                println("target did not exist copying over")
                IO.copyFile(fl, flTarget)
            } else if (anal.compilations.allCompilations.nonEmpty) {

                println("something was recompiled, copying over")
                IO.copyFile(fl, flTarget)
            }
        },
        mkBundles <<= mkBundles.triggeredBy(compile in Compile)
    )

具体来说是anal.compilations.allCompilations.nonEmpty。我想将plugin移动到一个目录中,只要在触发捆绑重新加载时发生了某些变化。

1 个答案:

答案 0 :(得分:1)

SBT 13.7的这个片段将在源更改时触发内部闭包。在SBT代码库中可能存在预卷逻辑。您可能需要用于SBT设置密钥更改和依赖关系更新的失效逻辑。

myTask := {
    val us = (unmanagedSources in Compile).value
    val cd = streams.value.cacheDirectory / "osgi-recompile-cache"
    println("bam")
    val func = FileFunction.cached(cd, FilesInfo.lastModified) { par: Set[File] =>
        println("boom")
        par
    }
    func(us.toSet)
}

myTask <<= myTask.triggeredBy(compile in Compile)

充实脚本以完成我需要的工作。这是:

import sbt._
import sbt.Keys._
import com.typesafe.sbt.osgi.OsgiKeys._

object OsgiDistUtils {
    lazy val rootDirectory = SettingKey[File]("the root of the entire build")
    lazy val distDirectoryName = SettingKey[String]("name for the dist directory")
    lazy val distdirectory = SettingKey[File]("derived location where the OSGI dist will be constructed")
    lazy val bundleDirectory = SettingKey[File]("location for the bundles")
    lazy val compileBundleAndMove = TaskKey[Unit]("make bundles if needed")

    val osgiDistUtildefaults = Seq(
        distDirectoryName := "app",
        distdirectory := rootDirectory.value / distDirectoryName.value,
        compileBundleAndMove := {
            val targetDirectory = bundleDirectory.value
            val moduleName = name.value
            val bundleFile = bundle.value
            val s = streams.value
            val targetFile = targetDirectory / bundleFile.getName

            if(!targetDirectory.exists()) {
                IO.createDirectory(targetDirectory)
            } else if(!targetFile.exists()) {
                s.log.info(s"module $moduleName did not exist in dist, copying over.")
                IO.copyFile(bundleFile, targetFile)
            } else {
                val sources = (unmanagedSources in Compile).value
                val cp = (managedClasspath in Compile).value
                val cd = s.cacheDirectory / "osgi-recompile-cache"
                FileFunction.cached(cd, FilesInfo.lastModified) { sources: Set[File] =>
                    s.log.info(s"Recompiling $moduleName as sources or classpath have changed.")
                    IO.copyFile(bundleFile, targetFile)
                    sources
                } (sources.toSet ++ cp.seq.map(_.data).toSet)
            }
        },
        compileBundleAndMove <<= compileBundleAndMove.triggeredBy(compile in Compile)
    )

    def createModuleGroup(base: File, name: String, aggregatorSettings: Seq[Def.Setting[_]], moduleSettings: Seq[Def.Setting[_]], projectDeps: Array[Project] = Array()) = {
        val moduleRoot = base / name

        val modules = for (x <- moduleRoot.listFiles if x.isDirectory && x.getName != "target") yield {
            Project(
                id = name + "-%s".format(x.getName).replace(".", "-"),
                base = x,
                settings = moduleSettings ++ osgiDistUtildefaults ++ Seq(
                    bundleDirectory := (distdirectory / name).value
                )
            ).dependsOn(projectDeps.map(x=> ClasspathDependency(x,Some("compile"))):_*)
        }

        val moduleRefs = modules.map { x =>
            x:ProjectReference
        }

        val aggregationNode = Project(
            id = name,
            base = moduleRoot,
            settings = aggregatorSettings
        ).aggregate(moduleRefs: _*)

        (aggregationNode, modules)
    }
}