From 19badd96cff4517a22e1cbfdaa1abf2a40f00c5e Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Thu, 22 Oct 2026 17:13:37 +0200 Subject: [PATCH 1/2] #335 - LineReaderTask: stop the iteration when there is no more line to read instead of at the end of the file, so that the last line of a file that does not end with a line break is no longer lost. Add tests. Co-Authored-By: Claude Opus 5.5 (1M context) --- CHANGELOG.md | 3 +++ src/Task/File/LineReaderTask.php | 3 ++- tests/Task/File/LineReaderTaskTest.php | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b33c604..56f45db8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ Latest ------ +## Fixes +* [#335](https://github.com/cleverage/process-bundle/issues/335) `LineReaderTask` (`line_reader`) and `InputLineReaderTask` (`input_line_reader`): the last line of a file that does not end with a line break is no longer lost. Add tests. + v5.4.1 ----- diff --git a/src/Task/File/LineReaderTask.php b/src/Task/File/LineReaderTask.php index 69f1d4c3..9e2fc5de 100644 --- a/src/Task/File/LineReaderTask.php +++ b/src/Task/File/LineReaderTask.php @@ -61,7 +61,8 @@ public function next(ProcessState $state): bool throw new LogicException('No File initialized'); } - $endOfFile = $this->file->eof(); + // Not eof(): with READ_AHEAD, the end of the file is reached when the last line is read, before it is emitted + $endOfFile = !$this->file->valid(); if ($endOfFile) { // Release the file to allow the following iteration to read it again $this->file = null; diff --git a/tests/Task/File/LineReaderTaskTest.php b/tests/Task/File/LineReaderTaskTest.php index d84de8a0..8a53964d 100644 --- a/tests/Task/File/LineReaderTaskTest.php +++ b/tests/Task/File/LineReaderTaskTest.php @@ -42,6 +42,7 @@ protected function setUp(): void $filesystem = new Filesystem(); $filesystem->dumpFile($this->tmpDir.'/a.txt', "a1\na2\n"); $filesystem->dumpFile($this->tmpDir.'/b.txt', "b1\n"); + $filesystem->dumpFile($this->tmpDir.'/no_final_line_break.txt', "l1\n\nl3\r\nl4"); } protected function tearDown(): void @@ -60,6 +61,18 @@ public function testSameFileIsReadAgainOnSecondExecution(): void ); } + public function testTheLastLineIsReadWithoutFinalLineBreak(): void + { + self::assertSame( + ["l1\n", "\n", "l3\r\n", "l4"], + $this->iterate(new LineReaderTask(), $this->createState(['filename' => $this->tmpDir.'/no_final_line_break.txt'])), + ); + self::assertSame( + ["l1\n", "\n", "l3\r\n", "l4"], + $this->iterate(new InputLineReaderTask(), $this->createState([]), $this->tmpDir.'/no_final_line_break.txt'), + ); + } + public function testInputLineReaderReadsSameFileTwice(): void { $task = new InputLineReaderTask(); From bfb7bdd79818b3e24667928fe2eb7bc0bc3169bf Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Thu, 22 Oct 2026 17:16:02 +0200 Subject: [PATCH 2/2] #335 - Fix coding standards Co-Authored-By: Claude Opus 5.5 (1M context) --- tests/Task/File/LineReaderTaskTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Task/File/LineReaderTaskTest.php b/tests/Task/File/LineReaderTaskTest.php index 8a53964d..1da68ee0 100644 --- a/tests/Task/File/LineReaderTaskTest.php +++ b/tests/Task/File/LineReaderTaskTest.php @@ -64,11 +64,11 @@ public function testSameFileIsReadAgainOnSecondExecution(): void public function testTheLastLineIsReadWithoutFinalLineBreak(): void { self::assertSame( - ["l1\n", "\n", "l3\r\n", "l4"], + ["l1\n", "\n", "l3\r\n", 'l4'], $this->iterate(new LineReaderTask(), $this->createState(['filename' => $this->tmpDir.'/no_final_line_break.txt'])), ); self::assertSame( - ["l1\n", "\n", "l3\r\n", "l4"], + ["l1\n", "\n", "l3\r\n", 'l4'], $this->iterate(new InputLineReaderTask(), $this->createState([]), $this->tmpDir.'/no_final_line_break.txt'), ); }