Move implicit FileStamp JsonFormats into object

I realized it was probably not ideal to have these implicit JsonFormats
defined directly in the FileStamp object because they might
inadvertently be brought into scope with a wildcard import.
This commit is contained in:
Ethan Atkins 2019-07-20 17:41:17 -07:00
parent 2990e08c5d
commit fb15065438
5 changed files with 139 additions and 128 deletions

View File

@ -605,6 +605,7 @@ object Defaults extends BuildCommon {
s"inc_compile$extra.zip" s"inc_compile$extra.zip"
}, },
externalHooks := { externalHooks := {
import sbt.nio.FileStamp.Formats.seqPathFileStampJsonFormatter
val current = val current =
(unmanagedSources / inputFileStamps).value ++ (managedSources / outputFileStamps).value (unmanagedSources / inputFileStamps).value ++ (managedSources / outputFileStamps).value
val previous = (externalHooks / inputFileStamps).previous val previous = (externalHooks / inputFileStamps).previous

View File

@ -65,7 +65,8 @@ private[sbt] object FileStamp {
final case class LastModified private[sbt] (time: Long) extends FileStamp final case class LastModified private[sbt] (time: Long) extends FileStamp
final case class Error(exception: IOException) extends FileStamp final case class Error(exception: IOException) extends FileStamp
implicit val pathJsonFormatter: JsonFormat[Seq[Path]] = new JsonFormat[Seq[Path]] { object Formats {
implicit val seqPathJsonFormatter: JsonFormat[Seq[Path]] = new JsonFormat[Seq[Path]] {
override def write[J](obj: Seq[Path], builder: Builder[J]): Unit = { override def write[J](obj: Seq[Path], builder: Builder[J]): Unit = {
builder.beginArray() builder.beginArray()
obj.foreach { path => obj.foreach { path =>
@ -88,7 +89,7 @@ private[sbt] object FileStamp {
} }
} }
implicit val fileJsonFormatter: JsonFormat[Seq[File]] = new JsonFormat[Seq[File]] { implicit val seqFileJsonFormatter: JsonFormat[Seq[File]] = new JsonFormat[Seq[File]] {
override def write[J](obj: Seq[File], builder: Builder[J]): Unit = { override def write[J](obj: Seq[File], builder: Builder[J]): Unit = {
builder.beginArray() builder.beginArray()
obj.foreach { file => obj.foreach { file =>
@ -110,30 +111,32 @@ private[sbt] object FileStamp {
deserializationError("Expected JsArray but found None") deserializationError("Expected JsArray but found None")
} }
} }
implicit val fileJson: JsonFormat[File] = new JsonFormat[File] { implicit val fileJsonFormatter: JsonFormat[File] = new JsonFormat[File] {
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): File = override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): File =
fileJsonFormatter.read(jsOpt, unbuilder).head seqFileJsonFormatter.read(jsOpt, unbuilder).head
override def write[J](obj: File, builder: Builder[J]): Unit = override def write[J](obj: File, builder: Builder[J]): Unit =
fileJsonFormatter.write(obj :: Nil, builder) seqFileJsonFormatter.write(obj :: Nil, builder)
} }
implicit val pathJson: JsonFormat[Path] = new JsonFormat[Path] { implicit val pathJsonFormatter: JsonFormat[Path] = new JsonFormat[Path] {
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): Path = override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): Path =
pathJsonFormatter.read(jsOpt, unbuilder).head seqPathJsonFormatter.read(jsOpt, unbuilder).head
override def write[J](obj: Path, builder: Builder[J]): Unit = override def write[J](obj: Path, builder: Builder[J]): Unit =
pathJsonFormatter.write(obj :: Nil, builder) seqPathJsonFormatter.write(obj :: Nil, builder)
} }
implicit val fileStampJsonFormatter: JsonFormat[Seq[(Path, FileStamp)]] = implicit val seqPathFileStampJsonFormatter: JsonFormat[Seq[(Path, FileStamp)]] =
new JsonFormat[Seq[(Path, FileStamp)]] { new JsonFormat[Seq[(Path, FileStamp)]] {
override def write[J](obj: Seq[(Path, FileStamp)], builder: Builder[J]): Unit = { override def write[J](obj: Seq[(Path, FileStamp)], builder: Builder[J]): Unit = {
val (hashes, lastModifiedTimes) = obj.partition(_._2.isInstanceOf[Hash]) val (hashes, lastModifiedTimes) = obj.partition(_._2.isInstanceOf[Hash])
builder.beginObject() builder.beginObject()
builder.addField("hashes", hashes.asInstanceOf[Seq[(Path, Hash)]])(fileHashJsonFormatter) builder.addField("hashes", hashes.asInstanceOf[Seq[(Path, Hash)]])(
seqPathHashJsonFormatter
)
builder.addField( builder.addField(
"lastModifiedTimes", "lastModifiedTimes",
lastModifiedTimes.asInstanceOf[Seq[(Path, LastModified)]] lastModifiedTimes.asInstanceOf[Seq[(Path, LastModified)]]
)( )(seqPathLastModifiedJsonFormatter)
fileLastModifiedJsonFormatter
)
builder.endObject() builder.endObject()
} }
@ -141,16 +144,16 @@ private[sbt] object FileStamp {
jsOpt match { jsOpt match {
case Some(js) => case Some(js) =>
unbuilder.beginObject(js) unbuilder.beginObject(js)
val hashes = unbuilder.readField("hashes")(fileHashJsonFormatter) val hashes = unbuilder.readField("hashes")(seqPathHashJsonFormatter)
val lastModifieds = val lastModifieds =
unbuilder.readField("lastModifiedTimes")(fileLastModifiedJsonFormatter) unbuilder.readField("lastModifiedTimes")(seqPathLastModifiedJsonFormatter)
unbuilder.endObject() unbuilder.endObject()
hashes ++ lastModifieds hashes ++ lastModifieds
case None => case None =>
deserializationError("Expected JsObject but found None") deserializationError("Expected JsObject but found None")
} }
} }
val fileHashJsonFormatter: JsonFormat[Seq[(Path, Hash)]] = private[sbt] val seqPathHashJsonFormatter: JsonFormat[Seq[(Path, Hash)]] =
new JsonFormat[Seq[(Path, Hash)]] { new JsonFormat[Seq[(Path, Hash)]] {
override def write[J](obj: Seq[(Path, Hash)], builder: Builder[J]): Unit = { override def write[J](obj: Seq[(Path, Hash)], builder: Builder[J]): Unit = {
builder.beginArray() builder.beginArray()
@ -181,7 +184,7 @@ private[sbt] object FileStamp {
deserializationError("Expected JsArray but found None") deserializationError("Expected JsArray but found None")
} }
} }
val fileLastModifiedJsonFormatter: JsonFormat[Seq[(Path, LastModified)]] = private[sbt] val seqPathLastModifiedJsonFormatter: JsonFormat[Seq[(Path, LastModified)]] =
new JsonFormat[Seq[(Path, LastModified)]] { new JsonFormat[Seq[(Path, LastModified)]] {
override def write[J](obj: Seq[(Path, LastModified)], builder: Builder[J]): Unit = { override def write[J](obj: Seq[(Path, LastModified)], builder: Builder[J]): Unit = {
builder.beginArray() builder.beginArray()
@ -212,6 +215,7 @@ private[sbt] object FileStamp {
deserializationError("Expected JsArray but found None") deserializationError("Expected JsArray but found None")
} }
} }
}
private implicit class EitherOps(val e: Either[FileStamp, FileStamp]) extends AnyVal { private implicit class EitherOps(val e: Either[FileStamp, FileStamp]) extends AnyVal {
def value: Option[FileStamp] = if (e == null) None else Some(e.fold(identity, identity)) def value: Option[FileStamp] = if (e == null) None else Some(e.fold(identity, identity))

View File

@ -16,7 +16,7 @@ import sbt.internal.Clean.ToSeqPath
import sbt.internal.Continuous.FileStampRepository import sbt.internal.Continuous.FileStampRepository
import sbt.internal.util.{ AttributeKey, SourcePosition } import sbt.internal.util.{ AttributeKey, SourcePosition }
import sbt.internal.{ Clean, Continuous, DynamicInput, SettingsGraph } import sbt.internal.{ Clean, Continuous, DynamicInput, SettingsGraph }
import sbt.nio.FileStamp.{ fileStampJsonFormatter, pathJsonFormatter, _ } import sbt.nio.FileStamp.Formats._
import sbt.nio.FileStamper.{ Hash, LastModified } import sbt.nio.FileStamper.{ Hash, LastModified }
import sbt.nio.Keys._ import sbt.nio.Keys._
import sbt.nio.file.ChangedFiles import sbt.nio.file.ChangedFiles

View File

@ -11,7 +11,8 @@ import java.nio.file.{ Path, Paths }
import org.scalatest.FlatSpec import org.scalatest.FlatSpec
import sbt.nio.FileStamp import sbt.nio.FileStamp
import sbt.nio.FileStamp._ import sbt.nio.FileStamp.Formats
import sjsonnew.JsonFormat
import sjsonnew.support.scalajson.unsafe.Converter import sjsonnew.support.scalajson.unsafe.Converter
class FileStampJsonSpec extends FlatSpec { class FileStampJsonSpec extends FlatSpec {
@ -20,8 +21,10 @@ class FileStampJsonSpec extends FlatSpec {
Paths.get("foo") -> FileStamp.hash("bar"), Paths.get("foo") -> FileStamp.hash("bar"),
Paths.get("bar") -> FileStamp.hash("buzz") Paths.get("bar") -> FileStamp.hash("buzz")
) )
val json = Converter.toJsonUnsafe(hashes)(fileHashJsonFormatter) implicit val formatter: JsonFormat[Seq[(Path, FileStamp.Hash)]] =
val deserialized = Converter.fromJsonUnsafe(json)(fileHashJsonFormatter) Formats.seqPathHashJsonFormatter
val json = Converter.toJsonUnsafe(hashes)
val deserialized = Converter.fromJsonUnsafe(json)
assert(hashes == deserialized) assert(hashes == deserialized)
} }
"file last modified times" should "be serializable" in { "file last modified times" should "be serializable" in {
@ -29,8 +32,10 @@ class FileStampJsonSpec extends FlatSpec {
Paths.get("foo") -> FileStamp.LastModified(1234), Paths.get("foo") -> FileStamp.LastModified(1234),
Paths.get("bar") -> FileStamp.LastModified(5678) Paths.get("bar") -> FileStamp.LastModified(5678)
) )
val json = Converter.toJsonUnsafe(lastModifiedTimes)(fileLastModifiedJsonFormatter) implicit val formatter: JsonFormat[Seq[(Path, FileStamp.LastModified)]] =
val deserialized = Converter.fromJsonUnsafe(json)(fileLastModifiedJsonFormatter) Formats.seqPathLastModifiedJsonFormatter
val json = Converter.toJsonUnsafe(lastModifiedTimes)
val deserialized = Converter.fromJsonUnsafe(json)
assert(lastModifiedTimes == deserialized) assert(lastModifiedTimes == deserialized)
} }
"both" should "be serializable" in { "both" should "be serializable" in {
@ -43,8 +48,9 @@ class FileStampJsonSpec extends FlatSpec {
Paths.get("bar") -> FileStamp.LastModified(5678) Paths.get("bar") -> FileStamp.LastModified(5678)
) )
val both: Seq[(Path, FileStamp)] = hashes ++ lastModifiedTimes val both: Seq[(Path, FileStamp)] = hashes ++ lastModifiedTimes
val json = Converter.toJsonUnsafe(both)(fileStampJsonFormatter) import Formats.seqPathFileStampJsonFormatter
val deserialized = Converter.fromJsonUnsafe(json)(fileStampJsonFormatter) val json = Converter.toJsonUnsafe(both)
val deserialized = Converter.fromJsonUnsafe(json)
assert(both == deserialized) assert(both == deserialized)
} }
} }

View File

@ -34,11 +34,11 @@ package object sbt
implicit def filesToFinder(cc: Traversable[File]): sbt.io.PathFinder = implicit def filesToFinder(cc: Traversable[File]): sbt.io.PathFinder =
sbt.io.PathFinder.strict(cc) sbt.io.PathFinder.strict(cc)
implicit val fileStampJsonFormatter: JsonFormat[Seq[(NioPath, FileStamp)]] = implicit val fileStampJsonFormatter: JsonFormat[Seq[(NioPath, FileStamp)]] =
FileStamp.fileStampJsonFormatter FileStamp.Formats.seqPathFileStampJsonFormatter
implicit val pathJsonFormatter: JsonFormat[Seq[NioPath]] = FileStamp.pathJsonFormatter implicit val pathJsonFormatter: JsonFormat[Seq[NioPath]] = FileStamp.Formats.seqPathJsonFormatter
implicit val fileJsonFormatter: JsonFormat[Seq[File]] = FileStamp.fileJsonFormatter implicit val fileJsonFormatter: JsonFormat[Seq[File]] = FileStamp.Formats.seqFileJsonFormatter
implicit val singlePathJsonFormatter: JsonFormat[NioPath] = FileStamp.pathJson implicit val singlePathJsonFormatter: JsonFormat[NioPath] = FileStamp.Formats.pathJsonFormatter
implicit val singleFileJsonFormatter: JsonFormat[File] = FileStamp.fileJson implicit val singleFileJsonFormatter: JsonFormat[File] = FileStamp.Formats.fileJsonFormatter
// others // others
object CompileOrder { object CompileOrder {