From defd1ee0d45e3d2b98bf8b2adda4c314464c09ed Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 20 Apr 2011 18:31:10 -0400 Subject: [PATCH] Cache doc task --- cache/CacheIO.scala | 2 +- cache/FileInfo.scala | 9 ++++-- cache/tracking/Tracked.scala | 4 +-- main/Defaults.scala | 5 ++-- main/actions/Console.scala | 19 ------------- main/actions/Doc.scala | 54 ++++++++++++++++++++++++++++++++++++ 6 files changed, 67 insertions(+), 26 deletions(-) create mode 100644 main/actions/Doc.scala diff --git a/cache/CacheIO.scala b/cache/CacheIO.scala index dad9bd467..ac698c24e 100644 --- a/cache/CacheIO.scala +++ b/cache/CacheIO.scala @@ -24,7 +24,7 @@ object CacheIO fromFile[T](file) getOrElse default def fromFile[T](file: File)(implicit format: Format[T], mf: Manifest[Format[T]]): Option[T] = try { Some( Operations.fromFile(file)(stampedFormat(format)) ) } - catch { case e: FileNotFoundException => None } + catch { case e: Exception => None } def toFile[T](format: Format[T])(value: T)(file: File)(implicit mf: Manifest[Format[T]]): Unit = toFile(value)(file)(format, mf) diff --git a/cache/FileInfo.scala b/cache/FileInfo.scala index ae626b827..e4706c1fa 100644 --- a/cache/FileInfo.scala +++ b/cache/FileInfo.scala @@ -46,7 +46,7 @@ object FileInfo implicit val format: Format[F] import Cache._ implicit def fileInfoEquiv: Equiv[F] = defaultEquiv - implicit def infoInputCache: InputCache[F] = basicInput + def infoInputCache: InputCache[F] = basicInput implicit def fileInputCache: InputCache[File] = wrapIn[File,F] } object full extends Style @@ -95,7 +95,7 @@ object FilesInfo val manifest: Manifest[Format[FilesInfo[F]]] def empty: FilesInfo[F] = new FilesInfo[F](Set.empty) import Cache._ - implicit def infosInputCache: InputCache[FilesInfo[F]] = basicInput + def infosInputCache: InputCache[FilesInfo[F]] = basicInput implicit def filesInputCache: InputCache[Set[File]] = wrapIn[Set[File],FilesInfo[F]] implicit def filesInfoEquiv: Equiv[FilesInfo[F]] = defaultEquiv } @@ -112,4 +112,9 @@ object FilesInfo lazy val hash: Style { type F = HashFileInfo } = new BasicStyle(FileInfo.hash) lazy val lastModified: Style { type F = ModifiedFileInfo } = new BasicStyle(FileInfo.lastModified) lazy val exists: Style { type F = PlainFileInfo } = new BasicStyle(FileInfo.exists) + + implicit def existsInputsCache: InputCache[FilesInfo[PlainFileInfo]] = exists.infosInputCache + implicit def hashInputsCache: InputCache[FilesInfo[HashFileInfo]] = hash.infosInputCache + implicit def modifiedInputsCache: InputCache[FilesInfo[ModifiedFileInfo]] = lastModified.infosInputCache + implicit def fullInputsCache: InputCache[FilesInfo[HashModifiedFileInfo]] = full.infosInputCache } \ No newline at end of file diff --git a/cache/tracking/Tracked.scala b/cache/tracking/Tracked.scala index 1add819f4..10b37101f 100644 --- a/cache/tracking/Tracked.scala +++ b/cache/tracking/Tracked.scala @@ -3,7 +3,7 @@ */ package sbt -import java.io.{File,IOException} +import java.io.File import CacheIO.{fromFile, toFile} import sbinary.{Format, JavaIO} import scala.reflect.Manifest @@ -120,7 +120,7 @@ class Changed[O](val cacheFile: File)(implicit equiv: Equiv[O], format: Format[O stream => equiv.equiv(value, format.reads(stream)) } } catch { - case _: IOException => false + case _: Exception => false } } object Difference diff --git a/main/Defaults.scala b/main/Defaults.scala index d3631c163..c790cd7fd 100644 --- a/main/Defaults.scala +++ b/main/Defaults.scala @@ -314,9 +314,10 @@ object Defaults } def docTask: Initialize[Task[File]] = - (compileInputs, streams, docDirectory, configuration, scaladocOptions) map { (in, s, target, config, options) => + (cacheDirectory, compileInputs, streams, docDirectory, configuration, scaladocOptions) map { (cache, in, s, target, config, options) => val d = new Scaladoc(in.config.maxErrors, in.compilers.scalac) - d(nameForSrc(config.name), in.config.sources, in.config.classpath, target, options)(s.log) + val cp = in.config.classpath.toList - in.config.classesDirectory + d.cached(cache / "doc", nameForSrc(config.name), in.config.sources, cp, target, options, s.log) target } diff --git a/main/actions/Console.scala b/main/actions/Console.scala index d4026558b..f4e03ce30 100644 --- a/main/actions/Console.scala +++ b/main/actions/Console.scala @@ -27,23 +27,4 @@ final class Console(compiler: AnalyzingCompiler) object Console { def apply(conf: Compiler.Inputs): Console = new Console( conf.compilers.scalac ) -} - -final class Scaladoc(maximumErrors: Int, compiler: AnalyzingCompiler) -{ - final def apply(label: String, sources: Seq[File], classpath: Seq[File], outputDirectory: File, options: Seq[String])(implicit log: Logger) - { - log.info(actionStartMessage(label)) - if(sources.isEmpty) - log.info(ActionNothingToDoMessage) - else - { - IO.createDirectory(outputDirectory) - compiler.doc(sources, classpath, outputDirectory, options, maximumErrors, log) - log.info(ActionSuccessfulMessage) - } - } - def actionStartMessage(label: String) = "Generating API documentation for " + label + " sources..." - val ActionNothingToDoMessage = "No sources specified." - val ActionSuccessfulMessage = "API documentation generation successful." } \ No newline at end of file diff --git a/main/actions/Doc.scala b/main/actions/Doc.scala new file mode 100644 index 000000000..cfd100125 --- /dev/null +++ b/main/actions/Doc.scala @@ -0,0 +1,54 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009, 2010, 2011 Mark Harrah + */ +package sbt + + import java.io.File + import compiler.AnalyzingCompiler + + import Predef.{conforms => _, _} + import Types.:+: + import Path._ + + import sbinary.DefaultProtocol.FileFormat + import Cache.{defaultEquiv, hConsCache, hNilCache, seqCache, seqFormat, streamFormat, StringFormat, UnitFormat, wrapIn} + import Tracked.{inputChanged, outputChanged} + import FilesInfo.{exists, hash, lastModified} + +final class Scaladoc(maximumErrors: Int, compiler: AnalyzingCompiler) +{ + final def apply(label: String, sources: Seq[File], classpath: Seq[File], outputDirectory: File, options: Seq[String], log: Logger) + { + log.info(actionStartMessage(label)) + if(sources.isEmpty) + log.info(ActionNothingToDoMessage) + else + { + IO.delete(outputDirectory) + IO.createDirectory(outputDirectory) + compiler.doc(sources, classpath, outputDirectory, options, maximumErrors, log) + log.info(ActionSuccessfulMessage) + } + } + def actionStartMessage(label: String) = "Generating API documentation for " + label + " sources..." + val ActionNothingToDoMessage = "No sources specified." + val ActionSuccessfulMessage = "API documentation generation successful." + + def cached(cache: File, label: String, sources: Seq[File], classpath: Seq[File], outputDirectory: File, options: Seq[String], log: Logger) + { + type Inputs = FilesInfo[HashFileInfo] :+: FilesInfo[ModifiedFileInfo] :+: String :+: File :+: Seq[String] :+: HNil + val inputs: Inputs = hash(sources.toSet) :+: lastModified(classpath.toSet) :+: classpath.absString :+: outputDirectory :+: options :+: HNil + implicit val stringEquiv: Equiv[String] = defaultEquiv + implicit val fileEquiv: Equiv[File] = defaultEquiv + val cachedDoc = inputChanged(cache / "inputs") { (inChanged, in: Inputs) => + outputChanged(cache / "output") { (outChanged, outputs: FilesInfo[PlainFileInfo]) => + if(inChanged || outChanged) + apply(label, sources, classpath, outputDirectory, options, log) + else + log.debug("Doc uptodate: " + outputDirectory.getAbsolutePath) + } + } + + cachedDoc(inputs)(() => exists(outputDirectory.***.get)) + } +}