From ea1712d3bc0af1b82736df2a2b903282e9c70986 Mon Sep 17 00:00:00 2001 From: Ankit Kumar Date: Fri, 13 Mar 2026 18:59:32 +0000 Subject: [PATCH 1/5] Wrote 2 test cases, modified writeAll function to stop inwanted file creation --- .../src/main/scala/fs2/io/file/Files.scala | 20 +++++++--- .../test/scala/fs2/io/file/FilesSuite.scala | 37 ++++++++++++++++--- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/io/shared/src/main/scala/fs2/io/file/Files.scala b/io/shared/src/main/scala/fs2/io/file/Files.scala index cdec19e291..9fd59db29b 100644 --- a/io/shared/src/main/scala/fs2/io/file/Files.scala +++ b/io/shared/src/main/scala/fs2/io/file/Files.scala @@ -530,13 +530,21 @@ object Files extends FilesCompanionPlatform with FilesLowPriority { }) def writeAll( - path: Path, - flags: Flags - ): Pipe[F, Byte, Nothing] = + path: Path, + 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, diff --git a/io/shared/src/test/scala/fs2/io/file/FilesSuite.scala b/io/shared/src/test/scala/fs2/io/file/FilesSuite.scala index ed7e1503f3..5d702d09d5 100644 --- a/io/shared/src/test/scala/fs2/io/file/FilesSuite.scala +++ b/io/shared/src/test/scala/fs2/io/file/FilesSuite.scala @@ -113,8 +113,8 @@ class FilesSuite extends Fs2Suite with BaseFileSuite { val src = Stream("Hello", " world!").covary[IO].through(text.utf8.encode) src.through(Files[IO].writeAll(path)) ++ src.through(Files[IO].writeAll(path, Flags.Append)) ++ Files[IO] - .readAll(path) - .through(text.utf8.decode) + .readAll(path) + .through(text.utf8.decode) } .compile .foldMonoid @@ -165,9 +165,10 @@ class FilesSuite extends Fs2Suite with BaseFileSuite { } .compile .foldMonoid - .assertEquals("""|foo - |bar - |""".stripMargin) + .assertEquals( + """|foo + |bar + |""".stripMargin) } test("writeUtf8Lines - side effect") { @@ -200,6 +201,32 @@ class FilesSuite extends Fs2Suite with BaseFileSuite { .foldMonoid .assertEquals("") } + test("empty stream does not create file") { + 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") { From d94cc8d801a7ddf3ae8eb5476ee3618a26f292ff Mon Sep 17 00:00:00 2001 From: Ankit Kumar Date: Fri, 13 Mar 2026 19:15:36 +0000 Subject: [PATCH 2/5] Applied ScalafmtAll --- io/shared/src/main/scala/fs2/io/file/Files.scala | 8 ++++---- io/shared/src/test/scala/fs2/io/file/FilesSuite.scala | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/io/shared/src/main/scala/fs2/io/file/Files.scala b/io/shared/src/main/scala/fs2/io/file/Files.scala index 9fd59db29b..093ed6003a 100644 --- a/io/shared/src/main/scala/fs2/io/file/Files.scala +++ b/io/shared/src/main/scala/fs2/io/file/Files.scala @@ -530,12 +530,12 @@ object Files extends FilesCompanionPlatform with FilesLowPriority { }) def writeAll( - path: Path, - flags: Flags - ): Pipe[F, Byte, Nothing] = + path: Path, + flags: Flags + ): Pipe[F, Byte, Nothing] = in => in.pull.stepLeg.flatMap { - case None => Pull.done + case None => Pull.done case Some(leg) => Stream .resource(writeCursor(path, flags)) diff --git a/io/shared/src/test/scala/fs2/io/file/FilesSuite.scala b/io/shared/src/test/scala/fs2/io/file/FilesSuite.scala index 5d702d09d5..a0a4821d42 100644 --- a/io/shared/src/test/scala/fs2/io/file/FilesSuite.scala +++ b/io/shared/src/test/scala/fs2/io/file/FilesSuite.scala @@ -113,8 +113,8 @@ class FilesSuite extends Fs2Suite with BaseFileSuite { val src = Stream("Hello", " world!").covary[IO].through(text.utf8.encode) src.through(Files[IO].writeAll(path)) ++ src.through(Files[IO].writeAll(path, Flags.Append)) ++ Files[IO] - .readAll(path) - .through(text.utf8.decode) + .readAll(path) + .through(text.utf8.decode) } .compile .foldMonoid @@ -165,8 +165,7 @@ class FilesSuite extends Fs2Suite with BaseFileSuite { } .compile .foldMonoid - .assertEquals( - """|foo + .assertEquals("""|foo |bar |""".stripMargin) } From 3a20392199419354d7e093498108290a4130b43a Mon Sep 17 00:00:00 2001 From: Ankit Kumar Date: Tue, 17 Mar 2026 20:40:34 +0000 Subject: [PATCH 3/5] Applied ScalafmtAll --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index e52fb3ce0f..aec1ff0c38 100644 --- a/build.sbt +++ b/build.sbt @@ -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" From 4af9af147e9568d951e97b0e885883d99a47fec5 Mon Sep 17 00:00:00 2001 From: Ankit Kumar Date: Tue, 17 Mar 2026 20:58:37 +0000 Subject: [PATCH 4/5] WriteAll() for JS Platform --- build.sbt | 2 +- .../scala/fs2/io/file/FilesPlatform.scala | 66 +++++++++++-------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/build.sbt b/build.sbt index aec1ff0c38..e52fb3ce0f 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,7 @@ import com.typesafe.tools.mima.core._ Global / onChangedBuildSource := ReloadOnSourceChanges -ThisBuild / tlBaseVersion := "3.13" +ThisBuild / tlBaseVersion := "3.12" ThisBuild / organization := "co.fs2" ThisBuild / organizationName := "Functional Streams for Scala" diff --git a/io/js/src/main/scala/fs2/io/file/FilesPlatform.scala b/io/js/src/main/scala/fs2/io/file/FilesPlatform.scala index 6fee6275c1..b635964a0b 100644 --- a/io/js/src/main/scala/fs2/io/file/FilesPlatform.scala +++ b/io/js/src/main/scala/fs2/io/file/FilesPlatform.scala @@ -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))) + } + ) + () + }) + .flatMap { ws => + leg.stream + .cons(leg.head) + .through(writeWritable(F.pure(ws))) } - ) - () - } - ) - } + .pull + .echo + } + .stream + } } From f5ebc092b9a4186d311db3054079336b81167a67 Mon Sep 17 00:00:00 2001 From: Ankit Kumar Date: Tue, 17 Mar 2026 21:05:03 +0000 Subject: [PATCH 5/5] Apllied ScalafmtAll --- build.sbt | 2 +- .../scala/fs2/io/file/FilesPlatform.scala | 70 +++++++++---------- 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/build.sbt b/build.sbt index e52fb3ce0f..aec1ff0c38 100644 --- a/build.sbt +++ b/build.sbt @@ -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" diff --git a/io/js/src/main/scala/fs2/io/file/FilesPlatform.scala b/io/js/src/main/scala/fs2/io/file/FilesPlatform.scala index b635964a0b..5a9f238457 100644 --- a/io/js/src/main/scala/fs2/io/file/FilesPlatform.scala +++ b/io/js/src/main/scala/fs2/io/file/FilesPlatform.scala @@ -418,44 +418,42 @@ private[fs2] trait FilesCompanionPlatform { } override def writeAll(path: Path, _flags: Flags): Pipe[F, Byte, Nothing] = in => - 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)) + 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[js.Error]( - "error", - error => { - ws.removeAllListeners() - cb(Left(js.JavaScriptException(error))) - } - ) - () - }) - .flatMap { ws => - leg.stream - .cons(leg.head) - .through(writeWritable(F.pure(ws))) - } - .pull - .echo - } - .stream + ws.once[Unit]( + "ready", + _ => { + ws.removeAllListeners() + cb(Right(ws)) + } + ) + ws.once[js.Error]( + "error", + error => { + ws.removeAllListeners() + cb(Left(js.JavaScriptException(error))) + } + ) + () + }) + .flatMap { ws => + leg.stream + .cons(leg.head) + .through(writeWritable(F.pure(ws))) + } + .pull + .echo + }.stream } }