Git   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 255
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 85
dl 0
loc 255
rs 10
c 1
b 0
f 1
wmc 20

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A pushWithTags() 0 9 1
A runCommandAsProcess() 0 11 2
A pull() 0 15 2
A checkout() 0 11 1
A clone() 0 15 2
A createPushCommand() 0 13 2
A tag() 0 11 1
A pushForcefully() 0 9 1
A push() 0 9 1
A describeClosestTag() 0 18 3
A addRemote() 0 13 1
A existsRemote() 0 16 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Dandelion\VersionControl;
6
7
use Dandelion\Exception\RuntimeException;
8
use Dandelion\Process\ProcessFactory;
9
10
class Git implements GitInterface
11
{
12
    /**
13
     * @var \Dandelion\Process\ProcessFactory
14
     */
15
    protected $processFactory;
16
17
    /**
18
     * @param \Dandelion\Process\ProcessFactory $processFactory
19
     */
20
    public function __construct(
21
        ProcessFactory $processFactory
22
    ) {
23
        $this->processFactory = $processFactory;
24
    }
25
26
    /**
27
     * @param string $repository
28
     * @param string|null $directory
29
     *
30
     * @return \Dandelion\VersionControl\GitInterface
31
     */
32
    public function clone(string $repository, string $directory = null): GitInterface
33
    {
34
        $command = [
35
            'git',
36
            'clone',
37
            $repository
38
        ];
39
40
        if ($directory !== null) {
41
            $command[] = $directory;
42
        }
43
44
        $this->runCommandAsProcess($command);
45
46
        return $this;
47
    }
48
49
    /**
50
     * @param string $branch
51
     *
52
     * @return \Dandelion\VersionControl\GitInterface
53
     */
54
    public function checkout(string $branch): GitInterface
55
    {
56
        $command = [
57
            'git',
58
            'checkout',
59
            $branch
60
        ];
61
62
        $this->runCommandAsProcess($command);
63
64
        return $this;
65
    }
66
67
    /**
68
     * @param string $tagName
69
     *
70
     * @return \Dandelion\VersionControl\GitInterface
71
     */
72
    public function tag(string $tagName): GitInterface
73
    {
74
        $command = [
75
            'git',
76
            'tag',
77
            $tagName
78
        ];
79
80
        $this->runCommandAsProcess($command);
81
82
        return $this;
83
    }
84
85
    /**
86
     * @param string $name
87
     * @param string $url
88
     *
89
     * @return \Dandelion\VersionControl\GitInterface
90
     */
91
    public function addRemote(string $name, string $url): GitInterface
92
    {
93
        $command = [
94
            'git',
95
            'remote',
96
            'add',
97
            $name,
98
            $url
99
        ];
100
101
        $this->runCommandAsProcess($command);
102
103
        return $this;
104
    }
105
106
    /**
107
     * @param string $remote
108
     * @param string|null $localBranch
109
     *
110
     * @return \Dandelion\VersionControl\GitInterface
111
     */
112
    public function pull(string $remote, ?string $localBranch = null): GitInterface
113
    {
114
        $command = [
115
            'git',
116
            'pull',
117
            $remote
118
        ];
119
120
        if ($localBranch !== null) {
121
            $command[] = $localBranch;
122
        }
123
124
        $this->runCommandAsProcess($command);
125
126
        return $this;
127
    }
128
129
    /**
130
     * @param string $remote
131
     * @param string|null $refSpec
132
     *
133
     * @return \Dandelion\VersionControl\GitInterface
134
     */
135
    public function push(
136
        string $remote,
137
        ?string $refSpec = null
138
    ): GitInterface {
139
        $command = $this->createPushCommand($remote, $refSpec);
140
141
        $this->runCommandAsProcess($command);
142
143
        return $this;
144
    }
145
146
    /**
147
     * @param string $remote
148
     * @param string|null $refSpec
149
     *
150
     * @return \Dandelion\VersionControl\GitInterface
151
     */
152
    public function pushForcefully(string $remote, ?string $refSpec = null): GitInterface
153
    {
154
        $command = $this->createPushCommand($remote, $refSpec);
155
156
        $command[] = '--force';
157
158
        $this->runCommandAsProcess($command);
159
160
        return $this;
161
    }
162
163
    /**
164
     * @param string $remote
165
     *
166
     * @return \Dandelion\VersionControl\GitInterface
167
     */
168
    public function pushWithTags(string $remote): GitInterface
169
    {
170
        $command = $this->createPushCommand($remote);
171
172
        $command[] = '--tags';
173
174
        $this->runCommandAsProcess($command);
175
176
        return $this;
177
    }
178
179
    /**
180
     * @param string $remote
181
     * @param string|null $refSpec
182
     *
183
     * @return string[]
184
     */
185
    protected function createPushCommand(string $remote, ?string $refSpec = null): array
186
    {
187
        $command = [
188
            'git',
189
            'push',
190
            $remote
191
        ];
192
193
        if ($refSpec !== null) {
194
            $command[] = $refSpec;
195
        }
196
197
        return $command;
198
    }
199
200
    /**
201
     * @param string[] $command
202
     *
203
     * @return string
204
     */
205
    protected function runCommandAsProcess(array $command): string
206
    {
207
        $process = $this->processFactory->create($command);
208
209
        $process->run();
210
211
        if (!$process->isSuccessful()) {
212
            throw new RuntimeException($process->getExitCodeText(), $process->getExitCode());
213
        }
214
215
        return $process->getOutput();
216
    }
217
218
    /**
219
     * @param string|null $match
220
     *
221
     * @return string|null
222
     */
223
    public function describeClosestTag(?string $match = null): ?string
224
    {
225
        $command = [
226
            'git',
227
            'describe',
228
            '--tags',
229
            '--abbrev=0'
230
        ];
231
232
        if ($match !== null) {
233
            $command[] = '--match';
234
            $command[] = \sprintf('\'%s\'', $match);
235
        }
236
237
        try {
238
            return $this->runCommandAsProcess($command);
239
        } catch (RuntimeException $e) {
240
            return null;
241
        }
242
    }
243
244
    /**
245
     * @param string $remote
246
     *
247
     * @return bool
248
     */
249
    public function existsRemote(string $remote): bool
250
    {
251
        $command = [
252
            'git',
253
            'config',
254
            '--get',
255
            sprintf('remote.%s.url', $remote)
256
        ];
257
258
        try {
259
            $this->runCommandAsProcess($command);
260
        } catch (RuntimeException $e) {
261
            return false;
262
        }
263
264
        return true;
265
    }
266
}
267