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 ( fe3ff3...30552d )
by Anton
02:05
created

Arguments   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 172
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 85.71%

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 3
dl 0
loc 172
ccs 72
cts 84
cp 0.8571
rs 10
c 0
b 0
f 0

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 33 8
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/deployer_$connectionData";
145
                    break;
146 2
                case 3:
147
                    $controlPath = "$homeDir/.ssh/deployer_%C";
148
                    break;
149 2
                case 4:
150
                    $controlPath = "$homeDir/.ssh/mux_%C";
151
                    break;
152 2
                case 5:
153
                    throw new Exception("The multiplexing control path is too long. Control path is: $controlPath");
154
                default:
155 2
                    $controlPath = "$homeDir/.ssh/deployer_$connectionData";
156
            }
157 2
            $tryLongestPossible++;
158 2
        } while (strlen($controlPath) + $connectionHashLength > $unixMaxPath); // Unix socket max length
159
160 2
        return $controlPath;
161
    }
162
163
    private function buildFlagsFromArray($flags)
164
    {
165 8
        $boolFlags = array_filter(array_map(function ($key, $value) {
166 8
            if (is_int($key)) {
167 6
                return $value;
168
            }
169
170 4
            if (null === $value) {
171 3
                return $key;
172
            }
173
174 4
            return false;
175 8
        }, array_keys($flags), $flags));
176
177 8
        $valueFlags = array_filter($flags, function ($key, $value) {
178 8
            return is_string($key) && is_string($value);
179 8
        }, ARRAY_FILTER_USE_BOTH);
180
181 8
        return array_merge(array_fill_keys($boolFlags, null), $valueFlags);
182
    }
183
184
    public function __toString()
185
    {
186
        return $this->getCliArguments();
187
    }
188
}
189