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
#327)

* [#323] added Files.createTemp* Managed methods; added Files.deleteRecursive method

* [#323] added default arguments to createTempFileManaged

Co-authored-by: Vitalii Honta <[email protected]>
Co-authored-by: Lachlan O'Dea <[email protected]>
  • Loading branch information
3 people authored and svroonland committed Aug 8, 2021
1 parent 45331a2 commit fbbf5d9
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 7 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
44 changes: 37 additions & 7 deletions nio/src/main/scala/zio/nio/file/Files.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package zio.nio.file

import zio.blocking._
import zio.nio.charset.Charset
import zio.stream.{ ZSink, ZStream }
import zio.{ Chunk, ZIO, ZManaged }

import java.io.IOException
import java.nio.file.attribute._
import java.nio.file.{
CopyOption,
DirectoryStream,
Expand All @@ -11,14 +17,7 @@ import java.nio.file.{
Files => JFiles,
Path => JPath
}
import java.nio.file.attribute._
import java.util.function.BiPredicate

import zio.{ Chunk, ZIO, ZManaged }
import zio.blocking._
import zio.nio.charset.Charset
import zio.stream.ZStream

import scala.jdk.CollectionConverters._
import scala.reflect._

Expand Down Expand Up @@ -57,6 +56,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] = None,
fileAttributes: Iterable[FileAttribute[_]] = Nil
): ZManaged[Blocking, IOException, Path] =
ZManaged.make(createTempFileIn(dir, suffix, prefix, fileAttributes))(release = deleteIfExists(_).ignore)

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

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

def createTempDirectory(
dir: Path,
prefix: Option[String],
Expand All @@ -73,13 +87,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 @@ -97,6 +124,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
85 changes: 85 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,85 @@
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("."))
.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()
.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 fbbf5d9

Please sign in to comment.