SshTask::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 6
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 3
crap 2
1
<?php
2
3
/*
4
 * This file is part of the Conveyor package.
5
 *
6
 * (c) Jeroen Fiege <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webcreate\Conveyor\Task;
13
14
use Webcreate\Conveyor\DependencyInjection\TransporterAwareInterface;
15
use Webcreate\Conveyor\IO\IOInterface;
16
use Webcreate\Conveyor\Repository\Version;
17
use Webcreate\Conveyor\Transporter\AbstractTransporter;
18
use Webcreate\Conveyor\Transporter\SshCapableTransporterInterface;
19
use Webcreate\Conveyor\Util\FilePath;
20
use Webcreate\Util\Cli;
21
22
class SshTask extends Task implements TransporterAwareInterface
23
{
24
    /**
25
     * @var AbstractTransporter|SshCapableTransporterInterface
26
     */
27
    protected $transporter;
28
29
    public function __construct($config, Cli $cli, IOInterface $io)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $io. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
30
    {
31
        $this->config = $config;
0 ignored issues
show
Bug introduced by
The property config does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
32
        $this->cli    = $cli;
0 ignored issues
show
Bug introduced by
The property cli does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
33
        $this->io     = $io;
0 ignored issues
show
Bug introduced by
The property io does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
34
    }
35
36
    public function setTransporter($transporter)
37
    {
38
        if (false === $transporter instanceof SshCapableTransporterInterface) {
39
            throw new \InvalidArgumentException(sprintf("Given transporter of type '%s' does not support SSH.", get_class($transporter)));
40
        }
41
42
        $this->transporter = $transporter;
43
    }
44
45
    /**
46
     * @todo improve output (also @see ShellTask)
47
     *
48
     * @param $target
49
     * @param  Version           $version
50
     * @throws \RuntimeException
51
     */
52
    public function execute($target, Version $version)
53
    {
54
        $command = $this->getCommand($target, $version, $this->options['command']);
55
56
        $this->output(sprintf('Executing: <comment>%s</comment>', $command));
57
58
        $hasOutput = false;
59
60
        $self = $this;
61 View Code Duplication
        $outputter = function ($buffer) use ($self, &$hasOutput) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
            if (false === $self->io->isVerbose()) return;
0 ignored issues
show
Coding Style introduced by
Please always use braces to surround the code block of IF statements.
Loading history...
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
63
64
            if (!$hasOutput) {
65
                $this->io->write('');
66
                $this->io->write('');
67
                $hasOutput = true;
68
            }
69
70
            $lines = explode("\n", $buffer);
71
            foreach ($lines as $line) {
72
                if ($output = trim($line, "\r\n")) {
73
                    $self->io->write(sprintf('> %s', $output));
74
                }
75
            }
76
        };
77
78
        if ($exitCode = $this->transporter->exec($command, $outputter) <> 0) {
0 ignored issues
show
Bug introduced by
The method exec does only exist in Webcreate\Conveyor\Trans...bleTransporterInterface, but not in Webcreate\Conveyor\Transporter\AbstractTransporter.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
79
            throw new \RuntimeException(
80
                sprintf(
81
                    'The command "%s" failed.'."\nExit Code: %s",
82
                    $command,
83
                    $exitCode
84
                )
85
            );
86
        }
87
    }
88
89
    public function simulate($target, Version $version)
90
    {
91
        $command = $this->getCommand($target, $version, $this->options['command']);
92
93
        $this->output(sprintf('Executing: <comment>%s</comment>', $command));
94
    }
95
96
    protected function getCommand($target, $version, $command)
0 ignored issues
show
Unused Code introduced by
The parameter $target is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $version is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
97
    {
98
        $basepath = $path = $this->transporter->getPath();
0 ignored issues
show
Bug introduced by
The method getPath does only exist in Webcreate\Conveyor\Transporter\AbstractTransporter, but not in Webcreate\Conveyor\Trans...bleTransporterInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
99
100
        if (isset($this->options['path']) && $this->options['path']) {
101
            $path = FilePath::join($basepath, $this->options['path']);
102
        }
103
104
        $command = sprintf('cd %s && %s', $path, $command);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $command. This often makes code more readable.
Loading history...
105
106
        return $command;
107
    }
108
}
109