Completed
Push — master ( 651eb5...e7f95e )
by Tomáš
16:52 queued 15:34
created

GitProcess::wait()   A

Complexity

Conditions 5
Paths 11

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
rs 9.1288
c 0
b 0
f 0
cc 5
nc 11
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GitWrapper\Process;
6
7
use GitWrapper\Event\GitBypassEvent;
8
use GitWrapper\Event\GitErrorEvent;
9
use GitWrapper\Event\GitPrepareEvent;
10
use GitWrapper\Event\GitSuccessEvent;
11
use GitWrapper\Exception\GitException;
12
use GitWrapper\GitCommand;
13
use GitWrapper\GitWrapper;
14
use RuntimeException;
15
use Symfony\Component\Process\Process;
16
use Symfony\Contracts\EventDispatcher\Event;
17
18
final class GitProcess extends Process
19
{
20
    /**
21
     * @var GitWrapper
22
     */
23
    protected $gitWrapper;
24
25
    /**
26
     * @var GitCommand
27
     */
28
    protected $gitCommand;
29
30
    public function __construct(GitWrapper $gitWrapper, GitCommand $gitCommand, ?string $cwd = null)
31
    {
32
        $this->gitWrapper = $gitWrapper;
33
        $this->gitCommand = $gitCommand;
34
35
        // Build the command line options, flags, and arguments.
36
        $commandLine = $gitCommand->getCommandLine();
37
        $gitBinary = $gitWrapper->getGitBinary();
38
        if (is_string($commandLine)) {
39
            // Support for executing an arbitrary git command.
40
            $commandLine = [$gitBinary, $commandLine];
41
        } else {
42
            array_unshift($commandLine, $gitBinary);
43
        }
44
45
        // Resolve the working directory of the Git process. Use the directory
46
        // in the command object if it exists.
47
        $cwd = $this->resolveWorkingDirectory($cwd, $gitCommand);
48
49
        // Finalize the environment variables, an empty array is converted
50
        // to null which enherits the environment of the PHP process.
51
        $env = $gitWrapper->getEnvVars();
52
        if ($env === []) {
53
            $env = null;
54
        }
55
56
        parent::__construct($commandLine, $cwd, $env, null, (float) $gitWrapper->getTimeout());
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function start(?callable $callback = null, array $env = []): void
63
    {
64
        $gitPrepareEvent = new GitPrepareEvent($this->gitWrapper, $this, $this->gitCommand);
65
        $this->dispatchEvent($gitPrepareEvent);
66
67
        if ($this->gitCommand->notBypassed()) {
68
            parent::start($callback, $env);
69
        } else {
70
            $gitBypassEvent = new GitBypassEvent($this->gitWrapper, $this, $this->gitCommand);
71
            $this->dispatchEvent($gitBypassEvent);
72
        }
73
    }
74
75
    public function wait(?callable $callback = null): int
76
    {
77
        if (! $this->gitCommand->notBypassed()) {
78
            return -1;
79
        }
80
81
        try {
82
            $exitCode = parent::wait($callback);
83
84
            if ($this->isSuccessful()) {
85
                $gitSuccessEvent = new GitSuccessEvent($this->gitWrapper, $this, $this->gitCommand);
86
                $this->dispatchEvent($gitSuccessEvent);
87
            } else {
88
                $output = $this->getErrorOutput();
89
90
                if (trim($output) === '') {
91
                    $output = $this->getOutput();
92
                }
93
94
                throw new GitException($output);
95
            }
96
        } catch (RuntimeException $runtimeException) {
97
            $gitErrorEvent = new GitErrorEvent($this->gitWrapper, $this, $this->gitCommand);
98
            $this->dispatchEvent($gitErrorEvent);
99
100
            throw new GitException($runtimeException->getMessage(), $runtimeException->getCode(), $runtimeException);
101
        }
102
103
        return $exitCode;
104
    }
105
106
    private function resolveWorkingDirectory(?string $cwd, GitCommand $gitCommand): ?string
107
    {
108
        if ($cwd !== null) {
109
            return $cwd;
110
        }
111
112
        $directory = $gitCommand->getDirectory();
113
        if ($directory === null) {
114
            return $cwd;
115
        }
116
117
        if (! $cwd = realpath($directory)) {
118
            throw new GitException('Path to working directory could not be resolved: ' . $directory);
119
        }
120
121
        return $cwd;
122
    }
123
124
    private function dispatchEvent(Event $event): void
125
    {
126
        $this->gitWrapper->getDispatcher()->dispatch($event);
127
    }
128
}
129