diff --git a/CHANGELOG.md b/CHANGELOG.md index d591453..97fb79f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +# v1.1.1 +Fixes: +- Crontabs must end with an empty line [PR #2](https://github.com/mintware-de/native-cron/pull/2) + # v1.1.0 Features: - Added a DateTimeDefinition which represents the date / time part of cronjob lines. [PR #1](https://github.com/mintware-de/native-cron/pull/1) diff --git a/src/Content/Crontab.php b/src/Content/Crontab.php index c8be696..a4d4bcc 100644 --- a/src/Content/Crontab.php +++ b/src/Content/Crontab.php @@ -113,6 +113,11 @@ public function parse(string $content): void public function build(): string { - return implode("\n", array_map(fn (CrontabLineInterface $l) => $l->build(), $this->lines)); + $content = implode("\n", array_map(fn (CrontabLineInterface $l) => $l->build(), $this->lines)); + if (!str_ends_with($content, "\n")) { + $content .= "\n"; + } + + return $content; } } diff --git a/tests/Content/CrontabTest.php b/tests/Content/CrontabTest.php index e282fb7..6c60726 100644 --- a/tests/Content/CrontabTest.php +++ b/tests/Content/CrontabTest.php @@ -45,12 +45,13 @@ public function testParseAndBuild(): void # Edit this file to introduce tasks to be run by cron. */2 * * * * test argument + TEXT; $crontab = new Crontab(false); $crontab->parse($content); $lines = $crontab->getLines(); - self::assertCount(3, $lines); + self::assertCount(4, $lines); self::assertInstanceOf(CommentLine::class, $lines[0]); self::assertInstanceOf(BlankLine::class, $lines[1]); self::assertInstanceOf(CronJobLine::class, $lines[2]); @@ -78,6 +79,7 @@ public function testParseAndBuildWithLeading(): void # Edit this file to introduce tasks to be run by cron. */2 * * * * test argument + TEXT; self::assertEquals($expected, $crontab->build()); } @@ -88,12 +90,13 @@ public function testParseAndBuildSystemCrontab(): void # Edit this file to introduce tasks to be run by cron. */2 * * * * root test argument + TEXT; $crontab = new Crontab(); $crontab->parse($content); $lines = $crontab->getLines(); - self::assertCount(3, $lines); + self::assertCount(4, $lines); self::assertInstanceOf(CommentLine::class, $lines[0]); self::assertInstanceOf(BlankLine::class, $lines[1]); self::assertInstanceOf(CronJobLine::class, $lines[2]); @@ -124,6 +127,7 @@ public function testParseAndBuildRealExample(): void 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) # + TEXT; $crontab = new Crontab(); @@ -137,6 +141,7 @@ public function testAddLine(): void # Edit this file to introduce tasks to be run by cron. */2 * * * * test argument + TEXT; $crontab = new Crontab(false); @@ -153,6 +158,7 @@ public function testRemove(): void $content = <<build()); } + + public function testBuildShouldAppendABlankLine(): void + { + $crontab = new Crontab(); + self::assertEquals("\n", $crontab->build()); + } }