diff --git a/src/Github/CreateReleaseTextViaKeepAChangelog.php b/src/Github/CreateReleaseTextViaKeepAChangelog.php index d3da1141..38f9f47e 100644 --- a/src/Github/CreateReleaseTextViaKeepAChangelog.php +++ b/src/Github/CreateReleaseTextViaKeepAChangelog.php @@ -18,6 +18,7 @@ use Symfony\Component\Process\Process; use Webmozart\Assert\Assert; +use function array_reduce; use function count; use function explode; use function implode; @@ -25,33 +26,17 @@ use function preg_quote; use function preg_replace; use function sprintf; -use function str_replace; class CreateReleaseTextViaKeepAChangelog implements CreateReleaseText { - private const DEFAULT_CONTENTS = <<< 'CONTENTS' - ### Added - - - Nothing. - - ### Changed - - - Nothing. - - ### Deprecated - - - Nothing. - - ### Removed - - - Nothing. - - ### Fixed - - - Nothing. - - CONTENTS; - + /** @psalm-var list */ + private const DEFAULT_SECTIONS = [ + 'Added', + 'Changed', + 'Deprecated', + 'Removed', + 'Fixed', + ]; private ChangelogExists $changelogExists; private Clock $clock; @@ -152,7 +137,15 @@ private function updateReleaseDate(string $changelog, string $version): string */ private function removeDefaultContents(string $changelog): string { - $contents = str_replace(self::DEFAULT_CONTENTS, '', $changelog); + $contents = array_reduce( + self::DEFAULT_SECTIONS, + static fn (string $changelog, string $section): string => preg_replace( + "/\n\#{3} " . $section . "\n\n- Nothing.\n/s", + '', + $changelog + ), + $changelog + ); Assert::notEmpty($contents); return $contents; diff --git a/test/unit/Github/CreateReleaseTextViaKeepAChangelogTest.php b/test/unit/Github/CreateReleaseTextViaKeepAChangelogTest.php index af139e70..a9ad0c3d 100644 --- a/test/unit/Github/CreateReleaseTextViaKeepAChangelogTest.php +++ b/test/unit/Github/CreateReleaseTextViaKeepAChangelogTest.php @@ -109,22 +109,43 @@ public function testExtractsReleaseTextViaChangelogFile(): void ### Added - Everything. + END, $date); + + self::assertStringContainsString( + $expected, + (new CreateReleaseTextViaKeepAChangelog(new ChangelogExistsViaConsole(), $this->clock)) + ->__invoke( + $this->createMockMilestone(), + RepositoryName::fromFullName('example/repo'), + SemVerVersion::fromMilestoneName('1.0.0'), + BranchName::fromName('1.0.x'), + $workingPath + ) + ->contents() + ); + } + + public function testExtractsNonEmptySectionsForVersionViaChangelogFile(): void + { + $date = $this->clock->now()->format('Y-m-d'); + $changelogContents = sprintf(self::CHANGELOG_MULTI_SECTION, $date); + $repositoryPath = $this->createMockRepositoryWithChangelog( + $changelogContents, + 'CHANGELOG.md', + '2.3.x' + ); + $workingPath = $this->checkoutMockRepositoryWithChangelog($repositoryPath); + + $expected = sprintf(<<< 'END' + ## 2.3.12 - %s - ### Changed - - - Nothing. - - ### Deprecated - - - Nothing. - - ### Removed - - - Nothing. + ### Added + - Something. + ### Fixed - - - Nothing. + + - Several things END, $date); self::assertStringContainsString( @@ -133,8 +154,8 @@ public function testExtractsReleaseTextViaChangelogFile(): void ->__invoke( $this->createMockMilestone(), RepositoryName::fromFullName('example/repo'), - SemVerVersion::fromMilestoneName('1.0.0'), - BranchName::fromName('1.0.x'), + SemVerVersion::fromMilestoneName('2.3.12'), + BranchName::fromName('2.3.x'), $workingPath ) ->contents() @@ -163,7 +184,8 @@ private function createMockMilestone(): Milestone */ private function createMockRepositoryWithChangelog( string $template, - string $filename = 'CHANGELOG.md' + string $filename = 'CHANGELOG.md', + string $initialBranch = '1.0.x' ): string { $repo = tempnam(sys_get_temp_dir(), 'CreateReleaseTextViaKeepAChangelog'); Assert::notEmpty($repo); @@ -181,7 +203,7 @@ private function createMockRepositoryWithChangelog( (new Process(['git', 'config', 'user.email', 'me@example.com'], $repo))->mustRun(); (new Process(['git', 'config', 'user.name', 'Just Me'], $repo))->mustRun(); (new Process(['git', 'commit', '-m', 'Initial import'], $repo))->mustRun(); - (new Process(['git', 'switch', '-c', '1.0.x'], $repo))->mustRun(); + (new Process(['git', 'switch', '-c', $initialBranch], $repo))->mustRun(); return $repo; } @@ -261,5 +283,56 @@ private function checkoutMockRepositoryWithChangelog(string $origin): string - Nothing. + END; + + private const CHANGELOG_MULTI_SECTION = <<< 'END' + # Changelog + + All notable changes to this project will be documented in this file, in reverse chronological order by release. + + ## 2.3.12 - %s + + ### Added + + - Something. + + ### Changed + + - Nothing. + + ### Deprecated + + - Nothing. + + ### Removed + + - Nothing. + + ### Fixed + + - Several things + + ## 0.1.0 - 2019-01-01 + + ### Added + + - Everything. + + ### Changed + + - Nothing. + + ### Deprecated + + - Nothing. + + ### Removed + + - Nothing. + + ### Fixed + + - Nothing. + END; }