Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
81.40% covered (warning)
81.40%
35 / 43
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
GitLoader
81.40% covered (warning)
81.40%
35 / 43
80.00% covered (warning)
80.00%
4 / 5
15.26
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBranchName
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 getLastCommitMessage
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 getLastCommitDetail
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
4
 execCommand
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3declare(strict_types=1);
4
5namespace App\Helper;
6
7use RuntimeException;
8use Symfony\Component\DependencyInjection\Attribute\Autowire;
9use function is_array;
10
11class GitLoader
12{
13    public function __construct(
14        #[Autowire('%kernel.project_dir%')]
15        private readonly string $rootDir
16    ) {}
17
18    public function getBranchName(): string
19    {
20        $gitHeadFile = $this->rootDir.'/.git/HEAD';
21        $branchName = 'no branch name';
22
23        $stringFromFile = file_exists($gitHeadFile)
24            ? file($gitHeadFile, FILE_USE_INCLUDE_PATH) : '';
25
26        if (is_array($stringFromFile)) {
27            // Get the string from the array
28            $firstLine = $stringFromFile[0];
29
30            // Separate out by the "/" in the string
31            $explodedString = explode('/', $firstLine, 3);
32
33            $branchName = trim($explodedString[2]);
34        }
35
36        return $branchName;
37    }
38
39    public function getLastCommitMessage(): string
40    {
41        $gitCommitMessageFile = $this->rootDir.'/.git/COMMIT_EDITMSG';
42        $commitMessage = file_exists($gitCommitMessageFile)
43            ? file($gitCommitMessageFile, FILE_USE_INCLUDE_PATH) : '';
44
45        return is_array($commitMessage) ? trim($commitMessage[0]) : '';
46    }
47
48    /**
49     * @return array{author: string, date: string, sha: string}
50     */
51    public function getLastCommitDetail(): array
52    {
53        $matches = [];
54        $gitLogFile = $this->rootDir.'/.git/logs/HEAD';
55        $gitLogs = file_exists($gitLogFile)
56            ? file($gitLogFile, FILE_USE_INCLUDE_PATH) : [];
57        $sha = trim(
58            (string)$this->execCommand(
59                'cd '.$this->rootDir.' && git rev-parse --short HEAD'
60            )
61        );
62
63        if ($gitLogs) {
64            preg_match(
65                "/([\w]+) ([\w]+) ([\w\s]+) (<[\w.@]+>) ([\d]+) ([\d-]+)\tcommit: ([\w\s]+)/",
66                end($gitLogs),
67                $matches
68            );
69        }
70
71        $logs = [];
72
73        $logs['author'] = $matches[3] ?? 'not defined';
74        $logs['date'] = isset($matches[5]) ? date('Y/m/d H:i', (int)$matches[5])
75            : 'not defined';
76        $logs['sha'] = $sha;
77
78        return $logs;
79    }
80
81    protected function execCommand(string $command): bool|string
82    {
83        ob_start();
84        $lastLine = system($command, $status);
85
86        if ($status !== 0) {
87            // Command exited with a status != 0
88            if ($lastLine) {
89                throw new RuntimeException($lastLine);
90            }
91
92            throw new RuntimeException('An unknown error occurred');
93        }
94
95        ob_end_clean();
96
97        return $lastLine;
98    }
99}