Skip to content

Commit

Permalink
Merge pull request #38 from muuki88/add-mapping-helpers
Browse files Browse the repository at this point in the history
Add helper methods to create mappings
  • Loading branch information
dwijnand authored Mar 28, 2017
2 parents c130679 + 2b184f0 commit 47725b5
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 4 deletions.
1 change: 1 addition & 0 deletions io/src/main/scala/sbt/io/Path.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ object Path extends Mapper {
val sep: Char = java.io.File.separatorChar

def toURLs(files: Seq[File]): Array[URL] = files.map(_.toURI.toURL).toArray

}

object PathFinder {
Expand Down
55 changes: 55 additions & 0 deletions io/src/main/scala/sbt/io/PathMapper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,61 @@ abstract class Mapper {
def selectSubpaths(base: File, filter: FileFilter): Traversable[(File, String)] =
(PathFinder(base) ** filter --- PathFinder(base)) pair (relativeTo(base) | flat)

/**
* return a Seq of mappings which effect is to add a whole directory in the generated package
*
* @example In order to create mappings for a static directory "extra" add
* {{{
* mappings ++= directory(baseDirectory.value / "extra")
* }}}
*
* The resulting mappings sequence will look something like this
*
* {{{
* File($baseDirectory/extras) -> "extras"
* File($baseDirectory/extras/file1) -> "extras/file1"
* File($baseDirectory/extras/file2) -> "extras/file2"
* ...
* }}}
*
*
* @param baseDirectory The directory that should be turned into a mappings sequence.
* @return mappings The `baseDirectory` and all of its contents
*/
def directory(baseDirectory: File): Seq[(File, String)] =
Option(baseDirectory.getParentFile)
.map(parent => PathFinder(baseDirectory).allPaths pair relativeTo(parent))
.getOrElse(PathFinder(baseDirectory).allPaths pair basic)

/**
* return a Seq of mappings excluding the directory itself.
*
* @example In order to create mappings for a static directory "extra" add
* {{{
* mappings ++= contentOf(baseDirectory.value / "extra")
* }}}
*
* The resulting mappings sequence will look something like this
*
* {{{
* File($baseDirectory/extras/file1) -> "file1"
* File($baseDirectory/extras/file2) -> "file2"
* ...
* }}}
*
* @example Add a static directory "extra" and re-map the destination to a different path
* {{{
* mappings ++= contentOf(baseDirectory.value / "extra").map {
* case (src, destination) => src -> s"new/path/$destination"
* }
* }}}
*
* @param baseDirectory The directory that should be turned into a mappings sequence.
* @return mappings - The `basicDirectory`'s contents exlcuding `basicDirectory` itself
*/
def contentOf(baseDirectory: File): Seq[(File, String)] =
(PathFinder(baseDirectory).allPaths --- PathFinder(baseDirectory)) pair relativeTo(baseDirectory)

private[this] def fold[A, B, T](zero: A => Option[B], in: Iterable[T])(f: T => A => Option[B]): A => Option[B] =
(zero /: in)((mapper, base) => f(base) | mapper)
}
113 changes: 109 additions & 4 deletions io/src/test/scala/sbt/io/PathMapperSpec.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package sbt.io

import java.nio.file.{ Files, Path => NioPath }

import org.scalatest._
import Path._
import sbt.io.syntax._

class PathMapperSpec extends fixture.FlatSpec with Matchers {

import Path._, sbt.io.syntax._
type FixtureParam = NioPath

class PathMapperSpec extends FlatSpec with Matchers {
"PathMapper" should "create copy resource mappings correctly" in {
val base = file("/")
"rebase | flat" should "copy resource mappings correctly" in { tempDirectory =>
val base = tempDirectory.toFile

val files = Seq(base / "src" / "main" / "resources" / "scalac-plugin.xml")
val dirs = Seq(
Expand All @@ -22,4 +27,104 @@ class PathMapperSpec extends FlatSpec with Matchers {
base / "target" / "scala-2.11" / "classes" / "scalac-plugin.xml"
)
}

"directory" should "create mappings including the baseDirectory" in { tempDirectory =>
val nestedFile1 = Files.createFile(tempDirectory resolve "file1").toFile
val nestedFile2 = Files.createFile(tempDirectory resolve "file2").toFile
val nestedDir = Files.createDirectory(tempDirectory resolve "dir1")
val nestedDirFile = Files.createDirectory(nestedDir resolve "dir1-file1").toFile

IO.touch(nestedFile1)
IO.touch(nestedFile2)
IO.createDirectory(nestedDir.toFile)
IO.touch(nestedDirFile)

val mappings = Path.directory(tempDirectory.toFile)

mappings should contain theSameElementsAs List[(File, String)](
tempDirectory.toFile -> s"${tempDirectory.getFileName}",
nestedFile1 -> s"${tempDirectory.getFileName}/file1",
nestedFile2 -> s"${tempDirectory.getFileName}/file2",
nestedDir.toFile -> s"${tempDirectory.getFileName}/dir1",
nestedDirFile -> s"${tempDirectory.getFileName}/dir1/dir1-file1"
)
}

it should "create one mapping entry for an empty directory" in { tempDirectory =>
val mappings = Path.directory(tempDirectory.toFile)

mappings should contain theSameElementsAs List[(File, String)](
tempDirectory.toFile -> s"${tempDirectory.getFileName}"
)
}

it should "create an empty mappings sequence for a non-existing directory" in { tempDirectory =>
val nonExistingDirectory = tempDirectory.resolve("imaginary")
val mappings = Path.directory(nonExistingDirectory.toFile)

mappings should be(empty)
}

it should "create one mapping entry if the directory is a file" in { tempDirectory =>
val file = tempDirectory.resolve("file").toFile
IO.touch(file)
val mappings = Path.directory(file)

mappings should contain theSameElementsAs List[(File, String)](
file -> s"${file.getName}"
)
}

"contentOf" should "create mappings excluding the baseDirectory" in { tempDirectory =>

val nestedFile1 = Files.createFile(tempDirectory resolve "file1").toFile
val nestedFile2 = Files.createFile(tempDirectory resolve "file2").toFile
val nestedDir = Files.createDirectory(tempDirectory resolve "dir1")
val nestedDirFile = Files.createDirectory(nestedDir resolve "dir1-file1").toFile

IO.touch(nestedFile1)
IO.touch(nestedFile2)
IO.createDirectory(nestedDir.toFile)
IO.touch(nestedDirFile)


val mappings = Path.contentOf(tempDirectory.toFile)

mappings should contain theSameElementsAs List[(File, String)](
nestedFile1 -> s"file1",
nestedFile2 -> s"file2",
nestedDir.toFile -> s"dir1",
nestedDirFile -> s"dir1/dir1-file1"
)
}

it should "create an empty mappings sequence for an empty directory" in { tempDirectory =>
val mappings = Path.contentOf(tempDirectory.toFile)

mappings should be(empty)
}

it should "create an empty mappings sequence for a non-existing directory" in { tempDirectory =>
val nonExistingDirectory = tempDirectory.resolve("imaginary")
val mappings = Path.contentOf(nonExistingDirectory.toFile)

mappings should be(empty)
}

it should "create an empty mappings sequence if the directory is a file" in { tempDirectory =>
val file = tempDirectory.resolve("file").toFile
val mappings = Path.contentOf(file)

mappings should be(empty)
}

override protected def withFixture(test: OneArgTest): Outcome = {
val tmpDir = Files.createTempDirectory("path-mappings")
try {
withFixture(test.toNoArgTest(tmpDir))
} finally {
// cleanup an delete the temp directory
IO.delete(tmpDir.toFile)
}
}
}

0 comments on commit 47725b5

Please sign in to comment.