Failed Conditions
Push — master ( 5433f0...117895 )
by Alexander
01:52
created

BackportCommand::createBackportsIssues()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 35
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 35
ccs 0
cts 26
cp 0
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 19
nc 4
nop 2
crap 20
1
<?php
2
/**
3
 * This file is part of the Jira-CLI 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/jira-cli
9
 */
10
11
namespace ConsoleHelpers\JiraCLI\Command;
12
13
14
use chobie\Jira\Issue;
15
use ConsoleHelpers\ConsoleKit\Exception\CommandException;
16
use ConsoleHelpers\JiraCLI\Issue\BackportableIssueCloner;
17
use Symfony\Component\Console\Helper\Table;
18
use Symfony\Component\Console\Input\InputArgument;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Input\InputOption;
21
use Symfony\Component\Console\Output\OutputInterface;
22
23
class BackportCommand extends AbstractCommand
24
{
25
26
	const ISSUE_LINK_NAME = 'Backports';
27
28
	/**
29
	 * Issue cloner.
30
	 *
31
	 * @var BackportableIssueCloner
32
	 */
33
	protected $issueCloner;
34
35
	/**
36
	 * {@inheritdoc}
37
	 */
38
	protected function configure()
39
	{
40
		$this
41
			->setName('backport')
42
			->setDescription('Shows/creates backport issues')
43
			->addArgument(
44
				'project_key',
45
				InputArgument::REQUIRED,
46
				'Project key, e.g. <comment>JRA</comment>'
47
			)
48
			->addOption(
49
				'create',
50
				null,
51
				InputOption::VALUE_NONE,
52
				'Creates missing backported issues'
53
			);
54
	}
55
56
	/**
57
	 * Prepare dependencies.
58
	 *
59
	 * @return void
60
	 */
61
	protected function prepareDependencies()
62
	{
63
		parent::prepareDependencies();
64
65
		$container = $this->getContainer();
66
67
		$this->issueCloner = $container['backportable_issue_cloner'];
68
	}
69
70
	/**
71
	 * {@inheritdoc}
72
	 *
73
	 * @throws CommandException When no backportable issues were found.
74
	 */
75
	protected function execute(InputInterface $input, OutputInterface $output)
76
	{
77
		$project_key = $this->io->getArgument('project_key');
78
79
		if ( !in_array($project_key, $this->getProjectKeys()) ) {
80
			throw new CommandException('The project with "' . $project_key . '" key does\'t exist.');
81
		}
82
83
		$issues = $this->issueCloner->getIssues(
84
			'project = ' . $project_key . ' AND labels = backportable',
85
			self::ISSUE_LINK_NAME,
86
			BackportableIssueCloner::LINK_DIRECTION_INWARD
87
		);
88
		$issue_count = count($issues);
89
90
		if ( !$issue_count ) {
91
			throw new CommandException('No backportable issues found.');
92
		}
93
94
		$this->io->writeln(
95
			'Found <info>' . $issue_count . '</info> backportable issues in <info>' . $project_key . '</info> project.'
96
		);
97
98
		if ( $this->io->getOption('create') ) {
99
			$this->createBackportsIssues($project_key, $issues);
100
		}
101
		else {
102
			$this->showBackportableIssues($issues);
103
		}
104
	}
105
106
	/**
107
	 * Shows backportable issues.
108
	 *
109
	 * @param array $issues Backportable Issues.
110
	 *
111
	 * @return void
112
	 */
113
	protected function showBackportableIssues(array $issues)
114
	{
115
		$table = new Table($this->io->getOutput());
116
117
		foreach ( $issues as $issue_pair ) {
118
			/** @var Issue $issue */
119
			$issue = $issue_pair[0];
120
121
			/** @var Issue $backported_by_issue */
122
			$backported_by_issue = $issue_pair[1];
123
124
			$issue_status = $this->issueCloner->getIssueStatusName($issue);
125
			$row_data = array(
126
				$issue->getKey(),
127
				$issue->get('summary'),
128
				$issue_status,
129
			);
130
131
			if ( is_object($backported_by_issue) ) {
132
				$backported_by_issue_status = $this->issueCloner->getIssueStatusName($backported_by_issue);
133
				$row_data[] = $backported_by_issue->getKey();
134
				$row_data[] = $backported_by_issue->get('summary');
135
				$row_data[] = $backported_by_issue_status;
136
			}
137
			else {
138
				$row_data[] = '';
139
				$row_data[] = '';
140
				$row_data[] = '';
141
			}
142
143
			$table->addRow($row_data);
144
		}
145
146
		$table->setHeaders(array(
147
			'From Key',
148
			'From Summary',
149
			'From Status',
150
			'To Key',
151
			'To Summary',
152
			'To Status',
153
		));
154
155
		$table->render();
156
	}
157
158
	/**
159
	 * Creates backports issues.
160
	 *
161
	 * @param string $project_key Project key.
162
	 * @param array  $issue_pairs Backportable Issues.
163
	 *
164
	 * @return void
165
	 */
166
	protected function createBackportsIssues($project_key, array $issue_pairs)
167
	{
168
		foreach ( $issue_pairs as $issue_pair ) {
169
			/** @var Issue $issue */
170
			$issue = $issue_pair[0];
171
172
			/** @var Issue $linked_issue */
173
			$linked_issue = $issue_pair[1];
174
175
			$this->io->write('Processing "<info>' . $issue->getKey() . '</info>" issue ... ');
176
177
			if ( is_object($linked_issue) ) {
178
				$this->io->writeln(
179
					'linked issue "<info>' . $linked_issue->getKey() . '</info>" already exists.'
180
				);
181
				continue;
182
			}
183
184
			$components = array();
185
186
			foreach ( $issue->get('components') as $component ) {
187
				$components[] = $component['id'];
188
			}
189
190
			$linked_issue_key = $this->issueCloner->createLinkedIssue(
191
				$issue,
192
				$project_key,
193
				self::ISSUE_LINK_NAME,
194
				BackportableIssueCloner::LINK_DIRECTION_INWARD,
195
				$components
196
			);
197
198
			$this->io->writeln('linked issue "<info>' . $linked_issue_key . '</info>" created.');
199
		}
200
	}
201
202
}
203