Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
20 | class TaskCommand extends Command |
||
21 | { |
||
22 | /** |
||
23 | * @var Deployer |
||
24 | */ |
||
25 | private $deployer; |
||
26 | |||
27 | /** |
||
28 | * @var ExecutorInterface |
||
29 | */ |
||
30 | public $executor; |
||
31 | |||
32 | /** |
||
33 | * @param string $name |
||
34 | * @param string $description |
||
35 | * @param Deployer $deployer |
||
36 | */ |
||
37 | 7 | public function __construct($name, $description, Deployer $deployer) |
|
43 | |||
44 | /** |
||
45 | * Configures the command |
||
46 | */ |
||
47 | 7 | protected function configure() |
|
97 | |||
98 | /** |
||
99 | * {@inheritdoc} |
||
100 | */ |
||
101 | 7 | protected function execute(Input $input, Output $output) |
|
102 | { |
||
103 | 7 | $stage = $input->hasArgument('stage') ? $input->getArgument('stage') : null; |
|
104 | 7 | $roles = $input->getOption('roles'); |
|
105 | 7 | $hosts = $input->getOption('hosts'); |
|
106 | 7 | $this->parseOptions($input->getOption('option')); |
|
107 | |||
108 | 7 | $hooksEnabled = !$input->getOption('no-hooks'); |
|
109 | 7 | if (!empty($input->getOption('log'))) { |
|
110 | $this->deployer->config['log_file'] = $input->getOption('log'); |
||
111 | } |
||
112 | |||
113 | 7 | View Code Duplication | if (!empty($hosts)) { |
114 | $hosts = $this->deployer->hostSelector->getByHostnames($hosts); |
||
115 | 7 | } elseif (!empty($roles)) { |
|
116 | $hosts = $this->deployer->hostSelector->getByRoles($roles); |
||
117 | } else { |
||
118 | 7 | $hosts = $this->deployer->hostSelector->getHosts($stage); |
|
119 | } |
||
120 | |||
121 | 7 | if (empty($hosts)) { |
|
122 | throw new Exception('No host selected'); |
||
123 | } |
||
124 | |||
125 | 7 | $tasks = $this->deployer->scriptManager->getTasks( |
|
126 | 7 | $this->getName(), |
|
127 | $hosts, |
||
128 | $hooksEnabled |
||
129 | ); |
||
130 | |||
131 | 7 | if (empty($tasks)) { |
|
132 | throw new Exception('No task will be executed, because the selected hosts do not meet the conditions of the tasks'); |
||
133 | } |
||
134 | |||
135 | 7 | if ($input->getOption('parallel')) { |
|
136 | 1 | $executor = $this->deployer->parallelExecutor; |
|
137 | } else { |
||
138 | 6 | $executor = $this->deployer->seriesExecutor; |
|
139 | } |
||
140 | |||
141 | try { |
||
142 | 7 | $executor->run($tasks, $hosts); |
|
143 | } catch (\Throwable $exception) { |
||
144 | if ($exception instanceof GracefulShutdownException) { |
||
145 | throw $exception; |
||
146 | } else { |
||
147 | // Check if we have tasks to execute on failure |
||
148 | if ($this->deployer['fail']->has($this->getName())) { |
||
149 | $taskName = $this->deployer['fail']->get($this->getName()); |
||
150 | $tasks = $this->deployer->scriptManager->getTasks($taskName, $hosts, $hooksEnabled); |
||
151 | |||
152 | $executor->run($tasks, $hosts); |
||
153 | } |
||
154 | throw $exception; |
||
155 | } |
||
156 | } |
||
157 | 7 | } |
|
158 | |||
159 | 7 | private function parseOptions(array $options) |
|
167 | |||
168 | 1 | private function castValueToPhpType($value) |
|
179 | } |
||
180 |