Failed Conditions
Push — master ( 2cd9b5...479acf )
by Alexander
01:46
created

ChangeLogCloneCommand::getLinkNames()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 18
ccs 0
cts 14
cp 0
rs 9.4285
c 1
b 0
f 0
cc 3
eloc 10
nc 2
nop 0
crap 12
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\ChangeLogIssueCloner;
17
use ConsoleHelpers\JiraCLI\JiraApi;
18
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
19
use Symfony\Component\Console\Input\InputArgument;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
24
class ChangeLogCloneCommand extends AbstractCommand
25
{
26
27
	/**
28
	 * Issue cloner.
29
	 *
30
	 * @var ChangeLogIssueCloner
31
	 */
32
	protected $issueCloner;
33
34
	/**
35
	 * {@inheritdoc}
36
	 */
37
	protected function configure()
38
	{
39
		$this
40
			->setName('changelog-clone')
41
			->setDescription('Clones issue for changelog into another project')
42
			->addArgument(
43
				'issue_key',
44
				InputArgument::REQUIRED,
45
				'Issue key, e.g. <comment>JRA-1234</comment>'
46
			)
47
			->addArgument(
48
				'project_keys',
49
				InputArgument::REQUIRED | InputArgument::IS_ARRAY,
50
				'Project keys, e.g. <comment>PRJ</comment>'
51
			)
52
			->addOption(
53
				'link-name',
54
				null,
55
				InputOption::VALUE_REQUIRED,
56
				'Link name between issues',
57
				'Blocks'
58
			);
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->issueCloner = $container['changelog_issue_cloner'];
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 === 'link-name' ) {
88
			return $this->jiraApi->getIssueLinkTypeNames();
89
		}
90
91
		return $ret;
92
	}
93
94
	/**
95
	 * {@inheritdoc}
96
	 *
97
	 * @throws CommandException When no backportable issues were found.
98
	 */
99
	protected function execute(InputInterface $input, OutputInterface $output)
100
	{
101
		$issue_key = $this->io->getArgument('issue_key');
102
		$link_name = $this->io->getOption('link-name');
103
104
		if ( !in_array($link_name, $this->jiraApi->getIssueLinkTypeNames()) ) {
105
			throw new CommandException('The "' . $link_name . '" link name doesn\'t exist.');
106
		}
107
108
		$project_keys = $this->io->getArgument('project_keys');
109
		$non_existing_projects = array_diff($project_keys, $this->jiraApi->getProjectKeys());
110
111
		if ( $non_existing_projects ) {
112
			throw new CommandException(
113
				'These projects doesn\'t exist: "' . implode('", "', $non_existing_projects) . '".'
114
			);
115
		}
116
117
		$issues = $this->issueCloner->getIssues(
118
			'key = ' . $issue_key,
119
			$link_name,
120
			ChangeLogIssueCloner::LINK_DIRECTION_OUTWARD,
121
			$project_keys
122
		);
123
		$issue_count = count($issues);
124
125
		if ( !$issue_count ) {
126
			throw new CommandException('The "' . $issue_key . '" issue not found.');
127
		}
128
129
		foreach ( $issues as $issue_pair ) {
130
			/** @var Issue $issue */
131
			/** @var Issue $linked_issue */
132
			list($issue, $linked_issue, $link_project_key) = $issue_pair;
133
134
			$issue_project = $issue->get('project');
135
136
			if ( $issue_project['key'] === $link_project_key ) {
137
				throw new CommandException('Creating of linked issue in same project is not supported.');
138
			}
139
140
			if ( is_object($linked_issue) ) {
141
				$this->io->writeln(sprintf(
142
					'The "<info>%s</info>" issue already has "<info>%s</info>" link to "<info>%s</info>" issue.',
143
					$issue->getKey(),
144
					$link_name,
145
					$linked_issue->getKey()
146
				));
147
148
				continue;
149
			}
150
151
			$components = array();
152
			$project_components = $this->jiraApi->getProjectComponentMapping(
153
				$link_project_key,
154
				JiraApi::CACHE_DURATION_ONE_MONTH
155
			);
156
157
			if ( $project_components ) {
158
				$component_name = $this->io->choose(
159
					'Select linked issue component in "' . $link_project_key . '" project:',
160
					$project_components,
161
					'',
162
					'The component isn\'t valid'
163
				);
164
165
				$components[] = array_search($component_name, $project_components);
166
			}
167
168
			$linked_issue_key = $this->issueCloner->createLinkedIssue(
169
				$issue,
170
				$link_project_key,
171
				$link_name,
172
				ChangeLogIssueCloner::LINK_DIRECTION_OUTWARD,
173
				$components
174
			);
175
176
			$this->io->writeln(sprintf(
177
				'The "<info>%s</info>" issue now has "<info>%s</info>" link to "<info>%s</info>" issue.',
178
				$issue->getKey(),
179
				$link_name,
180
				$linked_issue_key
181
			));
182
		}
183
	}
184
185
}
186