Completed
Push — add/changelog-tooling ( 86359e...64ad4d )
by
unknown
40:44 queued 31:04
created

VersionCommand::configure()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 0
dl 0
loc 24
rs 9.536
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
2
/**
3
 * "Version" command for the changelogger tool CLI.
4
 *
5
 * @package automattic/jetpack-changelogger
6
 */
7
8
// phpcs:disable WordPress.NamingConventions.ValidVariableName
9
10
namespace Automattic\Jetpack\Changelogger;
11
12
use Symfony\Component\Console\Command\Command;
13
use Symfony\Component\Console\Input\InputArgument;
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Input\InputOption;
16
use Symfony\Component\Console\Output\OutputInterface;
17
use function Wikimedia\quietCall;
18
19
/**
20
 * "Version" command for the changelogger tool CLI.
21
 */
22
class VersionCommand extends Command {
23
24
	/**
25
	 * The default command name
26
	 *
27
	 * @var string|null
28
	 */
29
	protected static $defaultName = 'version';
30
31
	/**
32
	 * Configures the command.
33
	 */
34
	protected function configure() {
35
		$this->setDescription( 'Displays versions from the changelog and change files' )
36
			->addArgument( 'which', InputArgument::REQUIRED, 'Version to fetch: <info>previous</>, <info>current</>, or <info>next</>' )
37
			->addOption( 'use-version', null, InputOption::VALUE_REQUIRED, 'When fetching the next version, use this instead of the current version in the changelog' )
38
			->addOption( 'use-significance', null, InputOption::VALUE_REQUIRED, 'When fetching the next version, use this significance instead of using the actual change files' )
39
			->addOption( 'prerelease', 'p', InputOption::VALUE_REQUIRED, 'When fetching the next version, include this prerelease suffix' )
40
			->addOption( 'buildinfo', 'b', InputOption::VALUE_REQUIRED, 'When fetching the next version, include this buildinfo suffix' )
41
			->setHelp(
42
				<<<EOF
43
The <info>version</info> command reads the versions from the changelog, and outputs the previous, current, or next version based on the change files.
44
EOF
45
			);
46
47
		try {
48
			$this->getDefinition()->addOptions( Config::formatterPlugin()->getOptions() );
49
		} catch ( \Exception $ex ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
50
			// Will handle later.
51
		}
52
		try {
53
			$this->getDefinition()->addOptions( Config::versioningPlugin()->getOptions() );
54
		} catch ( \Exception $ex ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
55
			// Will handle later.
56
		}
57
	}
58
59
	/**
60
	 * Executes the command.
61
	 *
62
	 * @param InputInterface  $input InputInterface.
63
	 * @param OutputInterface $output OutputInterface.
64
	 * @return int 0 if everything went fine, or an exit code.
65
	 */
66
	protected function execute( InputInterface $input, OutputInterface $output ) {
67
		try {
68
			$formatter = Config::formatterPlugin();
69
			$formatter->setIO( $input, $output );
70
			$versioning = Config::versioningPlugin();
71
			$versioning->setIO( $input, $output );
72
		} catch ( \Exception $ex ) {
73
			$output->writeln( "<error>{$ex->getMessage()}</>" );
74
			return 1;
75
		}
76
77
		$which = (string) $input->getArgument( 'which' );
78
		$l     = '' === $which ? 1 : strlen( $which );
79
		$ok    = false;
80
		foreach ( array( 'previous', 'current', 'next' ) as $w ) {
81
			if ( substr( $w, 0, $l ) === $which ) {
82
				$which = $w;
83
				$ok    = true;
84
			}
85
		}
86
		if ( ! $ok ) {
87
			$output->writeln( "<error>Don't know how to fetch the \"$which\" version</>" );
88
			return 1;
89
		}
90
91
		if ( 'next' === $which && $input->getOption( 'use-version' ) !== null ) {
92
			$versions = array( $input->getOption( 'use-version' ) );
93
		} else {
94
			$file = Config::changelogFile();
95
			if ( ! file_exists( $file ) ) {
96
				$output->writeln( "<error>Changelog file $file does not exist</>" );
97
				return 1;
98
			}
99
100
			Utils::error_clear_last();
101
			$contents = quietCall( 'file_get_contents', $file );
102
			// @codeCoverageIgnoreStart
103
			if ( ! is_string( $contents ) ) {
104
				$err = error_get_last();
105
				$output->writeln( "<error>Failed to read $file: {$err['message']}</>" );
106
				return 1;
107
			}
108
			// @codeCoverageIgnoreEnd
109
110
			try {
111
				$versions = $formatter->parse( $contents )->getVersions();
112
			} catch ( \Exception $ex ) {
113
				$output->writeln( "<error>Failed to parse changelog: {$ex->getMessage()}</>" );
114
				return 1;
115
			}
116
117
			if ( count( $versions ) === 0 ) {
118
				$output->writeln( '<error>Changelog file contains no entries</>' );
119
				return 1;
120
			}
121
		}
122
123
		if ( 'previous' === $which ) {
124
			if ( count( $versions ) < 2 ) {
125
				$output->writeln( '<error>Changelog file contains no previous version</>' );
126
				return 1;
127
			}
128
			$output->writeln( $versions[1], OutputInterface::VERBOSITY_QUIET );
129
			return 0;
130
		}
131
		if ( 'current' === $which ) {
132
			$output->writeln( $versions[0], OutputInterface::VERBOSITY_QUIET );
133
			return 0;
134
		}
135
136
		if ( $input->getOption( 'use-significance' ) ) {
137
			try {
138
				$changes = array(
139
					$formatter->newChangeEntry(
140
						array(
141
							'significance' => $input->getOption( 'use-significance' ),
142
							'content'      => 'Dummy',
143
						)
144
					),
145
				);
146
			} catch ( \Exception $ex ) {
147
				$output->writeln( "<error>{$ex->getMessage()}</>" );
148
				return 1;
149
			}
150
		} else {
151
			$changes = Utils::loadAllChanges( Config::changesDir(), Config::types(), $formatter, $output );
152
		}
153
		$extra = array_filter(
154
			array(
155
				'prerelease' => $input->getOption( 'prerelease' ),
156
				'buildinfo'  => $input->getOption( 'buildinfo' ),
157
			)
158
		);
159
		try {
160
			$output->writeln( $versioning->nextVersion( $versions[0], $changes, $extra ), OutputInterface::VERBOSITY_QUIET );
161
			return 0;
162
		} catch ( \Exception $ex ) {
163
			$output->writeln( "<error>{$ex->getMessage()}</>" );
164
			return 1;
165
		}
166
	}
167
}
168