BackportCommand::showBackportableIssues()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 43
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 3
eloc 27
c 3
b 0
f 0
nc 3
nop 1
dl 0
loc 43
ccs 0
cts 29
cp 0
crap 12
rs 9.488
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
	const SUMMARY_COLUMN_WIDTH = 70;
29
30
	/**
31
	 * Issue cloner.
32
	 *
33
	 * @var BackportableIssueCloner
34
	 */
35
	protected $issueCloner;
36
37
	/**
38
	 * {@inheritdoc}
39
	 */
40
	protected function configure()
41
	{
42
		$this
43
			->setName('backport')
44
			->setDescription('Shows/creates backport issues')
45
			->addArgument(
46
				'project_key',
47
				InputArgument::REQUIRED,
48
				'Project key, e.g. <comment>JRA</comment>'
49
			)
50
			->addOption(
51
				'create',
52
				null,
53
				InputOption::VALUE_NONE,
54
				'Creates missing backported issues'
55
			);
56
	}
57
58
	/**
59
	 * Prepare dependencies.
60
	 *
61
	 * @return void
62
	 */
63
	protected function prepareDependencies()
64
	{
65
		parent::prepareDependencies();
66
67
		$container = $this->getContainer();
68
69
		$this->issueCloner = $container['backportable_issue_cloner'];
70
	}
71
72
	/**
73
	 * {@inheritdoc}
74
	 *
75
	 * @throws CommandException When no backportable issues were found.
76
	 */
77
	protected function execute(InputInterface $input, OutputInterface $output)
78
	{
79
		$project_key = $this->io->getArgument('project_key');
80
81
		if ( !in_array($project_key, $this->jiraApi->getProjectKeys()) ) {
82
			throw new CommandException('The project with "' . $project_key . '" key does\'t exist.');
0 ignored issues
show
Bug introduced by
Are you sure $project_key of type null|string|string[] can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

82
			throw new CommandException('The project with "' . /** @scrutinizer ignore-type */ $project_key . '" key does\'t exist.');
Loading history...
83
		}
84
85
		$issues = $this->issueCloner->getIssues(
86
			'project = ' . $project_key . ' AND labels = backportable',
87
			self::ISSUE_LINK_NAME,
88
			BackportableIssueCloner::LINK_DIRECTION_INWARD,
89
			array($project_key)
90
		);
91
		$issue_count = count($issues);
92
93
		if ( !$issue_count ) {
94
			throw new CommandException('No backportable issues found.');
95
		}
96
97
		$this->io->writeln(
98
			'Found <info>' . $issue_count . '</info> backportable issues in <info>' . $project_key . '</info> project.'
99
		);
100
101
		if ( $this->io->getOption('create') ) {
102
			$this->createBackportsIssues($project_key, $issues);
0 ignored issues
show
Bug introduced by
It seems like $project_key can also be of type string[]; however, parameter $project_key of ConsoleHelpers\JiraCLI\C...createBackportsIssues() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

102
			$this->createBackportsIssues(/** @scrutinizer ignore-type */ $project_key, $issues);
Loading history...
103
		}
104
		else {
105
			$this->showBackportableIssues($issues);
106
		}
107
108
		$this->showStatistics();
109
	}
110
111
	/**
112
	 * Shows backportable issues.
113
	 *
114
	 * @param array $issues Backportable Issues.
115
	 *
116
	 * @return void
117
	 */
118
	protected function showBackportableIssues(array $issues)
119
	{
120
		$table = new Table($this->io->getOutput());
121
122
		foreach ( $issues as $issue_pair ) {
123
			/** @var Issue $issue */
124
			$issue = $issue_pair[0];
125
126
			/** @var Issue $backported_by_issue */
127
			$backported_by_issue = $issue_pair[1];
128
129
			$issue_status = $this->issueCloner->getIssueStatusName($issue);
130
			$row_data = array(
131
				$issue->getKey(),
132
				wordwrap($issue->get('summary'), self::SUMMARY_COLUMN_WIDTH),
0 ignored issues
show
Bug introduced by
$issue->get('summary') of type array is incompatible with the type string expected by parameter $string of wordwrap(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

132
				wordwrap(/** @scrutinizer ignore-type */ $issue->get('summary'), self::SUMMARY_COLUMN_WIDTH),
Loading history...
133
				$issue_status,
134
			);
135
136
			if ( is_object($backported_by_issue) ) {
137
				$backported_by_issue_status = $this->issueCloner->getIssueStatusName($backported_by_issue);
138
				$row_data[] = $backported_by_issue->getKey();
139
				$row_data[] = wordwrap($backported_by_issue->get('summary'), self::SUMMARY_COLUMN_WIDTH);
140
				$row_data[] = $backported_by_issue_status;
141
			}
142
			else {
143
				$row_data[] = '';
144
				$row_data[] = '';
145
				$row_data[] = '';
146
			}
147
148
			$table->addRow($row_data);
149
		}
150
151
		$table->setHeaders(array(
152
			'From Key',
153
			'From Summary',
154
			'From Status',
155
			'To Key',
156
			'To Summary',
157
			'To Status',
158
		));
159
160
		$table->render();
161
	}
162
163
	/**
164
	 * Creates backports issues.
165
	 *
166
	 * @param string $project_key Project key.
167
	 * @param array  $issue_pairs Backportable Issues.
168
	 *
169
	 * @return void
170
	 */
171
	protected function createBackportsIssues($project_key, array $issue_pairs)
172
	{
173
		foreach ( $issue_pairs as $issue_pair ) {
174
			/** @var Issue $issue */
175
			$issue = $issue_pair[0];
176
177
			/** @var Issue $linked_issue */
178
			$linked_issue = $issue_pair[1];
179
180
			$this->io->write('Processing "<info>' . $issue->getKey() . '</info>" issue ... ');
181
182
			if ( is_object($linked_issue) ) {
183
				$this->io->writeln(
184
					'linked issue "<info>' . $linked_issue->getKey() . '</info>" already exists.'
185
				);
186
				continue;
187
			}
188
189
			$components = array();
190
191
			foreach ( $issue->get('components') as $component ) {
192
				$components[] = $component['id'];
193
			}
194
195
			$linked_issue_key = $this->issueCloner->createLinkedIssue(
196
				$issue,
197
				$project_key,
198
				self::ISSUE_LINK_NAME,
199
				BackportableIssueCloner::LINK_DIRECTION_INWARD,
200
				$components
201
			);
202
203
			$this->io->writeln('linked issue "<info>' . $linked_issue_key . '</info>" created.');
204
		}
205
	}
206
207
}
208