TaskCommand::parseOptions()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 8
ccs 6
cts 6
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/* (c) Anton Medvedev <[email protected]>
3
 *
4
 * For the full copyright and license information, please view the LICENSE
5
 * file that was distributed with this source code.
6
 */
7
8
namespace Deployer\Console;
9
10
use Deployer\Deployer;
11
use Deployer\Exception\Exception;
12
use Deployer\Exception\GracefulShutdownException;
13
use Deployer\Executor\ExecutorInterface;
14
use Symfony\Component\Console\Command\Command;
15
use Symfony\Component\Console\Input\InputArgument;
16
use Symfony\Component\Console\Input\InputInterface as Input;
17
use Symfony\Component\Console\Input\InputOption as Option;
18
use Symfony\Component\Console\Output\OutputInterface as Output;
19
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 17
    public function __construct($name, $description, Deployer $deployer)
38
    {
39 17
        parent::__construct($name);
40 17
        $this->setDescription($description);
41 17
        $this->deployer = $deployer;
42 17
    }
43
44
    /**
45
     * Configures the command
46
     */
47 17
    protected function configure()
48
    {
49 17
        $this->addArgument(
50 17
            'stage',
51 17
            InputArgument::OPTIONAL,
52 17
            'Stage or hostname'
53
        );
54 17
        $this->addOption(
55 17
            'parallel',
56 17
            'p',
57 17
            Option::VALUE_NONE,
58 17
            'Run tasks in parallel'
59
        );
60 17
        $this->addOption(
61 17
            'limit',
62 17
            'l',
63 17
            Option::VALUE_REQUIRED,
64 17
            'How many host to run in parallel?'
65
        );
66 17
        $this->addOption(
67 17
            'no-hooks',
68 17
            null,
69 17
            Option::VALUE_NONE,
70 17
            'Run task without after/before hooks'
71
        );
72 17
        $this->addOption(
73 17
            'log',
74 17
            null,
75 17
            Option::VALUE_REQUIRED,
76 17
            'Log to file'
77
        );
78 17
        $this->addOption(
79 17
            'roles',
80 17
            null,
81 17
            Option::VALUE_REQUIRED,
82 17
            'Roles to deploy'
83
        );
84 17
        $this->addOption(
85 17
            'hosts',
86 17
            null,
87 17
            Option::VALUE_REQUIRED,
88 17
            'Host to deploy, comma separated, supports ranges [:]'
89
        );
90 17
        $this->addOption(
91 17
            'option',
92 17
            'o',
93 17
            Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY,
94 17
            'Sets configuration option'
95
        );
96 17
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101 16
    protected function execute(Input $input, Output $output)
102
    {
103 16
        $stage = $input->hasArgument('stage') ? $input->getArgument('stage') : null;
104 16
        $roles = $input->getOption('roles');
105 16
        $hosts = $input->getOption('hosts');
106 16
        $this->parseOptions($input->getOption('option'));
107
108 16
        $hooksEnabled = !$input->getOption('no-hooks');
109 16
        if (!empty($input->getOption('log'))) {
110
            $this->deployer->config['log_file'] = $input->getOption('log');
111
        }
112
113 16 View Code Duplication
        if (!empty($hosts)) {
114
            $hosts = $this->deployer->hostSelector->getByHostnames($hosts);
115 16
        } elseif (!empty($roles)) {
116
            $hosts = $this->deployer->hostSelector->getByRoles($roles);
117
        } else {
118 16
            $hosts = $this->deployer->hostSelector->getHosts($stage);
119
        }
120
121 16
        if (empty($hosts)) {
122
            throw new Exception('No host selected');
123
        }
124
125 16
        $tasks = $this->deployer->scriptManager->getTasks(
126 16
            $this->getName(),
127
            $hosts,
128
            $hooksEnabled
129
        );
130
131 16
        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 16
        if ($input->getOption('parallel')) {
136 5
            $executor = $this->deployer->parallelExecutor;
137
        } else {
138 11
            $executor = $this->deployer->seriesExecutor;
139
        }
140
141
        try {
142 16
            $executor->run($tasks, $hosts);
143 2
        } catch (\Throwable $exception) {
144 2
            $this->deployer->logger->log('['. get_class($exception) .'] '. $exception->getMessage());
145 2
            $this->deployer->logger->log($exception->getTraceAsString());
146
147 2
            if ($exception instanceof GracefulShutdownException) {
148
                throw $exception;
149
            } else {
150
                // Check if we have tasks to execute on failure
151 2
                if ($this->deployer['fail']->has($this->getName())) {
152 2
                    $taskName = $this->deployer['fail']->get($this->getName());
153 2
                    $tasks = $this->deployer->scriptManager->getTasks($taskName, $hosts, $hooksEnabled);
154
155 2
                    $executor->run($tasks, $hosts);
156
                }
157 2
                throw $exception;
158
            }
159
        }
160 14
    }
161
162 16
    private function parseOptions(array $options)
163
    {
164 16
        foreach ($options as $option) {
165 1
            list($name, $value) = explode('=', $option);
166 1
            $value = $this->castValueToPhpType($value);
167 1
            $this->deployer->config->set($name, $value);
168
        }
169 16
    }
170
171 1
    private function castValueToPhpType($value)
172
    {
173
        switch ($value) {
174 1
            case 'true':
175
                return true;
176 1
            case 'false':
177
                return false;
178
            default:
179 1
                return $value;
180
        }
181
    }
182
}
183