Failed Conditions
Push — master ( dd969d...42da22 )
by Alexander
10:30
created

PharCreateCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 16
c 3
b 0
f 0
dl 0
loc 22
ccs 0
cts 16
cp 0
rs 9.7333
cc 1
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * This file is part of the SVN-Buddy library.
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 *
7
 * @copyright Alexander Obuhovich <[email protected]>
8
 * @link      https://github.com/console-helpers/svn-buddy
9
 */
10
11
namespace ConsoleHelpers\SVNBuddy\Command\Dev;
12
13
14
use ConsoleHelpers\ConsoleKit\Exception\CommandException;
15
use ConsoleHelpers\SVNBuddy\Command\AbstractCommand;
16
use ConsoleHelpers\SVNBuddy\Updater\Stability;
17
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Input\InputOption;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Symfony\Component\Process\ProcessBuilder;
22
23
class PharCreateCommand extends AbstractCommand
24
{
25
26
	/**
27
	 * Root folder of the project.
28
	 *
29
	 * @var string
30
	 */
31
	private $_projectRootFolder;
32
33
	/**
34
	 * {@inheritdoc}
35
	 */
36
	protected function configure()
37
	{
38
		$this
39
			->setName('dev:phar-create')
40
			->setDescription(
41
				'Creates PHAR for new release'
42
			)
43
			->addOption(
44
				'build-dir',
45
				null,
46
				InputOption::VALUE_REQUIRED,
47
				'Directory, where build results would be stored',
48
				'build'
49
			)
50
			->addOption(
51
				'stability',
52
				's',
53
				InputOption::VALUE_REQUIRED,
54
				'Stability of the build (<comment>stable</comment>, <comment>snapshot</comment>, <comment>preview</comment>)'
55
			);
56
57
		parent::configure();
58
	}
59
60
	/**
61
	 * Prepare dependencies.
62
	 *
63
	 * @return void
64
	 */
65
	protected function prepareDependencies()
66
	{
67
		parent::prepareDependencies();
68
69
		$container = $this->getContainer();
70
71
		$this->_projectRootFolder = $container['project_root_folder'];
72
	}
73
74
	/**
75
	 * Return possible values for the named option
76
	 *
77
	 * @param string            $optionName Option name.
78
	 * @param CompletionContext $context    Completion context.
79
	 *
80
	 * @return array
81
	 */
82
	public function completeOptionValues($optionName, CompletionContext $context)
83
	{
84
		$ret = parent::completeOptionValues($optionName, $context);
85
86
		if ( $optionName === 'stability' ) {
87
			return $this->_getStabilities();
88
		}
89
90
		return $ret;
91
	}
92
93
	/**
94
	 * {@inheritdoc}
95
	 *
96
	 * @throws \RuntimeException When unknown stability was specified.
97
	 */
98
	protected function execute(InputInterface $input, OutputInterface $output)
99
	{
100
		$stability = $this->_getStability();
101
102
		if ( $stability && !in_array($stability, $this->_getStabilities()) ) {
103
			throw new \RuntimeException('The "' . $stability . '" is unknown.');
104
		}
105
106
		$version = $this->_getVersion();
107
		$build_dir = realpath($this->io->getOption('build-dir'));
108
109
		$this->io->write('1. removing dev dependencies ... ');
110
		$this->_shellCommand(
111
			'composer',
112
			array(
113
				'install',
114
				'--no-interaction',
115
				'--no-dev',
116
				'--optimize-autoloader',
117
			),
118
			$this->_projectRootFolder
119
		);
120
		$this->io->writeln('done');
121
122
		$this->io->write('2. creating phar file ... ');
123
		$box_config = json_decode(file_get_contents($this->_projectRootFolder . '/box.json.dist'), true);
124
125
		$phar_file = $build_dir . '/' . basename($box_config['output']);
126
		$signature_file = $phar_file . '.sig';
127
128
		$box_config['replacements'] = array('git-version' => $version);
129
		$box_config['output'] = $phar_file;
130
131
		file_put_contents(
132
			$this->_projectRootFolder . '/box.json',
133
			json_encode($box_config, defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0)
134
		);
135
136
		$box_cli = trim($this->_shellCommand('which', array('box')));
137
		$this->_shellCommand('php', array('-d', 'phar.readonly=0', $box_cli, 'build'), $this->_projectRootFolder);
138
		$this->io->writeln('done');
139
140
		$this->io->write('3. calculating phar signature ... ');
141
		file_put_contents(
142
			$signature_file,
143
			$this->_shellCommand('sha1sum', array(basename($phar_file)), dirname($phar_file))
144
		);
145
		$this->io->writeln('done');
146
147
		$this->io->write('4. restoring dev dependencies ... ');
148
		$this->_shellCommand(
149
			'composer',
150
			array(
151
				'install',
152
				'--no-interaction',
153
				'--optimize-autoloader',
154
			),
155
			$this->_projectRootFolder
156
		);
157
		$this->io->writeln('done');
158
159
		$this->io->writeln('Phar for <info>' . $version . '</info> version created.');
160
	}
161
162
	/**
163
	 * Returns stability.
164
	 *
165
	 * @return string|null
166
	 */
167
	private function _getStability()
168
	{
169
		return $this->io->getOption('stability');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->io->getOption('stability') also could return the type boolean|string[] which is incompatible with the documented return type null|string.
Loading history...
170
	}
171
172
	/**
173
	 * Returns all stabilities.
174
	 *
175
	 * @return array
176
	 */
177
	private function _getStabilities()
178
	{
179
		return array(Stability::PREVIEW, Stability::SNAPSHOT, Stability::STABLE);
180
	}
181
182
	/**
183
	 * Returns version.
184
	 *
185
	 * @return string
186
	 * @throws CommandException When "stable" stability was used with non-stable version.
187
	 */
188
	private function _getVersion()
189
	{
190
		$stability = $this->_getStability();
191
		$git_version = $this->_getGitVersion();
192
		$is_unstable = preg_match('/^.*-[\d]+-g.{7}$/', $git_version);
193
194
		if ( !$stability ) {
195
			$stability = $is_unstable ? Stability::PREVIEW : Stability::STABLE;
196
		}
197
198
		if ( $is_unstable && $stability === Stability::STABLE ) {
199
			throw new CommandException('The "' . $git_version . '" version can\'t be used with "stable" stability.');
200
		}
201
202
		return $stability . ':' . $git_version;
203
	}
204
205
	/**
206
	 * Returns same version as Box does for "git-version" replacement.
207
	 *
208
	 * @return string
209
	 */
210
	private function _getGitVersion()
211
	{
212
		return trim($this->_shellCommand(
213
			'git',
214
			array('describe', 'HEAD', '--tags'),
215
			$this->_projectRootFolder
216
		));
217
	}
218
219
	/**
220
	 * Runs command.
221
	 *
222
	 * @param string      $command           Command.
223
	 * @param array       $arguments         Arguments.
224
	 * @param string|null $working_directory Working directory.
225
	 *
226
	 * @return string
227
	 */
228
	private function _shellCommand($command, array $arguments = array(), $working_directory = null)
229
	{
230
		$final_arguments = array_merge(array($command), $arguments);
231
232
		$process = ProcessBuilder::create($final_arguments)
233
			->setWorkingDirectory($working_directory)
234
			->getProcess();
235
236
		return $process->mustRun()->getOutput();
237
	}
238
239
}
240