Skip to content

Commit

Permalink
[#323] added Files.createTemp* Managed methods; added Files.deleteRec…
Browse files Browse the repository at this point in the history
…ursive method
  • Loading branch information
Vitalii Honta authored and vitaliihonta committed Mar 19, 2021
1 parent cdf45e1 commit 6ea8686
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
target
.sbtopts
project/.sbt
*.tmp
# if you are here to add your IDE's files please read this instead:
# https://stackoverflow.com/questions/7335420/global-git-ignore#22885996
34 changes: 32 additions & 2 deletions nio/src/main/scala/zio/nio/file/Files.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ import java.nio.file.{
}
import java.util.function.BiPredicate
import java.util.{ Iterator => JIterator }

import zio.blocking._
import zio.nio.core.file.Path
import zio.stream.ZStream
import zio.stream.{ ZSink, ZStream }
import zio.{ Chunk, UIO, ZIO, ZManaged }

import scala.jdk.CollectionConverters._
Expand Down Expand Up @@ -66,6 +65,14 @@ object Files {
effectBlocking(Path.fromJava(JFiles.createTempFile(dir.javaPath, prefix.orNull, suffix, fileAttributes.toSeq: _*)))
.refineToOrDie[IOException]

def createTempFileInManaged(
dir: Path,
suffix: String = ".tmp",
prefix: Option[String],
fileAttributes: Iterable[FileAttribute[_]]
): ZManaged[Blocking, IOException, Path] =
ZManaged.make(createTempFileIn(dir, suffix, prefix, fileAttributes))(release = deleteIfExists(_).ignore)

def createTempFile(
suffix: String = ".tmp",
prefix: Option[String],
Expand All @@ -74,6 +81,13 @@ object Files {
effectBlocking(Path.fromJava(JFiles.createTempFile(prefix.orNull, suffix, fileAttributes.toSeq: _*)))
.refineToOrDie[IOException]

def createTempFileManaged(
suffix: String = ".tmp",
prefix: Option[String],
fileAttributes: Iterable[FileAttribute[_]]
): ZManaged[Blocking, IOException, Path] =
ZManaged.make(createTempFile(suffix, prefix, fileAttributes))(release = deleteIfExists(_).ignore)

def createTempDirectory(
dir: Path,
prefix: Option[String],
Expand All @@ -82,13 +96,26 @@ object Files {
effectBlocking(Path.fromJava(JFiles.createTempDirectory(dir.javaPath, prefix.orNull, fileAttributes.toSeq: _*)))
.refineToOrDie[IOException]

def createTempDirectoryManaged(
dir: Path,
prefix: Option[String],
fileAttributes: Iterable[FileAttribute[_]]
): ZManaged[Blocking, IOException, Path] =
ZManaged.make(createTempDirectory(dir, prefix, fileAttributes))(release = deleteRecursive(_).ignore)

def createTempDirectory(
prefix: Option[String],
fileAttributes: Iterable[FileAttribute[_]]
): ZIO[Blocking, IOException, Path] =
effectBlocking(Path.fromJava(JFiles.createTempDirectory(prefix.orNull, fileAttributes.toSeq: _*)))
.refineToOrDie[IOException]

def createTempDirectoryManaged(
prefix: Option[String],
fileAttributes: Iterable[FileAttribute[_]]
): ZManaged[Blocking, IOException, Path] =
ZManaged.make(createTempDirectory(prefix, fileAttributes))(release = deleteRecursive(_).ignore)

def createSymbolicLink(
link: Path,
target: Path,
Expand All @@ -106,6 +133,9 @@ object Files {
def deleteIfExists(path: Path): ZIO[Blocking, IOException, Boolean] =
effectBlocking(JFiles.deleteIfExists(path.javaPath)).refineToOrDie[IOException]

def deleteRecursive(path: Path): ZIO[Blocking, IOException, Long] =
newDirectoryStream(path).mapM(delete).run(ZSink.count) <* delete(path)

def copy(source: Path, target: Path, copyOptions: CopyOption*): ZIO[Blocking, IOException, Unit] =
effectBlocking(JFiles.copy(source.javaPath, target.javaPath, copyOptions: _*)).unit
.refineToOrDie[IOException]
Expand Down
92 changes: 92 additions & 0 deletions nio/src/test/scala/zio/nio/file/FilesSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package zio.nio.file

import zio.{ Chunk, Ref }
import zio.nio.BaseSpec
import zio.nio.core.file.Path
import zio.test._
import zio.test.Assertion._

object FilesSpec extends BaseSpec {

override def spec =
suite("FilesSpec")(
testM("createTempFileInManaged cleans up temp file") {
val sampleFileContent = Chunk.fromArray("createTempFileInManaged works!".getBytes)
for {
pathRef <- Ref.make[Option[Path]](None)
readBytes <- Files
.createTempFileInManaged(
dir = Path("."),
prefix = None,
fileAttributes = Nil
)
.use { tmpFile =>
pathRef.set(Some(tmpFile)) *> writeAndThenRead(tmpFile)(sampleFileContent)
}
Some(tmpFilePath) <- pathRef.get
tmpFileExistsAfterUsage <- Files.exists(tmpFilePath)
} yield assert(readBytes)(equalTo(sampleFileContent)) &&
assert(tmpFileExistsAfterUsage)(isFalse)
},
testM("createTempFileManaged cleans up temp file") {
val sampleFileContent = Chunk.fromArray("createTempFileManaged works!".getBytes)
for {
pathRef <- Ref.make[Option[Path]](None)
readBytes <- Files
.createTempFileManaged(
prefix = None,
fileAttributes = Nil
)
.use { tmpFile =>
pathRef.set(Some(tmpFile)) *> writeAndThenRead(tmpFile)(sampleFileContent)
}
Some(tmpFilePath) <- pathRef.get
tmpFileExistsAfterUsage <- Files.exists(tmpFilePath)
} yield assert(readBytes)(equalTo(sampleFileContent)) &&
assert(tmpFileExistsAfterUsage)(isFalse)
},
testM("createTempDirectoryManaged cleans up temp dir") {
val sampleFileContent = Chunk.fromArray("createTempDirectoryManaged works!".getBytes)
for {
pathRef <- Ref.make[Option[Path]](None)
readBytes <- Files
.createTempDirectoryManaged(
prefix = None,
fileAttributes = Nil
)
.use { tmpDir =>
val sampleFile = tmpDir / "createTempDirectoryManaged"
pathRef.set(Some(tmpDir)) *> createAndWriteAndThenRead(sampleFile)(sampleFileContent)
}
Some(tmpFilePath) <- pathRef.get
tmpFileExistsAfterUsage <- Files.exists(tmpFilePath)
} yield assert(readBytes)(equalTo(sampleFileContent)) &&
assert(tmpFileExistsAfterUsage)(isFalse)
},
testM("createTempDirectoryManaged (dir) cleans up temp dir") {
val sampleFileContent = Chunk.fromArray("createTempDirectoryManaged(dir) works!".getBytes)
for {
pathRef <- Ref.make[Option[Path]](None)
readBytes <- Files
.createTempDirectoryManaged(
dir = Path("."),
prefix = None,
fileAttributes = Nil
)
.use { tmpDir =>
val sampleFile = tmpDir / "createTempDirectoryManaged2"
pathRef.set(Some(tmpDir)) *> createAndWriteAndThenRead(sampleFile)(sampleFileContent)
}
Some(tmpFilePath) <- pathRef.get
tmpFileExistsAfterUsage <- Files.exists(tmpFilePath)
} yield assert(readBytes)(equalTo(sampleFileContent)) &&
assert(tmpFileExistsAfterUsage)(isFalse)
}
)

private def createAndWriteAndThenRead(file: Path)(bytes: Chunk[Byte]) =
Files.createFile(file) *> writeAndThenRead(file)(bytes)

private def writeAndThenRead(file: Path)(bytes: Chunk[Byte]) =
Files.writeBytes(file, bytes) *> Files.readAllBytes(file)
}

0 comments on commit 6ea8686

Please sign in to comment.