Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import com.typesafe.tools.mima.core._

Global / onChangedBuildSource := ReloadOnSourceChanges

ThisBuild / tlBaseVersion := "3.12"
ThisBuild / tlBaseVersion := "3.13"

ThisBuild / organization := "co.fs2"
ThisBuild / organizationName := "Functional Streams for Scala"
Expand Down
7 changes: 7 additions & 0 deletions crash.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[info] welcome to sbt 1.12.5 (Ubuntu Java 21.0.10)
[info] loading settings for project fs2-build from plugins.sbt...
[info] loading project definition from /home/anni_rain1/fs2/project
[info] loading settings for project root from build.sbt...
[info] resolving key references (21787 settings) ...
[info] set scmInfo to https://github.com/typelevel/fs2
[info] set current project to root (in build file:/home/anni_rain1/fs2/)
2,077 changes: 2,077 additions & 0 deletions hs_err_pid17440.log

Large diffs are not rendered by default.

1,548 changes: 1,548 additions & 0 deletions hs_err_pid21212.log

Large diffs are not rendered by default.

66 changes: 38 additions & 28 deletions io/js/src/main/scala/fs2/io/file/FilesPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -416,36 +416,46 @@ private[fs2] trait FilesCompanionPlatform {
.chunkN(options.chunkSize)
.flatMap(Stream.chunk)
}

override def writeAll(path: Path, _flags: Flags): Pipe[F, Byte, Nothing] =
in =>
in.through {
writeWritable(
F.async_[Writable] { cb =>
val ws = facade.fs
.createWriteStream(
path.toString,
new facade.fs.WriteStreamOptions {
flags = combineFlags(_flags)
}
)
ws.once[Unit](
"ready",
_ => {
ws.removeAllListeners()
cb(Right(ws))
}
)
ws.once[js.Error](
"error",
error => {
ws.removeAllListeners()
cb(Left(js.JavaScriptException(error)))
}
in.pull.stepLeg.flatMap {
case None => Pull.done
case Some(leg) =>
Stream
.eval(
F.async_[Writable] { cb =>
val ws = facade.fs
.createWriteStream(
path.toString,
new facade.fs.WriteStreamOptions {
flags = combineFlags(_flags)
}
)
ws.once[Unit](
"ready",
_ => {
ws.removeAllListeners()
cb(Right(ws))
}
)
ws.once[js.Error](
"error",
error => {
ws.removeAllListeners()
cb(Left(js.JavaScriptException(error)))
}
)
()
}.adaptError { case IOException(ex) => ex }
)
()
}
)
}
.flatMap { ws =>
leg.stream
.cons(leg.head)
.through(writeWritable(F.pure(ws)))
}
.pull
.echo
}.stream

}
}
14 changes: 11 additions & 3 deletions io/shared/src/main/scala/fs2/io/file/Files.scala
Original file line number Diff line number Diff line change
Expand Up @@ -534,9 +534,17 @@ object Files extends FilesCompanionPlatform with FilesLowPriority {
flags: Flags
): Pipe[F, Byte, Nothing] =
in =>
Stream
.resource(writeCursor(path, flags))
.flatMap(_.writeAll(in).void.stream)
in.pull.stepLeg.flatMap {
case None => Pull.done
case Some(leg) =>
Stream
.resource(writeCursor(path, flags))
.flatMap { cursor =>
cursor.writeAll(leg.stream.cons(leg.head)).void.stream
}
.pull
.echo
}.stream

def writeCursor(
path: Path,
Expand Down
30 changes: 28 additions & 2 deletions io/shared/src/test/scala/fs2/io/file/FilesSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ class FilesSuite extends Fs2Suite with BaseFileSuite {
.compile
.foldMonoid
.assertEquals("""|foo
|bar
|""".stripMargin)
|bar
|""".stripMargin)
}

test("writeUtf8Lines - side effect") {
Expand Down Expand Up @@ -200,6 +200,32 @@ class FilesSuite extends Fs2Suite with BaseFileSuite {
.foldMonoid
.assertEquals("")
}
test("empty stream does not create file") {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing an empty stream to a file should create an empty file.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @mpilquist Should i remove this test ?

Files[IO].tempDirectory.use { dir =>
val path = dir / "should-not-exist.txt"
Stream.empty
.covary[IO]
.through(Files[IO].writeAll(path))
.compile
.drain
.flatMap(_ => Files[IO].exists(path))
.assertEquals(false)
}
}

test("error stream does not create file") {
Files[IO].tempDirectory.use { dir =>
val path = dir / "should-not-exist.txt"
Stream
.raiseError[IO](new RuntimeException("boom"))
.through(Files[IO].writeAll(path))
.compile
.drain
.attempt
.flatMap(_ => Files[IO].exists(path))
.assertEquals(false)
}
}
}

group("tail") {
Expand Down
Loading