Passed
Push — master ( 8b5091...c51706 )
by Anton
01:50
created

RunCommand   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 93
Duplicated Lines 7.53 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 58.49%

Importance

Changes 0
Metric Value
dl 7
loc 93
ccs 31
cts 53
cp 0.5849
rs 10
c 0
b 0
f 0
wmc 9
lcom 1
cbo 7

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A configure() 0 32 1
B execute() 7 36 7

How to fix   Duplicated Code   

Duplicated Code

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
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 function Deployer\run;
13
use Deployer\Task\Context;
14
use Deployer\Task\Task;
15
use function Deployer\write;
16
use function Deployer\writeln;
17
use Symfony\Component\Console\Command\Command;
18
use Symfony\Component\Console\Input\InputArgument;
19
use Symfony\Component\Console\Input\InputInterface as Input;
20
use Symfony\Component\Console\Input\InputOption as Option;
21
use Symfony\Component\Console\Output\OutputInterface as Output;
22
23
class RunCommand extends Command
24
{
25
    /**
26
     * @var Deployer
27
     */
28
    private $deployer;
29
30
    /**
31
     * @param Deployer $deployer
32
     */
33 12
    public function __construct(Deployer $deployer)
34
    {
35 12
        parent::__construct('run');
36 12
        $this->setDescription('Run any arbitrary command on hosts');
37 12
        $this->deployer = $deployer;
38 12
    }
39
40
    /**
41
     * Configures the command
42
     */
43 12
    protected function configure()
44
    {
45 12
        $this->addArgument(
46 12
            'command-to-run',
47 12
            InputArgument::REQUIRED,
48 12
            'Command to run'
49
        );
50 12
        $this->addOption(
51 12
            'log',
52 12
            null,
53 12
            Option::VALUE_REQUIRED,
54 12
            'Log to file'
55
        );
56 12
        $this->addOption(
57 12
            'stage',
58 12
            null,
59 12
            Option::VALUE_REQUIRED,
60 12
            'Stage to deploy'
61
        );
62 12
        $this->addOption(
63 12
            'roles',
64 12
            null,
65 12
            Option::VALUE_REQUIRED,
66 12
            'Roles to deploy'
67
        );
68 12
        $this->addOption(
69 12
            'hosts',
70 12
            null,
71 12
            Option::VALUE_REQUIRED,
72 12
            'Host to deploy, comma separated, supports ranges [:]'
73
        );
74 12
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    protected function execute(Input $input, Output $output)
80
    {
81
        $command = $input->getArgument('command-to-run');
82
        $stage = $input->getOption('stage');
83
        $roles = $input->getOption('roles');
84
        $hosts = $input->getOption('hosts');
85
86
        if (!empty($input->getOption('log'))) {
87
            $this->deployer->config['log_file'] = $input->getOption('log');
88
        }
89
90 View Code Duplication
        if (!empty($hosts)) {
91
            $hosts = $this->deployer->hostSelector->getByHostnames($hosts);
92
        } elseif (!empty($roles)) {
93
            $hosts = $this->deployer->hostSelector->getByRoles($roles);
94
        } else {
95
            $hosts = $this->deployer->hostSelector->getHosts($stage);
96
        }
97
98
        if (empty($hosts)) {
99
            throw new Exception('No host selected');
100
        }
101
102
        $task = new Task($command, function () use ($command, $hosts) {
0 ignored issues
show
Bug introduced by Anton Medvedev
It seems like $command defined by $input->getArgument('command-to-run') on line 81 can also be of type array<integer,string> or null; however, Deployer\Task\Task::__construct() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
103
            $output = run($command);
0 ignored issues
show
Bug introduced by Anton Medvedev
It seems like $command defined by $input->getArgument('command-to-run') on line 81 can also be of type array<integer,string> or null; however, Deployer\run() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
104
            if (count($hosts) > 1) {
105
                writeln("[{{hostname}}] > $output");
106
            } else {
107
                write($output);
108
            }
109
        });
110
111
        foreach ($hosts as $host) {
112
            $task->run(new Context($host, $input, $output));
113
        }
114
    }
115
}
116