From 4bc1fae32f8e1ae640e85ed15a577c557e18e385 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 27 Jan 2011 23:26:19 +0000 Subject: A bunch of work on the sbt build. No review. --- project/build/AdditionalResources.scala | 24 +++++----- project/build/BasicLayer.scala | 77 +++++++++++++++++---------------- project/build/Compilation.scala | 29 +++++-------- project/build/CompilationStep.scala | 2 +- project/build/ExternalTaskRunner.scala | 34 --------------- project/build/ForkSBT.scala | 49 +++++++++++++++++++++ project/build/Partest.scala | 75 ++++++++++++++++++++++---------- project/build/ScalaBuildProject.scala | 2 - project/build/ScalaSBTBuilder.scala | 44 ++++++++++++------- project/build/Scaladoc.scala | 5 +-- project/plugins/Plugins.scala | 6 +++ 11 files changed, 197 insertions(+), 150 deletions(-) delete mode 100644 project/build/ExternalTaskRunner.scala create mode 100644 project/build/ForkSBT.scala create mode 100644 project/plugins/Plugins.scala diff --git a/project/build/AdditionalResources.scala b/project/build/AdditionalResources.scala index a347e0dbd1..edb4c4e9a2 100644 --- a/project/build/AdditionalResources.scala +++ b/project/build/AdditionalResources.scala @@ -34,18 +34,18 @@ object AdditionalResources { trait ResourcesToCopy { self : CompilationStep => + def getResources(from: Path, filter: FileFilter): PathFinder = (from ##)** filter def getResources(from: Path): PathFinder = getResources(from, AdditionalResources.basicFilter) def copyDestination: Path def filesToCopy: PathFinder + def copy = { log.info("Copying files for "+name) - try { - FileUtilities.copy(filesToCopy.get, copyDestination, log) - } catch { - case e => Some(e.toString) - } + try { FileUtilities.copy(filesToCopy.get, copyDestination, log) } + catch { case e => Some(e.toString) } + None } } @@ -62,21 +62,17 @@ trait PropertiesToWrite { val properties = new Properties - def insert(list: List[(String, String)]): Unit = list match { - case Nil => - case x :: xs => { - properties setProperty(x._1, x._2) - insert(xs) - } - } + def insert(list: List[(String, String)]): Unit = + list foreach { case (k, v) => properties.setProperty(k, v) } try { insert(propertyList) val destFile = propertyDestination.asFile val stream = new FileOutputStream(destFile) properties.store(stream, null) - } catch { - case e => Some(e.toString) + } + catch { + case e: Exception => Some(e.toString) } None } diff --git a/project/build/BasicLayer.scala b/project/build/BasicLayer.scala index c4006d9aae..b03637ad4d 100644 --- a/project/build/BasicLayer.scala +++ b/project/build/BasicLayer.scala @@ -13,13 +13,17 @@ abstract class BasicLayer(val info: ProjectInfo, val versionNumber: String, prev with AdditionalResources with LayerCompilation with BuildInfoEnvironment -{ + with ForkSBT { layer => // All path values must be lazy in order to avoid initialization issues (sbt way of doing things) def buildInfoEnvironmentLocation: Path = outputRootPath / ("build-"+name+".properties") + val forkProperty = "scala.sbt.forked" + def isDebug = info.logger atLevel Level.Debug + def isForked = System.getProperty(forkProperty) != null + // Support of triggered execution at project level override def watchPaths = info.projectPath / "src" ** ("*.scala" || "*.java" || AdditionalResources.basicFilter) override def dependencies = info.dependencies @@ -43,20 +47,15 @@ abstract class BasicLayer(val info: ProjectInfo, val versionNumber: String, prev * was created correctly and compile it if necessary */ lazy val startLayer = previousLayer match { - case Some(previous) => task { - None - }.dependsOn(previous.finishLayer) - case None => task {None} + case Some(previous) => task(None) dependsOn previous.finishLayer + case _ => task(None) } - def buildLayer: Option[String] = { - externalCompilation orElse - writeProperties - } + def buildLayer = externalCompilation orElse writeProperties + + lazy val build = compile - lazy val build = task { - buildLayer - }.dependsOn(startLayer) + lazy val compile = task(buildLayer) dependsOn startLayer /** * Finish the compilation and ressources copy and generation @@ -64,39 +63,40 @@ abstract class BasicLayer(val info: ProjectInfo, val versionNumber: String, prev * it permit locker to override it in order to lock the layer when the compilation * is finished. */ - lazy val finishLayer: ManagedTask = task {None}.dependsOn(build) + lazy val finishLayer: ManagedTask = task(None) dependsOn compile - def cleaningList = layerOutput :: layerEnvironment.envBackingPath :: packingDestination :: Nil + def cleaningList = List( + layerOutput, + layerEnvironment.envBackingPath, + packingDestination + ) def cleanFiles = FileUtilities.clean(cleaningList, true, log) + // We use super.task, so cleaning is done in every case, even when locked lazy val clean: Task = nextLayer match { - case None => super.task { cleanFiles}// We use super.task, so cleaning is done in every case, even when locked - case Some(next) => super.task {cleanFiles}.dependsOn {next.clean} - + case Some(next) => super.task(cleanFiles) dependsOn next.clean + case _ => super.task(cleanFiles) } - - lazy val cleanBuild = task { - cleanFiles orElse buildLayer - }.dependsOn(startLayer) + lazy val cleanBuild = task(cleanFiles orElse buildLayer) dependsOn startLayer // Utility methods (for quick access) - def libraryOutput = libraryConfig.outputDirectory - def actorsOutput = actorsConfig.outputDirectory - def dbcOutput = dbcConfig.outputDirectory - def swingOutput = swingConfig.outputDirectory - def scalapOutput = scalapConfig.outputDirectory - def librarySrcDir = libraryConfig.srcDir - def compilerOutput = compilerConfig.outputDirectory - def compilerSrcDir = compilerConfig.srcDir - def actorsSrcDir = actorsConfig.srcDir - def swingSrcDir = swingConfig.srcDir - def outputLibraryJar = libraryWS.packagingConfig.jarDestination + def actorsOutput = actorsConfig.outputDirectory + def actorsSrcDir = actorsConfig.srcDir + def compilerOutput = compilerConfig.outputDirectory + def compilerSrcDir = compilerConfig.srcDir + def dbcOutput = dbcConfig.outputDirectory + def libraryOutput = libraryConfig.outputDirectory + def librarySrcDir = libraryConfig.srcDir def outputCompilerJar = compilerConfig.packagingConfig.jarDestination - def outputPartestJar = partestConfig.packagingConfig.jarDestination - def outputScalapJar = scalapConfig.packagingConfig.jarDestination + def outputLibraryJar = libraryWS.packagingConfig.jarDestination + def outputPartestJar = partestConfig.packagingConfig.jarDestination + def outputScalapJar = scalapConfig.packagingConfig.jarDestination + def scalapOutput = scalapConfig.outputDirectory + def swingOutput = swingConfig.outputDirectory + def swingSrcDir = swingConfig.srcDir - // CONFIGURATION OF THE COMPILTATION STEPS + // CONFIGURATION OF THE COMPILATION STEPS /** * Configuration of the core library compilation @@ -210,7 +210,7 @@ abstract class BasicLayer(val info: ProjectInfo, val versionNumber: String, prev lazy val packagingConfig = new PackagingConfiguration( libsDestination / scalapJarName, - List(outputDirectory ##,decoderProperties) + List(outputDirectory ##, decoderProperties) ) } @@ -227,7 +227,10 @@ abstract class BasicLayer(val info: ProjectInfo, val versionNumber: String, prev def filesToCopy = getResources(srcDir) def propertyDestination = outputDirectory / "partest.properties" - def propertyList = ("version.number",partestVersionNumber.value.toString)::("copyright.string",copyright.value)::Nil + def propertyList = List( + ("version.number", partestVersionNumber.value.toString), + ("copyright.string", copyright.value) + ) lazy val packagingConfig = new PackagingConfiguration(libsDestination / partestJarName, List(outputDirectory ##)) diff --git a/project/build/Compilation.scala b/project/build/Compilation.scala index 116a25d979..9a313cab07 100644 --- a/project/build/Compilation.scala +++ b/project/build/Compilation.scala @@ -9,7 +9,6 @@ import FileUtilities._ trait Compilation { self : ScalaBuildProject with BuildInfoEnvironment => - def lastUsedCompilerVersion = layerEnvironment.lastCompilerVersion def instantiationCompilerJar: Path @@ -31,14 +30,10 @@ trait Compilation { instanceScope[Option[String]]{ scala => lazy val analyzing = new AnalyzingCompiler(scala, componentManager, xsbt.ClasspathOptions.manual, log) - def compilerVersionHasChanged: Boolean ={ - val lastVersion = lastUsedCompilerVersion.value - !(lastVersion.compareTo(scala.actualVersion) == 0) - - } + def compilerVersionHasChanged = lastUsedCompilerVersion.value != scala.actualVersion def checkAndClean(cleanFunction:() => Option[String]): Option[String] ={ - if (compilerVersionHasChanged){ + if (compilerVersionHasChanged) { log.info("The compiler version used to build this layer has changed since last time or this is a clean build.") lastUsedCompilerVersion.update(scala.actualVersion) layerEnvironment.saveEnvironment @@ -49,16 +44,17 @@ trait Compilation { } } - def compile0(steps: List[Step]): Option[String] = steps match { - case x :: xs => x match { - case c: CompilationStep => { + def compile0(steps: List[Step]): Option[String] = { + steps foreach { + case c: CompilationStep => val conditional = new CompileConditional(c, analyzing) log.info("") - conditional.run orElse copy(c) orElse earlyPackaging(c) orElse compile0(xs) - } - case _ => compile0(xs) + val res = conditional.run orElse copy(c) orElse earlyPackaging(c) + if (res.isDefined) + return res + case _ => () } - case Nil => None + None } /** @@ -104,8 +100,5 @@ trait LayerCompilation extends Compilation { */ lazy val compilation = task {compile(allSteps, cleanCompilation _)} - def externalCompilation: Option[String] = { - val runner = new ExternalTaskRunner(projectRoot, this.name, compilation.name, "Error during external compilation", log) - runner.runTask - } + def externalCompilation: Option[String] = maybeFork(compilation) } diff --git a/project/build/CompilationStep.scala b/project/build/CompilationStep.scala index d5fdb73f8c..d6310a9646 100644 --- a/project/build/CompilationStep.scala +++ b/project/build/CompilationStep.scala @@ -1,7 +1,7 @@ import sbt._ import AdditionalResources._ -trait Step extends Dag[Step] { +trait Step extends Dag[Step] { def dependencies: Iterable[Step] } diff --git a/project/build/ExternalTaskRunner.scala b/project/build/ExternalTaskRunner.scala deleted file mode 100644 index b99af1b003..0000000000 --- a/project/build/ExternalTaskRunner.scala +++ /dev/null @@ -1,34 +0,0 @@ -import sbt._ -import ExternalTaskRunner._ - -/** - * Provide a way to launch a specific task in a new sbt instance. - * As the compilation process need to be able to compile in a different process (due to memory related - * performance issue) and that in order to keep incremental compilation, we allow to launch a task from a - * specific project / sub-project in a different instance of sbt that disappear once the task has finished. - */ -class ExternalTaskRunner(root:Path,projectName:String, taskName :String,errorMessage:String, log: Logger ){ - - def runTask:Option[String] ={ - - val cmd:Seq[String] = Seq("project "+projectName,taskName) // TODO forward logging level (for example debug) - val externalSbt = Process(sbtCommand ++ cmd) - log.info("Launching task ["+taskName+"] of project ["+projectName+"] in new sbt instance") - externalSbt.! match{ - case 0 => None - case _ => Some(errorMessage) - } - - } - -} - -object ExternalTaskRunner{ - /** - * parameters needed to launch another instance of sbt - */ - val sbtCommand = Seq("sbt") // TODO remove dependency on sbt being on the path of the user - - - -} diff --git a/project/build/ForkSBT.scala b/project/build/ForkSBT.scala new file mode 100644 index 0000000000..986c2166dc --- /dev/null +++ b/project/build/ForkSBT.scala @@ -0,0 +1,49 @@ +/** Scala SBT build + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +import sbt._ + +/** Worked out a way to fork sbt tasks, preserving all sbt command line + * options and without hardcoding anything. + */ +trait ForkSBT { + self: BasicLayer => + + def jvmArguments: List[String] = { + import scala.collection.jcl.Conversions._ + import java.lang.management.ManagementFactory + ManagementFactory.getRuntimeMXBean().getInputArguments().toList + } + + private var extraJVMArgs: List[String] = Nil + def withJVMArgs[T](args: String*)(body: => T): T = { + val saved = extraJVMArgs + extraJVMArgs = args.toList + try { body } + finally extraJVMArgs = saved + } + + // Set a property in forked sbts to inhibit possible forking cycles. + def markForked = "-D" + forkProperty + "=true" + + /** Forks a new process to run "sbt task task ...": + */ + def forkTasks(tasks: String*): Boolean = { + require (!isForked, "Tried to fork but sbt is already forked: " + tasks.mkString(" ")) + + val sbtJar = System.getProperty("java.class.path") + val sbtMain = "xsbt.boot.Boot" // ok, much of anything. + val args = jvmArguments ++ Seq(markForked, "-classpath", sbtJar, sbtMain) ++ tasks + + log.info("Forking: " + args.mkString("java ", " ", "")) + Fork.java(None, args, StdoutOutput) == 0 + } + def maybeFork(task: TaskManager#Task): Option[String] = maybeFork(task, "Error during external compilation.") + def maybeFork(task: TaskManager#Task, errorMsg: String): Option[String] = { + if (isForked) task.run + else if (forkTasks("project " + this.name, task.name)) None + else Some(errorMsg) + } +} diff --git a/project/build/Partest.scala b/project/build/Partest.scala index 33d601e7ac..1828ec158c 100755 --- a/project/build/Partest.scala +++ b/project/build/Partest.scala @@ -91,7 +91,6 @@ trait PartestRunner { val javac = Some(javaHome / "bin" / "javac" asFile) val timeout = Some("2400000") val loader = info.launcher.topLoader - val isDebug = info.logger atLevel Level.Debug log.debug("Ready to run tests") @@ -106,15 +105,21 @@ trait PartestRunner { ) } - lazy val externalPartest = task {args => task { - val runner = new ExternalTaskRunner(projectRoot,this.name, "partest " + args.mkString(" "),"Some tests have failed", log) - runner.runTask - }.dependsOn(pack) + def partestDebugProp = + if (isDebug) List("-Dpartest.debug=true") + else Nil - }.completeWith(partestCompletionList) + lazy val externalPartest = task { args => + task { + if (isForked) partest(args).run + else withJVMArgs(partestDebugProp ++ args: _*) { + if (forkTasks("partest")) None + else Some("Some tests failed.") + } + } dependsOn pack + } completeWith partestCompletionList - lazy val partest = task{ - args => + lazy val partest = task { args => var failedOnly = false def setOptions(options: List[String], acc: List[String]): List[String] = options match { @@ -128,9 +133,8 @@ trait PartestRunner { } def resolveSets(l: List[String], rem: List[String], acc: List[TestSet]): (List[String], List[TestSet]) = { - def searchSet(arg: String): Option[TestSet] = { - filesTestMap.get(arg) - } + def searchSet(arg: String): Option[TestSet] = filesTestMap get arg + l match { case x :: xs => searchSet(x) match { case Some(s) => resolveSets(xs, rem, s :: acc) @@ -167,33 +171,56 @@ trait PartestRunner { val keys = setOptions(args.toList, Nil) - if (keys.length == 0) task {runPartest(testSuiteFiles, None, failedOnly) orElse runPartest(testSuiteContinuation, None, failedOnly)} // this is the case where there were only config options, we will run the standard test suite + if (keys.length == 0) task { + runPartest(testSuiteFiles, None, failedOnly) orElse { + runPartest(testSuiteContinuation, None, failedOnly) + } // this is the case where there were only config options, we will run the standard test suite + } else { - val (fileNames, sets) = resolveSets(keys, Nil, Nil) - val (notFound, allSets)= resolveFiles(fileNames, sets) - if (!notFound.isEmpty) log.info("Don't know what to do with : \n"+notFound.mkString("\n")) - - val (std, continuations) = allSets.partition(_.SType == TestSetType.Std) - task {runPartest(std, None, failedOnly) orElse runPartest(continuations, Some(continuationScalaOpts), failedOnly)} - } - + val (fileNames, sets) = resolveSets(keys, Nil, Nil) + val (notFound, allSets) = resolveFiles(fileNames, sets) + if (!notFound.isEmpty) + log.info("Don't know what to do with : \n"+notFound.mkString("\n")) + + val (std, continuations) = allSets partition (_.SType == TestSetType.Std) + task { + runPartest(std, None, failedOnly) orElse { + runPartest(continuations, Some(continuationScalaOpts), failedOnly) + } + } + } }.completeWith(partestCompletionList) } object Partest { - def runTest(parentLoader:ClassLoader, config:TestConfiguration,javacmd:Option[File],javaccmd:Option[File],scalacOpts:Option[String],timeout:Option[String], - showDiff:Boolean,showLog:Boolean,runFailed:Boolean,errorOnFailed:Boolean,debug:Boolean,log:Logger):Option[String] = { + def runTest( + parentLoader: ClassLoader, + config: TestConfiguration, + javacmd: Option[File], + javaccmd: Option[File], + scalacOpts: Option[String], + timeout: Option[String], + showDiff: Boolean, + showLog: Boolean, + runFailed: Boolean, + errorOnFailed: Boolean, + debug: Boolean, + log: Logger + ): Option[String] = { if (debug) - System.setProperty("partest.debug", "true") + log.setLevel(Level.Debug) if (config.classpath.isEmpty) return Some("The classpath is empty") log.debug("Classpath is "+ config.classpath) - val classloader = new URLClassLoader(Array(config.classpath.toSeq.map(_.asURL):_*),ClassLoader.getSystemClassLoader.getParent) + val classloader = new URLClassLoader( + Array(config.classpath.toSeq.map(_.asURL):_*), + ClassLoader.getSystemClassLoader.getParent + ) val runner: AnyRef = classloader.loadClass("scala.tools.partest.nest.SBTRunner").newInstance().asInstanceOf[AnyRef] val fileManager: AnyRef = diff --git a/project/build/ScalaBuildProject.scala b/project/build/ScalaBuildProject.scala index 4e388c9102..a94206006e 100644 --- a/project/build/ScalaBuildProject.scala +++ b/project/build/ScalaBuildProject.scala @@ -16,8 +16,6 @@ abstract class ScalaBuildProject extends Project { lazy val fjbgJar = lib / fjbgJarName lazy val msilJar = lib / msilJarName - - } object ScalaBuildProject { diff --git a/project/build/ScalaSBTBuilder.scala b/project/build/ScalaSBTBuilder.scala index 8f017c3b38..00e56515e7 100644 --- a/project/build/ScalaSBTBuilder.scala +++ b/project/build/ScalaSBTBuilder.scala @@ -6,7 +6,12 @@ import ScalaSBTBuilder._ * This class is the entry point for building scala with SBT. * @author Grégory Moix */ -class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectiveProject { +class ScalaSBTBuilder(val info: ProjectInfo) + extends Project + with ReflectiveProject + with BasicDependencyProject + // with IdeaProject + with MavenStyleScalaPaths { /** This secret system property turns off transitive dependencies during change * detection. It's a short term measure. BE AWARE! That means you can no longer * trust sbt to recompile everything: it's only recompiling changed files. @@ -15,17 +20,28 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectiveProj */ System.setProperty("sbt.intransitive", "true") - override def dependencies: Iterable[Project] = info.dependencies ++ locker.dependencies ++ quick.dependencies ++ strap.dependencies ++ libs.dependencies + // Required by BasicDependencyProject + def fullUnmanagedClasspath(config: Configuration) = unmanagedClasspath + + override def dependencies: Iterable[Project] = ( + info.dependencies ++ + locker.dependencies ++ + quick.dependencies ++ + strap.dependencies ++ + libs.dependencies + ) override def shouldCheckOutputDirectories = false - override def watchPaths = info.projectPath / "src" ** ("*.scala" || "*.java"||AdditionalResources.basicFilter) // Support of triggered execution at top level + // Support of triggered execution at top level + override def watchPaths = info.projectPath / "src" ** ("*.scala" || "*.java" || AdditionalResources.basicFilter) + // Top Level Tasks - lazy val build = task {None}.dependsOn(quick.binPack, quick.binQuick).describedAs(buildTaskDescription) lazy val buildFjbg = libs.buildFjbg.describedAs(buildFjbgTaskDescription) lazy val buildForkjoin = libs.buildForkjoin.describedAs(buildForkjoinTaskDescription) lazy val buildMsil = libs.buildMsil.describedAs(buildMislTaskDescription) lazy val clean = quick.clean.dependsOn(libs.clean).describedAs(cleanTaskDescription) lazy val cleanAll = locker.clean.dependsOn(libs.clean).describedAs(cleanAllTaskDescription) + lazy val compile = task {None}.dependsOn(quick.binPack, quick.binQuick).describedAs(buildTaskDescription) lazy val docs = quick.scaladoc.describedAs(docsTaskDescription) lazy val newFjbg = libs.newFjbg.describedAs(newFjbgTaskDescription) lazy val newForkjoin = libs.newForkjoin.describedAs(newForkjoinTaskDescription) @@ -33,9 +49,13 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectiveProj lazy val newMsil = libs.newMsil.describedAs(newMsilTaskDescription) lazy val newStarr = quick.newStarr.describedAs(newStarrTaskDescription) lazy val palo = locker.pack.describedAs(paloTaskDescription) - lazy val partest = quick.externalPartest.describedAs(partestTaskDescription) lazy val pasta = quick.pasta.describedAs(pastaTaskDescription) lazy val stabilityTest = strap.stabilityTest.describedAs(stabilityTestTaskDescription) + lazy val test = quick.externalPartest.describedAs(partestTaskDescription) + + // Non-standard names for tasks chosen earlier which I point at the standard ones. + lazy val build = compile + lazy val partest = test // Top level variables @@ -57,8 +77,6 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectiveProj getVersion+".r"+getRevision+"-b"+getTimeString } - - /* LAYER DEFINITIONS * We define here what's specific to each layer are they differ. * The common behavior is defined in the BasicLayer class @@ -187,12 +205,9 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectiveProj lazy val compileLibraryOnly = task { compile(libraryConfig, cleanCompilation _) } - lazy val externalCompileLibraryOnly = task { - val runner = new ExternalTaskRunner(projectRoot, this.name, compileLibraryOnly.name, "Error during external compilation", log) - runner.runTask - }.dependsOn(startLayer) + lazy val externalCompileLibraryOnly = task(maybeFork(compileLibraryOnly)) dependsOn startLayer - def createNewStarrJar: Option[String] = { + def createNewStarrJar: Option[String] ={ import Packer._ createJar(libraryWS.starrPackagingConfig, log) orElse createJar(compilerConfig.starrPackagingConfig, log) @@ -247,11 +262,8 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectiveProj log.warn("Stability test must be run on a clean build in order to yield correct results.") compare }.dependsOn(finishLayer) - } - - /** * An additional subproject used to build new version of forkjoin, fjbg and msil */ @@ -313,7 +325,7 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectiveProj lazy val msilConfig = new CompilationStep("msil", pathLayout, log) with Packaging { def label = "new msil library" - override def sources: PathFinder = sourceRoots.descendentsExcept("*.java"|"*.scala", ".svn"|"tests") + override def sources: PathFinder = sourceRoots.descendentsExcept("*.java" |"*.scala", ".svn" |"tests") def dependencies = Seq() override def classpath = super.classpath +++ quick.libraryOutput def options = Seq() diff --git a/project/build/Scaladoc.scala b/project/build/Scaladoc.scala index 7f2580f5b2..eae006c45f 100644 --- a/project/build/Scaladoc.scala +++ b/project/build/Scaladoc.scala @@ -34,10 +34,7 @@ trait Scaladoc { (antJar +++ jlineJar +++ msilJar +++ fjbgJar +++ forkJoinJar +++ outputLibraryJar +++ outputCompilerJar +++ outputPartestJar +++ outputScalapJar ).get } - lazy val scaladoc = task { - val externalSbt = new ExternalTaskRunner(projectRoot, this.name, generateScaladoc.name, "Error generating the scaladoc", log) - externalSbt.runTask - }.dependsOn(pack) + lazy val scaladoc = task(maybeFork(generateScaladoc, "Error generating scaladoc")) dependsOn pack lazy val generateScaladoc = task { instanceScope[Option[String]]{ scala => diff --git a/project/plugins/Plugins.scala b/project/plugins/Plugins.scala new file mode 100644 index 0000000000..15ee162329 --- /dev/null +++ b/project/plugins/Plugins.scala @@ -0,0 +1,6 @@ +import sbt._ + +class Plugins(info: ProjectInfo) extends PluginDefinition(info) { + val sbtIdeaRepo = "sbt-idea-repo" at "http://mpeltonen.github.com/maven/" + val sbtIdea = "com.github.mpeltonen" % "sbt-idea-plugin" % "0.2.0" +} \ No newline at end of file -- cgit v1.2.3