Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
43 / 43
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
ChangelogShowCommand
100.00% covered (success)
100.00%
43 / 43
100.00% covered (success)
100.00%
3 / 3
5
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 configure
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5/**
6 * Fast Forward Development Tools for PHP projects.
7 *
8 * This file is part of fast-forward/dev-tools project.
9 *
10 * @author   Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
11 * @license  https://opensource.org/licenses/MIT MIT License
12 *
13 * @see      https://github.com/php-fast-forward/
14 * @see      https://github.com/php-fast-forward/dev-tools
15 * @see      https://github.com/php-fast-forward/dev-tools/issues
16 * @see      https://php-fast-forward.github.io/dev-tools/
17 * @see      https://datatracker.ietf.org/doc/html/rfc2119
18 */
19
20namespace FastForward\DevTools\Console\Command;
21
22use FastForward\DevTools\Console\Command\Traits\LogsCommandResults;
23use Throwable;
24use FastForward\DevTools\Changelog\Manager\ChangelogManagerInterface;
25use FastForward\DevTools\Console\Input\HasJsonOption;
26use FastForward\DevTools\Filesystem\FilesystemInterface;
27use Symfony\Component\Console\Attribute\AsCommand;
28use Symfony\Component\Console\Command\Command;
29use Symfony\Component\Console\Input\InputArgument;
30use Symfony\Component\Console\Input\InputInterface;
31use Symfony\Component\Console\Input\InputOption;
32use Symfony\Component\Console\Output\OutputInterface;
33
34/**
35 * Prints the rendered notes body for a released changelog version.
36 */
37#[AsCommand(name: 'changelog:show', description: 'Prints the notes body for a released changelog version.')]
38 class ChangelogShowCommand extends Command
39{
40    use HasJsonOption;
41    use LogsCommandResults;
42
43    /**
44     * @param FilesystemInterface $filesystem
45     * @param ChangelogManagerInterface $changelogManager
46     */
47    public function __construct(
48        private  FilesystemInterface $filesystem,
49        private  ChangelogManagerInterface $changelogManager,
50    ) {
51        parent::__construct();
52    }
53
54    /**
55     * Configures the show command arguments and options.
56     */
57    protected function configure(): void
58    {
59        $this->setHelp(
60            'This command renders the body of one released changelog section so it can be reused for GitHub'
61            . ' release notes.'
62        );
63
64        $this->addJsonOption()
65            ->addArgument(
66                name: 'version',
67                mode: InputArgument::REQUIRED,
68                description: 'The released version to render.',
69            )
70            ->addOption(
71                name: 'file',
72                mode: InputOption::VALUE_REQUIRED,
73                description: 'Path to the changelog file.',
74                default: 'CHANGELOG.md',
75            );
76    }
77
78    /**
79     * Prints the rendered release notes body.
80     *
81     * @param InputInterface $input
82     * @param OutputInterface $output
83     */
84    protected function execute(InputInterface $input, OutputInterface $output): int
85    {
86        try {
87            $version = (string) $input->getArgument('version');
88            $file = (string) $input->getOption('file');
89            $releaseNotes = $this->changelogManager->renderReleaseNotes(
90                $this->filesystem->getAbsolutePath($file),
91                $version,
92            );
93
94            // This command feeds redirected release-notes files in changelog.yml,
95            // so plain-text mode MUST keep writing the rendered body directly.
96            if (! $this->isJsonOutput($input)) {
97                $output->write($releaseNotes);
98
99                return self::SUCCESS;
100            }
101
102            return $this->success(
103                $releaseNotes,
104                $input,
105                [
106                    'version' => $version,
107                    'release_notes' => $releaseNotes,
108                ],
109            );
110        } catch (Throwable $throwable) {
111            return $this->failure(
112                'Unable to render changelog release notes.',
113                $input,
114                [
115                    'exception_message' => $throwable->getMessage(),
116                ],
117                (string) $input->getOption('file'),
118            );
119        }
120    }
121}