Passed
Push — master ( fc9abb...9945a9 )
by Luke
02:47
created

GitVersionControl::runCommand()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
ccs 7
cts 7
cp 1
rs 9.4285
cc 3
eloc 7
nc 2
nop 2
crap 3
1
<?php
2
3
/**
4
 * Moodle component manager.
5
 *
6
 * @author Luke Carrier <[email protected]>
7
 * @copyright 2016 Luke Carrier
8
 * @license GPL-3.0+
9
 */
10
11
namespace ComponentManager\VersionControl\Git;
12
13
use ComponentManager\Exception\VersionControlException;
14
use ComponentManager\VersionControl\Git\Command\CheckoutCommand;
15
use ComponentManager\VersionControl\Git\Command\CheckoutIndexCommand;
16
use ComponentManager\VersionControl\Git\Command\Command;
17
use ComponentManager\VersionControl\Git\Command\FetchCommand;
18
use ComponentManager\VersionControl\Git\Command\InitCommand;
19
use ComponentManager\VersionControl\Git\Command\RevParseCommand;
20
use ComponentManager\VersionControl\Git\Command\RemoteAddCommand;
21
use Symfony\Component\Process\Process;
22
use Symfony\Component\Process\ProcessBuilder;
23
24
/**
25
 * Git version control.
26
 */
27
class GitVersionControl {
28
    /**
29
     * The repository's on-disk location.
30
     *
31
     * @var string
32
     */
33
    protected $directory;
34
35
    /**
36
     * Git executable.
37
     *
38
     * @var string
39
     */
40
    protected $gitExecutable;
41
42
    /**
43
     * Remotes.
44
     *
45
     * @var GitRemote[]
46
     */
47
    protected $remotes;
48
49
    /**
50
     * Initialiser.
51
     *
52
     * @param string $gitExecutable
53
     * @param string $directory
54
     */
55 3
    public function __construct($gitExecutable, $directory) {
56 3
        $this->gitExecutable = $gitExecutable;
57
58 3
        $this->directory = $directory;
59 3
        $this->remotes   = [];
60 3
    }
61
62
    /**
63
     * Get a ready-to-run Process instance.
64
     *
65
     * @param string[] $arguments Arguments to pass to the Git binary.
66
     *
67
     * @return \Symfony\Component\Process\Process
68
     */
69 3
    public function createProcess($arguments) {
70 3
        array_unshift($arguments, $this->gitExecutable);
71
72 3
        $builder = new ProcessBuilder($arguments);
73 3
        $builder->setWorkingDirectory($this->directory);
74
75 3
        return $builder->getProcess();
76
    }
77
78
    /**
79
     * Execute and ensure successful execution of a command.
80
     *
81
     * @param Command $command
82
     * @param integer|null $exceptionCode
83
     *
84
     * @return Process
85
     *
86
     * @throws VersionControlException
87
     */
88 2
    public function runCommand(Command $command, $exceptionCode=null) {
89 2
        $process = $this->createProcess($command->getCommandLine());
90 2
        $process->run();
91
92 2
        if ($exceptionCode !== null && !$process->isSuccessful()) {
93 1
            throw new VersionControlException(
94 1
                $process->getCommandLine(), $exceptionCode);
95
        }
96
97 1
        return $process;
98
    }
99
100
    /**
101
     * Add the specified remote to the repository.
102
     *
103
     * @param GitRemote $remote
104
     *
105
     * @return Process
106
     *
107
     * @throws VersionControlException
108
     *
109
     * @codeCoverageIgnore
110
     */
111
    public function addRemote(GitRemote $remote) {
112
        $command = new RemoteAddCommand($remote);
113
        return $this->runCommand($command,
114
                VersionControlException::CODE_REMOTE_ADD_FAILED);
115
    }
116
117
    /**
118
     * Checkout the specified reference.
119
     *
120
     * @param string $ref
121
     *
122
     * @return Process
123
     *
124
     * @throws VersionControlException
125
     *
126
     * @codeCoverageIgnore
127
     */
128
    public function checkout($ref) {
129
        $command = new CheckoutCommand($ref);
130
        return $this->runCommand(
131
                $command, VersionControlException::CODE_CHECKOUT_FAILED);
132
    }
133
134
    /**
135
     * Checkout all files in the index to the specified directory.
136
     *
137
     * @param string $prefix
138
     *
139
     * @return Process
140
     *
141
     * @throws VersionControlException
142
     *
143
     * @codeCoverageIgnore
144
     */
145
    public function checkoutIndex($prefix) {
146
        $command = new CheckoutIndexCommand($prefix);
147
        return $this->runCommand(
148
                $command, VersionControlException::CODE_CHECKOUT_INDEX_FAILED);
149
    }
150
151
    /**
152
     * Fetch references from the specified remote.
153
     *
154
     * @param string|null $remote
155
     *
156
     * @return Process
157
     *
158
     * @throws VersionControlException
159
     *
160
     * @codeCoverageIgnore
161
     */
162
    public function fetch($remote=null) {
163
        $command = new FetchCommand($remote);
164
        return $this->runCommand(
165
                $command, VersionControlException::CODE_FETCH_FAILED);
166
    }
167
168
    /**
169
     * Fetch tags from the specified remote.
170
     *
171
     * @param string|null $remote
172
     *
173
     * @return Process
174
     *
175
     * @throws VersionControlException
176
     *
177
     * @codeCoverageIgnore
178
     */
179
    public function fetchTags($remote=null) {
180
        $command = new FetchCommand($remote);
181
        $command->setTags(true);
182
        return $this->runCommand(
183
                $command, VersionControlException::CODE_FETCH_FAILED);
184
    }
185
186
    /**
187
     * Initialise Git repository.
188
     *
189
     * @throws VersionControlException
190
     *
191
     * @codeCoverageIgnore
192
     */
193
    public function init() {
194
        $command = new InitCommand();
195
        return $this->runCommand($command);
196
    }
197
198
    /**
199
     * Get the commit hash for the specified ref.
200
     *
201
     * @param string $ref
202
     *
203
     * @return Process
204
     *
205
     * @throws VersionControlException
206
     *
207
     * @codeCoverageIgnore
208
     */
209
    public function parseRevision($ref) {
210
        $command = new RevParseCommand($ref);
211
        return $this->runCommand(
212
                $command, VersionControlException::CODE_REV_PARSE_FAILED);
213
    }
214
}
215