GitProcess::dispatchEvent()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
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
    private $gitWrapper;
24
25
    /**
26
     * @var GitCommand
27
     */
28
    private $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
39
        // Support for executing an arbitrary git command.
40
        if (is_string($commandLine)) {
41
            $commandLine = explode(' ', $commandLine);
42
        }
43
44
        array_unshift($commandLine, $gitBinary);
45
46
        // Resolve the working directory of the Git process. Use the directory
47
        // in the command object if it exists.
48
        $cwd = $this->resolveWorkingDirectory($cwd, $gitCommand);
49
50
        // Finalize the environment variables, an empty array is converted
51
        // to null which enherits the environment of the PHP process.
52
        $env = $gitWrapper->getEnvVars();
53
        if ($env === []) {
54
            $env = null;
55
        }
56
57
        parent::__construct($commandLine, $cwd, $env, null, (float) $gitWrapper->getTimeout());
58
    }
59
60
    public function start(?callable $callback = null, array $env = []): void
61
    {
62
        $gitPrepareEvent = new GitPrepareEvent($this->gitWrapper, $this, $this->gitCommand);
63
        $this->dispatchEvent($gitPrepareEvent);
64
65
        if ($this->gitCommand->notBypassed()) {
66
            parent::start($callback, $env);
67
        } else {
68
            $gitBypassEvent = new GitBypassEvent($this->gitWrapper, $this, $this->gitCommand);
69
            $this->dispatchEvent($gitBypassEvent);
70
        }
71
    }
72
73
    public function wait(?callable $callback = null): int
74
    {
75
        if (! $this->gitCommand->notBypassed()) {
76
            return -1;
77
        }
78
79
        try {
80
            $exitCode = parent::wait($callback);
81
82
            if ($this->isSuccessful()) {
83
                $gitSuccessEvent = new GitSuccessEvent($this->gitWrapper, $this, $this->gitCommand);
84
                $this->dispatchEvent($gitSuccessEvent);
85
            } else {
86
                $output = $this->getErrorOutput();
87
88
                if (trim($output) === '') {
89
                    $output = $this->getOutput();
90
                }
91
92
                throw new GitException($output);
93
            }
94
        } catch (RuntimeException $runtimeException) {
95
            $gitErrorEvent = new GitErrorEvent($this->gitWrapper, $this, $this->gitCommand);
96
            $this->dispatchEvent($gitErrorEvent);
97
98
            throw new GitException($runtimeException->getMessage(), $runtimeException->getCode(), $runtimeException);
99
        }
100
101
        return $exitCode;
102
    }
103
104
    private function resolveWorkingDirectory(?string $cwd, GitCommand $gitCommand): ?string
105
    {
106
        if ($cwd !== null) {
107
            return $cwd;
108
        }
109
110
        $directory = $gitCommand->getDirectory();
111
        if ($directory === null) {
112
            return $cwd;
113
        }
114
115
        if (! $cwd = realpath($directory)) {
116
            throw new GitException('Path to working directory could not be resolved: ' . $directory);
117
        }
118
119
        return $cwd;
120
    }
121
122
    private function dispatchEvent(Event $event): void
123
    {
124
        $this->gitWrapper->getDispatcher()->dispatch($event);
125
    }
126
}
127