GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 30552d...bca1d2 )
by Anton
02:55
created

Arguments   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 89.74%

Importance

Changes 0
Metric Value
dl 0
loc 166
ccs 70
cts 78
cp 0.8974
rs 10
c 0
b 0
f 0
wmc 21
lcom 1
cbo 3

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getCliArguments() 0 17 1
A getOption() 0 4 1
A getFlag() 0 8 2
A withFlags() 0 7 1
A withOptions() 0 7 1
A withFlag() 0 7 1
A withOption() 0 7 1
A withDefaults() 0 8 1
A withMultiplexing() 0 12 1
B generateControlPath() 0 27 6
A buildFlagsFromArray() 0 20 4
A __toString() 0 4 1
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\Ssh;
9
10
use Deployer\Exception\Exception;
11
use Deployer\Host\Host;
12
use Deployer\Support\Unix;
13
14
/**
15
 * @author Michael Woodward <[email protected]>
16
 */
17
class Arguments
18
{
19
    /**
20
     * @var array
21
     */
22
    private $flags = [];
23
24
    /**
25
     * @var array
26
     */
27
    private $options = [];
28
29 9
    public function getCliArguments()
30
    {
31 9
        $boolFlags = array_keys(array_filter($this->flags, 'is_null'));
32
33 9
        $valueFlags = array_filter($this->flags);
34 9
        $valueFlags = array_map(function ($key, $value) {
35 4
            return "$key $value";
36 9
        }, array_keys($valueFlags), $valueFlags);
37
38 9
        $options = array_map(function ($key, $value) {
39 7
            return "-o $key=$value";
40 9
        }, array_keys($this->options), $this->options);
41
42 9
        $args = sprintf('%s %s %s', implode(' ', $boolFlags), implode(' ', $valueFlags), implode(' ', $options));
43
44 9
        return trim(preg_replace('!\s+!', ' ', $args));
45
    }
46
47 3
    public function getOption(string $option)
48
    {
49 3
        return $this->options[$option] ?? '';
50
    }
51
52 1
    public function getFlag(string $flag)
53
    {
54 1
        if (!array_key_exists($flag, $this->flags)) {
55
            return false;
56
        }
57
58 1
        return $this->flags[$flag] ?? true;
59
    }
60
61 8
    public function withFlags(array $flags)
62
    {
63 8
        $clone = clone $this;
64 8
        $clone->flags = $this->buildFlagsFromArray($flags);
65
66 8
        return $clone;
67
    }
68
69 10
    public function withOptions(array $options)
70
    {
71 10
        $clone = clone $this;
72 10
        $clone->options = $options;
73
74 10
        return $clone;
75
    }
76
77 4
    public function withFlag(string $flag, string $value = null)
78
    {
79 4
        $clone = clone $this;
80 4
        $clone->flags = array_merge($this->flags, [$flag => $value]);
81
82 4
        return $clone;
83
    }
84
85 4
    public function withOption(string $option, string $value)
86
    {
87 4
        $clone = clone $this;
88 4
        $clone->options = array_merge($this->options, [$option => $value]);
89
90 4
        return $clone;
91
    }
92
93 4
    public function withDefaults(Arguments $defaultOptions)
94
    {
95 4
        $clone = clone $this;
96 4
        $clone->options = array_merge($defaultOptions->options, $this->options);
97 4
        $clone->flags = array_merge($defaultOptions->flags, $this->flags);
98
99 4
        return $clone;
100
    }
101
102 2
    public function withMultiplexing(Host $host)
103
    {
104 2
        $controlPath = $this->generateControlPath($host);
105
106 2
        $multiplexDefaults = (new Arguments)->withOptions([
107 2
            'ControlMaster' => 'auto',
108 2
            'ControlPersist' => '60',
109 2
            'ControlPath' => $controlPath,
110
        ]);
111
112 2
        return $this->withDefaults($multiplexDefaults);
113
    }
114
115
    /**
116
     * Return SSH multiplexing control path
117
     *
118
     * When ControlPath is longer than 104 chars we can get:
119
     *
120
     *     SSH Error: unix_listener: too long for Unix domain socket
121
     *
122
     * So try to get as descriptive path as possible.
123
     * %C is for creating hash out of connection attributes.
124
     *
125
     * @param Host $host
126
     * @return string ControlPath
127
     * @throws Exception
128
     */
129 2
    private function generateControlPath(Host $host)
130
    {
131 2
        $connectionHashLength = 16; // Length of connection hash that OpenSSH appends to controlpath
132 2
        $unixMaxPath = 104; // Theoretical max limit for path length
133 2
        $homeDir = Unix::parseHomeDir('~');
134 2
        $port = empty($host->getPort()) ? '' : ':' . $host->getPort();
135 2
        $connectionData = "$host$port";
136 2
        $tryLongestPossible = 0;
137 2
        $controlPath = '';
138
        do {
139
            switch ($tryLongestPossible) {
140 2
                case 1:
141
                    $controlPath = "$homeDir/.ssh/deployer_%C";
142
                    break;
143 2
                case 2:
144
                    $controlPath = "$homeDir/.ssh/mux_%C";
145
                    break;
146 2
                case 3:
147
                    throw new Exception("The multiplexing control path is too long. Control path is: $controlPath");
148
                default:
149 2
                    $controlPath = "$homeDir/.ssh/deployer_$connectionData";
150
            }
151 2
            $tryLongestPossible++;
152 2
        } while (strlen($controlPath) + $connectionHashLength > $unixMaxPath); // Unix socket max length
153
154 2
        return $controlPath;
155
    }
156
157
    private function buildFlagsFromArray($flags)
158
    {
159 8
        $boolFlags = array_filter(array_map(function ($key, $value) {
160 8
            if (is_int($key)) {
161 6
                return $value;
162
            }
163
164 4
            if (null === $value) {
165 3
                return $key;
166
            }
167
168 4
            return false;
169 8
        }, array_keys($flags), $flags));
170
171 8
        $valueFlags = array_filter($flags, function ($key, $value) {
172 8
            return is_string($key) && is_string($value);
173 8
        }, ARRAY_FILTER_USE_BOTH);
174
175 8
        return array_merge(array_fill_keys($boolFlags, null), $valueFlags);
176
    }
177
178
    public function __toString()
179
    {
180
        return $this->getCliArguments();
181
    }
182
}
183