Completed
Push — master ( 2cfff3...1413b8 )
by Alexander
03:09
created

PharCreateCommand::_getVersion()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
ccs 0
cts 6
cp 0
rs 9.4285
cc 3
eloc 6
nc 2
nop 0
crap 12
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
				Stability::STABLE
56
			);
57
58
		parent::configure();
59
	}
60
61
	/**
62
	 * Prepare dependencies.
63
	 *
64
	 * @return void
65
	 */
66
	protected function prepareDependencies()
67
	{
68
		parent::prepareDependencies();
69
70
		$container = $this->getContainer();
71
72
		$this->_projectRootFolder = $container['project_root_folder'];
73
	}
74
75
	/**
76
	 * Return possible values for the named option
77
	 *
78
	 * @param string            $optionName Option name.
79
	 * @param CompletionContext $context    Completion context.
80
	 *
81
	 * @return array
82
	 */
83
	public function completeOptionValues($optionName, CompletionContext $context)
84
	{
85
		$ret = parent::completeOptionValues($optionName, $context);
86
87
		if ( $optionName === 'stability' ) {
88
			return $this->_getStabilities();
89
		}
90
91
		return $ret;
92
	}
93
94
	/**
95
	 * {@inheritdoc}
96
	 *
97
	 * @throws \RuntimeException When unknown stability was specified.
98
	 */
99
	protected function execute(InputInterface $input, OutputInterface $output)
100
	{
101
		$stability = $this->_getStability();
102
103
		if ( !in_array($stability, $this->_getStabilities()) ) {
104
			throw new \RuntimeException('The "' . $stability . '" is unknown.');
105
		}
106
107
		$version = $this->_getVersion();
108
		$build_dir = realpath($this->io->getOption('build-dir'));
109
110
		$this->io->write('1. removing dev dependencies ... ');
111
		$this->_shellCommand(
112
			'composer',
113
			array(
114
				'install',
115
				'--no-interaction',
116
				'--no-dev',
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
			),
154
			$this->_projectRootFolder
155
		);
156
		$this->io->writeln('done');
157
158
		$this->io->writeln('Phar for <info>' . $version . '</info> version created.');
159
	}
160
161
	/**
162
	 * Returns stability.
163
	 *
164
	 * @return string|null
165
	 */
166
	private function _getStability()
167
	{
168
		return $this->io->getOption('stability');
169
	}
170
171
	/**
172
	 * Returns all stabilities.
173
	 *
174
	 * @return array
175
	 */
176
	private function _getStabilities()
177
	{
178
		return array(Stability::PREVIEW, Stability::SNAPSHOT, Stability::STABLE);
179
	}
180
181
	/**
182
	 * Returns version.
183
	 *
184
	 * @return string
185
	 * @throws CommandException When "stable" stability was used with non-stable version.
186
	 */
187
	private function _getVersion()
188
	{
189
		$stability = $this->_getStability();
190
		$git_version = $this->_getGitVersion();
191
192
		if ( preg_match('/^.*-[\d]+-g.{7}$/', $git_version) && $stability === Stability::STABLE ) {
193
			throw new CommandException('The "' . $git_version . '" version can\'t be used with "stable" stability.');
194
		}
195
196
		return $stability . ':' . $git_version;
197
	}
198
199
	/**
200
	 * Returns same version as Box does for "git-version" replacement.
201
	 *
202
	 * @return string
203
	 */
204
	private function _getGitVersion()
205
	{
206
		return trim($this->_shellCommand('git', array('describe', 'HEAD', '--tags')));
207
	}
208
209
	/**
210
	 * Runs command.
211
	 *
212
	 * @param string      $command           Command.
213
	 * @param array       $arguments         Arguments.
214
	 * @param string|null $working_directory Working directory.
215
	 *
216
	 * @return string
217
	 */
218
	private function _shellCommand($command, array $arguments = array(), $working_directory = null)
219
	{
220
		$final_arguments = array_merge(array($command), $arguments);
221
222
		$process = ProcessBuilder::create($final_arguments)
223
			->setWorkingDirectory($working_directory)
224
			->getProcess();
225
226
		return $process->mustRun()->getOutput();
227
	}
228
229
}
230